我想编写一个程序,可以通过C语言中的opencv更正答案表 .
但是当我使用 cvFindContours()
时,完全找到了轮廓_2914723 .
我的意思是,我没有封闭的物体 . (我使用 cvDilate
和 cvErode
,不知道它们的真正功能,但是扩张省略了一些轮廓并且侵蚀了一些额外的,不需要的轮廓)
更大的问题是我想在每个轮廓中找到一个中心点(比较答案的位置与预定义的左侧和下侧边栏),但是一些轮廓不对称,所以中心点的位置不完全在中间 .
查看左侧黑色图片,在第二个轮廓中,检测到一些底部点,但未检测到顶部点 .
cvCvtColor(pic, blackpic, CV_BGR2GRAY);
cvResize(blackpic, src0);
cvSmooth(src0, src0, CV_GAUSSIAN, 3, 3);
cvThreshold(src0, src, 140, 255, CV_THRESH_BINARY);
//Find Contour
CvMemStorage* st = cvCreateMemStorage();
CvSeq* first_contour = NULL;
cvFindContours(src, st, &first_contour, sizeof(CvContour), CV_RETR_LIST);
vector <vector <CvPoint> > cont;
vector <CvPoint> dot;
for (CvSeq* s = first_contour; s != NULL; s = s->h_next)
if (s -> total > C_MIN_SIZE && cvContourArea(s) > C_MIN_AREA)
{
cont.push_back(vector <CvPoint>()); //convert seq to vector
CvPoint c = cvPoint(0,0);
for (int i = 0; i < s -> total; i++)
{
CvPoint* p = CV_GET_SEQ_ELEM(CvPoint, s, i);
cont.back().push_back(*p);
CV_IMAGE_ELEM(test, uchar, p -> y, p -> x) = 255; //drawing each contour's point
c.x += p -> x; //find the center point by average
c.y += p -> y;
}
c.x = floor(c.x / s -> total);
c.y = floor(c.y / s -> total);
dot.push_back(c);
}
-
虽然我使用C,但是我使用IplImage *和CvPoint(c structres for opencv)insted of cv :: Mat和cv :: Point(C stractures),如果有可能,请不要使用Mat和C模式 .
-
我不明白当我通过
cvDrawContours()
绘制轮廓时,轮廓是完全绘制的,但是当我亲自遍历轮廓点并逐点绘制它们时,似乎大多数都没有被检测到!
1 回答
对于您的第一个问题,您可以在互联网上找到数以千计的链接来解释Erode, Dilate以及所有其他基本的图像处理支柱,在阅读文档时花点时间不要跳过步骤 .
第二个问题:
我不确定你对轮廓中心有什么期望?你认为你会准确地指出那些椭圆的中心吗?不,这将永远不会发生,如果是这样的话,祝贺图像处理历史中的这一大堆!
我建议做的是一个简单的操作来解决你的问题:
找到轮廓(就像你现在正在做的那样)
计算每个轮廓的中心
当您将答案与中心位置进行比较时,请不要使用
a == b
进行比较,因为这绝不会发生!!相反,使用距离(阈值)的比较来确保软件的运行示例:
祝好运