Find rectangles without corners with opencv

I have an image where I want to find outlines, but the “outlines” in my image don't have corners. Are there some tricks I can use to help find the rectangles that are implied by the lines in this image? I was thinking about expanding all the lines to form corners, but I'm worried about lines intersecting with other contours, and how to determine which intersections are of interest to me. I am very new to opencv and I am not very good at image processing. Thanks for any help you can give. alt text

+6
opencv
source share
4 answers

I have finished implementing my own solution. It is not very graceful, but he is doing his job. I would be interested to know about the improvements. HoughLines2 did not always give me good results for finding line segments, and I had to deal with the threshold value for different scenarios a lot. Instead, I chose FindCountours, where I took the outlines with two elements, I should be guaranteed lines with 1 pixel. Having found the lines, I repeated them and traced them to find the rectangles.

Where the points are * CvSeq line endpoints

while(points->total>0){ if(p1.x==-1&&p1.y==-1){ cvSeqPopFront(points,&p1); cvSeqPopFront(points,&p2); } if((pos=findClosestPoint(&p1,&p2, points,maxDist))>=0){ p3 = (CvPoint*)cvGetSeqElem( points,pos ); pos2 = (pos%2==0)?pos+1:pos-1; //lines are in pairs of points p4 = (CvPoint*)cvGetSeqElem( points,pos2 ); if(isVertical(&p1,&p2) && isHorizontal(p3,p4)){ printf("found Corner %d %d\n",p2.x,p3->y); } else if(isHorizontal(&p1,&p2) && isVertical(p3,p4) ){ printf("found Corner %d %d\n",p3->x,p2.y); } memcpy(&p1,p3,sizeof(CvPoint)); memcpy(&p2,p4,sizeof(CvPoint)); cvSeqRemove(points, (pos>pos2)?pos:pos2); cvSeqRemove(points, (pos>pos2)?pos2:pos); } else { p1.x=-1; p1.y=-1; } } int findClosestPoint (CvPoint *p1, CvPoint *p2, CvSeq *points, int maxDist) { int ret = -1,i; float dist, minDist = maxDist; CvPoint* test; int (*dirTest)(CvPoint *,CvPoint *); if(isVertical(p1,p2)){ //vertical line if(p2->y > p1->y) {//going down dirTest = isBelow; } else { // going up dirTest = isAbove; } } else if (isHorizontal(p1,p2)){ //horizontal line if(p2->x > p1->x) {//going right dirTest = isRight; } else { //going left dirTest = isLeft; } } for( i = 0; i < points->total; i++ ) { test = (CvPoint*)cvGetSeqElem( points, i ); if(dirTest(p2,test)){ //only test points in the region we care about dist = sqrt(pow(test->x - p2->x,2)+pow(test->y - p2->y,2)); if(dist<minDist){ minDist = dist; ret = i; } } } return ret; } int isVertical(CvPoint *p1, CvPoint *p2){ return p1->x == p2->x; } int isHorizontal(CvPoint *p1, CvPoint *p2){ return p1->y == p2->y; } int isRight(CvPoint *pt1, CvPoint *pt2){ return pt2->x > pt1->x; } int isLeft(CvPoint *pt1, CvPoint *pt2){ return pt2->x < pt1->x; } int isBelow(CvPoint *pt1, CvPoint *pt2){ return pt2->y > pt1->y; } int isAbove(CvPoint *pt1, CvPoint *pt2){ return pt2->y < pt1->y; } 
+4
source share

Adjust the lines in your binary image using Hough transform and set the rectangles to orthogonally intersecting lines.

+4
source share

You can also try to create it as an optimization problem. A rectangle is defined as a 4D state vector (x, w, width, height) or 5D vector if you turn on rotation (x, y, width, height, rotation). For your current state, you can make a gradient descent to the result of the Hough lines to converge to the optimal state. Another option uses linear least squares: http://people.inf.ethz.ch/arbenz/MatlabKurs/node88.html

+1
source share

Using hough transform , you can extract strings. Then you can calculate the intersections of these lines to estimate the position of the rectangles.

0
source share

All Articles