我一直在做一些皮肤检测,但无法顺利进行。下面的图像包含输入(左)和输出(右),使用下面附带的代码。现在,所需的输出应该是最底部的图像(边缘光滑且没有孔的图像)。我如何实现此输出?关于从哪里开始的示例代码将有很大帮助。
输入(左)和不正确的输出(右):
期望的输出:
生成Incorect输出的代码:
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main(){
Mat src = imread("qq.jpg");
if (src.empty())
return -1;
blur( src, src, Size(3,3) );
Mat hsv;
cvtColor(src, hsv, CV_BGR2HSV);
Mat bw;
inRange(hsv, Scalar(0, 10, 60), Scalar(20, 150, 255), bw);
imshow("src", src);
imshow("dst", bw);
waitKey(0);
return 0;
}
修改后的代码(在Astor的建议之后): (现在的问题是:你如何平滑输出?)
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int findBiggestContour(vector<vector<Point> >);
int main(){
Mat src = imread("qq.jpg");
if (src.empty())
return -1;
blur( src, src, Size(3,3) );
Mat hsv;
cvtColor(src, hsv, CV_BGR2HSV);
Mat bw;
inRange(hsv, Scalar(0, 10, 60), Scalar(20, 150, 255), bw);
imshow("src", src);
imshow("dst", bw);
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours( bw, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
int s = findBiggestContour(contours);
Mat drawing = Mat::zeros( src.size(), CV_8UC1 );
drawContours( drawing, contours, s, Scalar(255), -1, 8, hierarchy, 0, Point() );
imshow("drw", drawing);
waitKey(0);
return 0;
}
int findBiggestContour(vector<vector<Point> > contours){
int indexOfBiggestContour = -1;
int sizeOfBiggestContour = 0;
for (int i = 0; i < contours.size(); i++){
if(contours[i].size() > sizeOfBiggestContour){
sizeOfBiggestContour = contours[i].size();
indexOfBiggestContour = i;
}
}
return indexOfBiggestContour;
}
答案 0 :(得分:10)
您应该使用findContours
来检测最大轮廓,然后使用方法drawContours
在绘制后使用填充参数-1创建轮廓。这是有用的链接:http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html
答案 1 :(得分:1)
为了改善输出的平滑度,或者换句话说,为了减少检测区域中的黑洞,尝试对得到的图像执行形态学操作。 以下文档解释了opencv中的侵蚀和扩张功能。 http://docs.opencv.org/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html