前言:
目前我们对“vc轮廓算法”大概比较讲究,大家都需要知道一些“vc轮廓算法”的相关知识。那么小编也在网上网罗了一些有关“vc轮廓算法””的相关文章,希望姐妹们能喜欢,看官们一起来了解一下吧!1. 寻找轮廓
findContours() 函数用于在二值图像中寻找轮廓。常与 drawContours() 函数配合使用;findContours() 函数检测到图像的轮廓后,就可以用 drawContours() 函数将检测到的轮廓绘制出来。
2. 绘制轮廓
drawContours() 函数用于在图像中绘制外部或内部轮廓。
3. 综合例子
利用图像平滑技术(blur ()函数)和边缘检测技术(canny()函数),根据滑动条,动态地检测出图形的轮廓。
例子代码:
#include<opencv2/opencv.hpp>#include<iostream>using namespace std;using namespace cv;Mat srcImg, grayImg,cannyOutImg;int ThreshValue = 80;int ThrashValueMax = 255;vector<vector<Point>> vContours;vector<Vec4i> vHierarchy;RNG rng(12345);void ThreshChange(int, void*);void test(){ srcImg = imread("home.jpg"); if (srcImg.empty()) { cout << "could not load image...\n" << endl; } namedWindow("Original iamge", CV_WINDOW_NORMAL); imshow("Original iamge", srcImg); cvtColor(srcImg, grayImg, COLOR_BGR2GRAY); blur(grayImg, grayImg, Size(3, 3)); namedWindow("ThreshWindow", CV_WINDOW_NORMAL); createTrackbar("canny_ThreshValue", "ThreshWindow", &ThreshValue, ThrashValueMax, ThreshChange); ThreshChange(0, 0);}void ThreshChange(int, void*){ Canny(grayImg, cannyOutImg, ThreshValue, ThreshValue*2,3); //寻找轮廓 findContours(cannyOutImg, vContours, vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); //会出轮廓 Mat drawing = Mat::zeros(cannyOutImg.size(), CV_8UC3); for (int i = 0; i < vContours.size(); i++) { Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); drawContours(drawing, vContours, i, color, 2, 8, vHierarchy, 0, Point()); } imshow("ThreshWindow", drawing);}int main(){ test(); waitKey(0); return 0;}
效果图:
4. 分水岭算法
例子代码:
#include<opencv2/opencv.hpp>#include<iostream>using namespace std;using namespace cv;Mat srcImg, maskImg, cannyOutImg;Point prevPt(-1, -1);//鼠标回调函数static void Mouse(int event, int x, int y, int flags, void*);static void ShowHelpText(); //提升用户操作函数void test(){ srcImg = imread("home.jpg"); if (srcImg.empty()) { cout << "could not load image...\n" << endl; } //namedWindow("Original image", CV_WINDOW_NORMAL); imshow("WindowOne", srcImg); Mat srcImg2, grayImg; srcImg.copyTo(srcImg2); cvtColor(srcImg, maskImg, COLOR_BGR2GRAY); cvtColor(maskImg, grayImg, COLOR_GRAY2BGR); maskImg = Scalar::all(0); setMouseCallback("WindowOne", Mouse, 0); //鼠标回调函数 //轮询按键,进行处理 while (true) { int c = waitKey(0); //按键值为 ESC ,退出 if ((char)c == 27) break; //按键值为 2 ,回复源图像 if ((char)c == '2') { maskImg = Scalar::all(0); srcImg2.copyTo(srcImg); imshow("image", srcImg); } //按键值为 1 或者空格 ,则进行处理 if ((char)c == '1' || (char)c == ' ') { //定义一些参数 int i, j, compCount = 0; vector<vector<Point>> contours; vector<Vec4i> hierarchy; //寻找轮廓 findContours(maskImg, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); //轮廓为空时的处理 if (contours.empty()) continue; //复制掩膜 Mat maskImg2(maskImg.size(), CV_32S); maskImg2 = Scalar::all(0); //循环绘制出轮廓 for (int i = 0; i >= 0; i = hierarchy[i][0], compCount++) drawContours(maskImg2, contours, i, Scalar::all(compCount+1), -1, 8, hierarchy, INT_MAX); //compCount 为零时的处理 if (compCount == 0) continue; //生成随机颜色 vector<Vec3b> colorTab; for (int j = 0; j < compCount; j++) { 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)); } //计算处理的时间 double dTime = (double)getTickCount(); watershed(srcImg2, maskImg2); dTime = (double)getTickCount() - dTime; cout << "\t处理时间为:" << dTime*1000. / getTickFrequency(); //双层循坏,将分水岭图像遍历存入 watershedImg 中 Mat watershedImg(maskImg2.size(), CV_8UC3); for (int i = 0; i < maskImg2.rows; i++) for (int j = 0; j < maskImg2.cols; j++) { int index = maskImg2.at<int>(i, j); if (index == -1) watershedImg.at<Vec3b>(i, j) = Vec3b(255, 255, 255); else if (index <= 0 || index > compCount) watershedImg.at<Vec3b>(i, j) = Vec3b(0, 0, 0); else watershedImg.at<Vec3b>(i, j) = colorTab[index - 1]; } //混合灰度图像和分水岭效果图并显示最终的窗口 watershedImg = watershedImg*0.5 + grayImg*0.5; imshow("watershed transform", watershedImg); } }}static void Mouse(int event, int x, int y, int flags, void*){ //处理鼠标不在窗口中的情况 if (x < 0 || x >= srcImg.cols || y < 0 || y >= srcImg.rows) return; //处理鼠标左键相关消息 if (event == EVENT_LBUTTONUP || !(flags & EVENT_FLAG_LBUTTON)) prevPt = Point(-1, -1); //处理鼠标左键按下并移动,绘制出白色线条 else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON)) { Point pt(x, y); if (prevPt.x < 0) prevPt = pt; line(maskImg, prevPt, pt, Scalar::all(255), 5, 8, 0); line(srcImg, prevPt, pt, Scalar::all(255), 5, 8, 0); prevPt = pt; imshow("WindowOne", srcImg); }}static void ShowHelpText(){ cout << "请先用鼠标在图片窗口中标记出大致的区域" << endl; cout << "然后再按键【1】或者【SPACE】启动算法" << endl; cout << "按键【1】或者【SPACE】启动算法" << endl; cout << "按键【2】- 恢复原始图像" << endl; cout << "按键【ESC】- 退出程序" << endl;}int main(){ ShowHelpText(); test(); waitKey(0); return 0;}
效果图:
版权声明:
本站文章均来自互联网搜集,如有侵犯您的权益,请联系我们删除,谢谢。
标签: #vc轮廓算法