凸包检测
cv::Mat src = cv::imread("1.jpg");
if (!src.data)
{
cout << "error" << endl;
return -1;
}
cv::Mat gray, dst, thresholdImage;
cv::RNG rng(12345);
vector<vector<cv::Point> > contours;
cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
cv::blur(gray, gray, cv::Size(3, 3));
cv::threshold(gray, thresholdImage, 170, 255, CV_THRESH_BINARY);
cv::findContours(thresholdImage,
contours,
CV_RETR_TREE,
CV_CHAIN_APPROX_SIMPLE);
vector<vector<cv::Point>>hull(contours.size());
for (unsigned int i = 0; i < contours.size(); i++)
{
cv::convexHull(cv::Mat(contours[i]),
hull[i],
false);
}
dst = cv::Mat::zeros(thresholdImage.size(), CV_8UC3);
for (unsigned int i = 0; i< contours.size(); i++)
{
cv::Scalar color = cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(dst, contours, i, color, 1, 8, vector<cv::Vec4i>(), 0, cv::Point());
drawContours(dst, hull, i, color, 1, 8, vector<cv::Vec4i>(), 0, cv::Point());
}
cv::imshow("原图", src);
cv::imshow("凸包检测效果图", dst);
分水岭算法
Mat g_maskImage, g_srcImage;
Point prevPt(-1, -1);
static void on_Mouse(int event, int x, int y, int flags, void*);
int main(int argc, _TCHAR* argv[])
{
g_srcImage = cv::imread("1.jpg");
if (!g_srcImage.data)
{
cout << "error" << endl;
return -1;
}
imshow("原图", g_srcImage);
Mat srcImage, grayImage;
g_srcImage.copyTo(srcImage);
cvtColor(g_srcImage, g_maskImage, COLOR_BGR2GRAY);
cvtColor(g_maskImage, grayImage, COLOR_GRAY2BGR);
g_maskImage = Scalar::all(0);
setMouseCallback("原图", on_Mouse, 0);
while (1)
{
int c = waitKey(0);
if ((char)c == 27)
break;
if ((char)c == '2')
{
g_maskImage = Scalar::all(0);
srcImage.copyTo(g_srcImage);
imshow("image", g_srcImage);
}
if ((char)c == '1' || (char)c == ' ')
{
int i, j, compCount = 0;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(g_maskImage, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
if (contours.empty())
continue;
Mat maskImage(g_maskImage.size(), CV_32S);
maskImage = Scalar::all(0);
for (int index = 0; index >= 0; index = hierarchy[index][0], compCount++)
drawContours(maskImage, contours, index, Scalar::all(compCount + 1), -1, 8, hierarchy, INT_MAX);
if (compCount == 0)
continue;
vector<Vec3b> colorTab;
for (i = 0; i < compCount; i++)
{
int b = theRNG().uniform(0, 255);
int g = theRNG().uniform(0, 255);
int r = theRNG().uniform(0, 255);
colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
}
watershed(srcImage, maskImage);
Mat watershedImage(maskImage.size(), CV_8UC3);
for (i = 0; i < maskImage.rows; i++)
for (j = 0; j < maskImage.cols; j++)
{
int index = maskImage.at<int>(i, j);
if (index == -1)
watershedImage.at<Vec3b>(i, j) = Vec3b(255, 255, 255);
else if (index <= 0 || index > compCount)
watershedImage.at<Vec3b>(i, j) = Vec3b(0, 0, 0);
else
watershedImage.at<Vec3b>(i, j) = colorTab[index - 1];
}
watershedImage = watershedImage*0.5 + grayImage*0.5;
imshow("分水岭效果图", watershedImage);
}
}
return 0;
}
static void on_Mouse(int event, int x, int y, int flags, void*)
{
if (x < 0 || x >= g_srcImage.cols || y < 0 || y >= g_srcImage.rows)
return;
if (event == EVENT_LBUTTONUP || !(flags & EVENT_FLAG_LBUTTON))
prevPt = Point(-1, -1);
else if (event == EVENT_LBUTTONDOWN)
prevPt = Point(x, y);
else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON))
{
Point pt(x, y);
if (prevPt.x < 0)
prevPt = pt;
line(g_maskImage, prevPt, pt, Scalar::all(255), 5, 8, 0);
line(g_srcImage, prevPt, pt, Scalar::all(255), 5, 8, 0);
prevPt = pt;
imshow("原图", g_srcImage);
}
}