使用opencv查找没有角的矩形 [英] Find rectangles without corners using opencv
问题描述
我有一个要查找轮廓的图像,但是图像中的轮廓"没有角.我可以使用一些技巧来帮助找到此图像中的线所隐含的矩形吗?我曾考虑过将所有线延长成角,但担心线与其他轮廓线相交以及如何确定我感兴趣的相交点.我对opencv并不陌生,对图像处理也不了解.感谢您提供的任何帮助.
I have an image where I want to find contours but the "contours" 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 thought about extending all the lines to form the corners but I worry about lines intersecting from other contours and how to determine which intersections I'm interested in. I'm very new to opencv and I don't know much about image processing. Thank you for any help you can give.
推荐答案
我最终实现了自己的解决方案.它不是很优雅,但是可以完成工作.我将有兴趣听到有关改进的信息. HoughLines2在寻找线段时并不总是给我带来很好的结果,并且我不得不在不同的情况下大为改变阈值.取而代之的是,我选择了FindCountours,在其中我用两个元素绘制了轮廓,应该保证我有1像素宽的线.找到线条后,我遍历了线条并找出了矩形.
I ended up implementing my own solution. It isn't very graceful but it gets the job done. I would be interested in hearing about improvements. HoughLines2 didn't always give me good results for finding line segments and I had to mess around with the threshold value a lot for different scenarios. Instead I opted for FindCountours where I took contours with two elements, I should be guaranteed 1 pixel wide lines. After finding the lines I iterated through them and traced them out to find the rectangles.
点是线端点的* CvSeq
Where points is a *CvSeq of the 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;
}
这篇关于使用opencv查找没有角的矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!