使用opencv查找没有角落的矩形

joh*_*ohn 6 opencv

我有一个图像,我想找到轮廓,但我的图像中的"轮廓"没有角.我是否可以使用一些技巧来帮助找到此图像中线条所暗示的矩形?我想扩展所有线条以形成角落,但我担心与其他轮廓相交的线条以及如何确定我感兴趣的交叉点.我对opencv很新,我对图像处理知之甚少.感谢您提供任何帮助. 替代文字

joh*_*ohn 4

我最终实施了自己的解决方案。它不是很优雅,但它可以完成工作。我有兴趣听到有关改进的信息。HoughLines2 并不总能为我找到线段提供良好的结果,而且我不得不针对不同的场景大量调整阈值。相反,我选择了 FindCountours,用两个元素绘制轮廓,应该保证 1 像素宽的线条。找到线条后,我迭代它们并追踪它们以找到矩形。

其中,points 是线端点的 *CvSeq

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;
}
Run Code Online (Sandbox Code Playgroud)