我有image:
我想从图像中取出三角形和矩形。我有2个算法,一个用于三角形,另一个用于下面代码中的矩形。但它们非常相似。但通过这种方式我只能把三角形更加明亮。任何人都可以帮助我。
IplImage* DetectAndDrawTriang(IplImage* img){
CvSeq* contours;
CvSeq* result;
CvMemStorage *storage = cvCreateMemStorage(0);
int d=30;
IplImage* ret = cvCreateImage(cvGetSize(img), 8, 3);
IplImage* temp = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
cvSet(ret,cvScalar(0,0,0));
cvCvtColor(img, temp, CV_BGR2GRAY);
cvThreshold( temp, temp, 180, 255, CV_THRESH_BINARY );
//cvSmooth(temp, temp, CV_GAUSSIAN, 9, 9, 0,0);
cvNamedWindow("thre");
cvShowImage("thre", temp);
cvFindContours(temp, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
while(contours)
{
result = cvApproxPoly(contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.1, 0);
if(result->total==3)
{
CvPoint *pt[3];
for(int i=0;i<3;i++)
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
if((int)sqrt((pt[0]->x-pt[2]->x)*(pt[0]->x-pt[2]->x)+(pt[0]->y-pt[2]->y)*(pt[0]->y-pt[2]->y))>=d && (int)sqrt((pt[0]->x-pt[1]->x)*(pt[0]->x-pt[1]->x)+(pt[0]->y-pt[1]->y)*(pt[0]->y-pt[1]->y))>=d && (int)sqrt((pt[1]->x-pt[2]->x)*(pt[1]->x-pt[2]->x)+(pt[1]->y-pt[2]->y)*(pt[1]->y-pt[2]->y))>=d)
{
cvLine(ret, *pt[0], *pt[1], cvScalar(255,255,255));
cvLine(ret, *pt[1], *pt[2], cvScalar(255,255,255));
cvLine(ret, *pt[2], *pt[0], cvScalar(255,255,255));
}
}
contours = contours->h_next;
}
cvReleaseImage(&temp);
cvReleaseMemStorage(&storage);
return ret;
}
答案 0 :(得分:2)
我能想到的一个想法是使用cv :: matchShapes函数(我建议使用带有Mat而不是Ipl图像的cv2库)。 matchShapes使用要检测的对象的Mat和要与其进行比较的对象的Mat。因此,在您的情况下,您可以制作三角形和正方形轮廓的Mat,并将这些图像与您正在搜索的图像中的每个轮廓进行比较。
您也可以考虑简单地进行模板匹配,因为您的对象是静态的。查看cv :: matchTemplate及其与上一段几乎相同的想法。
答案 1 :(得分:0)
近似是一个很好的解决方案如果你可以确定你的轮廓是完整的。 如果轮廓是正方形但没有关闭,则它将是近似后具有四个段和三个角的线。
另一个解决方案是在轮廓点周围安装一个方框(有一个功能可以做到这一点)并检查宽度/高度比。然后,您可以测试轮廓列表中的各个线段,看它们是否与箱边匹配。