Zedboard甲诊opencv图像处理(二)

通过前面的努力已经得到了n个轮廓了,现在要把最终的轮廓确定下来 ,然后进行特征提取。

先深入分析下轮廓和处理轮廓的方法:http://blog.csdn.net/hitwengqi/article/details/6929523

之前其实我尝试了用 cv::grabCut function把前景图像提取出来,但是这个方法需要的人工操作还是有点多,至少我这里没办法用。所以又放弃了。
先来看看cvApproxPoly()函数吧,http://blog.csdn.net/bruce_zeng/article/details/8074253

然后还有曲线拟合的方法:http://hi.baidu.com/bitroc/item/8f7b8d12f69a4f0ae65c3687

总之还是尝试吧,谁让我菜呢!

首先我采用了形态学处理的方法,进行闭操作,先进行膨胀,然后腐蚀,然后closed,对处理后的二值图像进行最大轮廓查找,去掉其他的轮廓。如果光照处理好的情况下,效果还不错:

但是貌似不是很稳定啊,换个指甲效果就没这么好了。还有就是就算我能处理程这样,还有两条手指头的边界很麻烦啊,需要去掉。当然我还要把最差的效果显示一下:

所以我的想法是,一改进采集装置,固定手指位置;二修改程序或者进一步处理.

Mat Widget::FindmaxCounters(Mat image)
{
       vector<vector<Point> > contours;
       vector<Point> maxContour;
       vector<vector<Point> > ::iterator itc;
       Mat dst = Mat::zeros(image.rows, image.cols, CV_8U);
       findContours( image, contours, CV_RETR_EXTERNAL , CV_CHAIN_APPROX_NONE );
       //找到最大的轮廓
       size_t maxSize=0;
       itc = contours.begin();
       while(itc!=contours.end())
       {
           if(itc->size()>maxSize)
               {
               maxSize=itc->size();
               maxContour=*itc;
           }
           ++itc;
       }
       itc = contours.begin();
       while(itc!= contours.end()) {             //Eliminate smaller contours
                       if(itc->size() < maxSize)
                           itc=contours.erase(itc);
                       else
                       ++itc;
           }
       QString str1;QFont ft;
       int ilz1 = (int)contours.size();
       str1.setNum(ilz1);ft.setPointSize(20);
       ui->label_9->setAlignment(Qt::AlignCenter);//设置字居中显示
       ui->label_9->setFont(ft);
       //放到QLabel上显示
       ui->label_9->setText(str1);
       ui->label_9->show();
       drawContours(dst, contours, 0, Scalar(255), CV_FILLED);
       //CvRect s;
       //CvPoint pt;
       //vector<vector<Point> > contours;
       //Mat dst = Mat::zeros(grayimage.rows, grayimage.cols, CV_8U);
       //findContours( grayimage, contours, CV_RETR_EXTERNAL , CV_CHAIN_APPROX_NONE );
       //s=cv::boundingRect(contours);
       //pt = cvPoint(s.x+s.width/2,s.y+s.height/2);//-------可以用其他方式获得连通域的一个内点作为起始种子点
       //cv::floodFill(dst, pt ,cvScalarAll(255));
       return dst;
}
原文地址:https://www.cnblogs.com/preorder69/p/3130531.html