0

I used standard hough transforms to obtain the straight lines in an image using OpenCV. Now, I need to find the x and y coordinates of the point of intersection of most of the lines in the image. My idea was to divide the image into several 8*8 pixel segments( I haven't decided on the size yet) and then search the region for lines. But I am not sure as to how I count the lines in the segments. I am struck at this point. So the things I am unable to do( using openCV) are 1.Divide the image into 8*8 pixel segments( i don't know if there is a function for it and if not what do I do) 2.Count the number of lines in each segment. Any reading material or hints for the code will be of really helpful.

Aditya Bhat
  • 95
  • 2
  • 10

3 Answers3

1

Your way of detecting intersection points is totally wrong. There is a simple mathematical formula for that. I am giving you an example code in plain C. :

// This is a point
typedef struct{
   int x,y;
} MYintPOINT;

// This is line
typedef struct {
    MYintPOINT  pStart;
    MYintPOINT  pEnd;
} MyLine;

#define PointMinusPoint(P,Q,R)      {(P).x = (Q).x - (R).x; (P).y = (Q).y - (R).y;}
#define PointCross(P,Q)             (((P).x*(Q).y)-((P).y*(Q).x))
#define SIGN(X)             (((X)>=0)? 1:-1 )
#define ABS(a)              ((a) >= 0 ? (a) : (-(a)))
#define ROUND(a)            ((SIGN(a)) * ( ( int )( ABS(a) + 0.5 ) ) ) 

// Given 2 line segments, find their intersection point
// rerurns [Px,Py] point in 'res' or FALSE if parallel. Uses vector cross product technique.
int findLinesIntersectionPoint(const MyLine*l1, const MyLine*l2, MYintPOINT *res){
    MYintPOINT  p  = l1->pStart;
    MYintPOINT  dp;
    MYintPOINT  q  = l2->pStart;
    MYintPOINT  dq;
    MYintPOINT  qmp;            // q-p
    int         dpdq_cross;     // 2 cross products
    int         qpdq_cross;     // dp with dq,  q-p with dq
    float       a;

    PointMinusPoint(dp,l1->pEnd,l1->pStart);
    PointMinusPoint(dq,l2->pEnd,l2->pStart);
    PointMinusPoint(qmp,q,p);

    dpdq_cross = PointCross(dp,dq);
    if (!dpdq_cross){
        // Perpendicular Lines
        return 0;
    }

    qpdq_cross = PointCross(qmp,dq);
    a = (qpdq_cross*1.0f/dpdq_cross);

    res->x = ROUND(p.x+a*dp.x);
    res->y = ROUND(p.y+a*dp.y);
    return 1;
}
DanielHsH
  • 4,287
  • 3
  • 30
  • 36
  • Thanks a lot. I used the same method and it worked like a charm – Aditya Bhat Dec 29 '12 at 10:16
  • Yeah. I used it too. Please accept my answer so other people will know to copy the code. I tried to document it as much as I could :-) – DanielHsH Jan 01 '13 at 17:59
  • 2
    When implementing any algorithm that involves geometry--even if it seems simple mathematically--you should consider checking GeometricTools.com, which has reviews of the mathematics, solutions to problems one can encounter when implementing algorithms, and also sample code. It's a great reference. http://www.geometrictools.com/ – Rethunk Jan 04 '13 at 03:30
0

I can help you with dividing the image into 8*8 pixel segments.

The rowRange() and colRange() functions in OpenCV are useful for this. (documentation here) Here's an example:

cv::Mat img = cv::imread("myImage.png");
cv::Mat region = img.rowRange(0,7).colRange(0,7);  //upper-left 8x8 image region
solvingPuzzles
  • 8,541
  • 16
  • 69
  • 112
0

Note that due to noise most of the lines might not intersect at one point at all, aside from that try the following:

create black_image 
for each line
    create temporary_black_image
    draw a line to temporary_black_image, use cvScalar(1) as a color for the line
    cvAdd both temporary_black_image to black_image
apply cvSmooth to black_image
CvPoint minLoc; CvPoint maxLoc;
double minVal; double maxVal;
cvMinMaxLoc( black_image, &minVal, &maxVal, &minLoc, &maxLoc );

maxLoc->x and maxLoc-> y will be your estimate

You can try to adjust results a little bit by varying parameters of the cvSmooth function

ivan_a
  • 613
  • 5
  • 12