当前位置:   article > 正文

Opencv图像处理代码

opencv图像处理代码
  1. #include "head.h"
  2. void Person::showImg(Mat &img)
  3. {
  4. namedWindow("透明通道显示白色背景", WINDOW_NORMAL);
  5. if (img.empty())
  6. {
  7. cout << "图片路径错误" << endl;
  8. return ;
  9. }
  10. imshow("透明通道显示白色背景", img);
  11. imwrite("D:/opencvSourse/openImg/保存的图片/透明通道.png", img);
  12. }
  13. void Person::creatMat(Mat& img)
  14. {
  15. //creatOne
  16. Mat colorImg = Mat(255, 255, CV_8UC3);
  17. imshow("1", colorImg);
  18. //creatTow
  19. Mat cImg = Mat(Size(img.size()), img.type());
  20. imshow("2", colorImg);
  21. //深拷贝
  22. Mat img1 = img.clone();
  23. imshow("深拷贝1", img1);
  24. Mat img2;
  25. img.copyTo(img2);
  26. imshow("深拷贝2", img2);
  27. }
  28. void Person::ergodic(Mat& img)
  29. {
  30. imshow("原始", img);
  31. int dis = img.channels();
  32. for (int row = 0; row < img.rows; row++)
  33. {
  34. for (int col = 0; col < img.cols; col++)
  35. {
  36. if (dis == 1)
  37. {
  38. img.at<uchar>(row, col) = 255 - img.at<uchar>(row, col);
  39. }
  40. if (dis == 3)
  41. {
  42. Vec3b vec = img.at<Vec3b>(row, col);
  43. img.at<Vec3b>(row, col)[0] = 255 - vec[0];
  44. img.at<Vec3b>(row, col)[1] = 255 - vec[1];
  45. img.at<Vec3b>(row, col)[2] = 255 - vec[2];
  46. }
  47. }
  48. }
  49. imshow("转换", img);
  50. }
  51. void Person::homeErgodic(Mat& img)
  52. {
  53. imshow("原始", img);
  54. int dis = img.channels();
  55. for (int row = 0; row < img.rows; row++)
  56. {
  57. uchar* p = img.ptr<uchar>(row);
  58. if (dis == 1)
  59. {
  60. for (int col = 0; col < img.cols; col++)
  61. {
  62. *p = 255 - *p;
  63. }
  64. }
  65. for (int col = 0; col < img.cols; col++)
  66. {
  67. *p++ = 255 - *p;
  68. *p++ = 255 - *p;
  69. *p++ = 255 - *p;
  70. }
  71. }
  72. imshow("转换", img);
  73. }
  74. void Person::arithmetic()
  75. {
  76. Mat img1 = imread("D:/opencvDownLoad/opencv-4.5.1/opencv/sources/samples/data/WindowsLogo.jpg");
  77. Mat img2 = imread("D:/opencvDownLoad/opencv-4.5.1/opencv/sources/samples/data/LinuxLogo.jpg");
  78. Mat dst;
  79. add(img1, img2, dst);
  80. imshow("add", dst);
  81. subtract(img1, img2, dst);
  82. imshow("subtract", dst);
  83. multiply(img1, img2, dst);
  84. imshow("multiply", dst);
  85. divide(img1, img2, dst);
  86. imshow("divide", dst);
  87. }
  88. void trackbarFn(int min, void *img)
  89. {
  90. Mat newImg = *(Mat*)img;
  91. Mat src = Mat::zeros(newImg.size(), newImg.type());
  92. Mat dst;
  93. addWeighted(newImg, 1.0, src, 0, min, dst);
  94. imshow("调节", dst);
  95. }
  96. void trackbarFn1(int min, void* img)
  97. {
  98. Mat newImg = *(Mat*)img;
  99. Mat src = Mat::zeros(newImg.size(), newImg.type());
  100. Mat dst;
  101. double newMin = min / 100.0;
  102. addWeighted(newImg, newMin, src, 0, 1, dst);
  103. imshow("调节", dst);
  104. }
  105. void Person::myTrackBar(Mat &img)
  106. {
  107. namedWindow("调节");
  108. imshow("调节", img);
  109. string barName = "亮度调节";
  110. string barName1 = "对比度调节";
  111. string windName = "调节";
  112. int min = 20;
  113. int max = 200;
  114. createTrackbar(barName, windName, &min, max, trackbarFn, (void*)&img);
  115. createTrackbar(barName1, windName, &min, max, trackbarFn1, (void*)&img);
  116. }
  117. void Person::logic(Mat &img)
  118. {
  119. imshow("原图", img);
  120. Mat mask = Mat::zeros(img.size(), CV_8UC1);
  121. Mat dst;
  122. double width = img.rows;
  123. double height = img.cols;
  124. for (int cols = 100; cols < height / 2; cols++)
  125. {
  126. uchar*p = mask.ptr<uchar>(cols);
  127. for (int rows = 200; rows < width / 2; rows++)
  128. {
  129. *p++ = 255;
  130. }
  131. }
  132. imshow("mask", mask);
  133. bitwise_not(img, dst, mask);
  134. imshow("取反", dst);
  135. }
  136. void Person::varianceAverage(Mat& img)
  137. {
  138. Mat newImg = Mat::zeros(Size(255, 255), CV_8UC3);
  139. newImg = Scalar(0, 0, 255);
  140. vector<Mat> vec;
  141. split(newImg, vec);
  142. double min; double max; Point minloc; Point maxloc;
  143. for (int channels = 0; channels < vec.size(); channels++)
  144. {
  145. minMaxLoc(vec[channels], &min, &max, &minloc, &maxloc);
  146. cout << "最小值: " << min << "\t" << "最大值: " << max << "\t"
  147. << "最小值x: " << minloc.x << "\t" << "最小值y: " << minloc.y << endl;
  148. }
  149. Mat mean; Mat stdDev;
  150. for (int channels = 0; channels < vec.size(); channels++)
  151. {
  152. meanStdDev(vec[channels], mean, stdDev);
  153. cout << "通道: " << channels << " 均值: " << mean << "\t"
  154. << "方差: " << stdDev << endl;
  155. }
  156. }
  157. void Person::draw()
  158. {
  159. Mat canvas = Mat::zeros(Size(500, 500), CV_8UC3);
  160. line(canvas, Point(0, 0), Point(500, 500), Scalar(150, 120, 180), 2, LINE_AA);
  161. rectangle(canvas, Rect(10, 200, 300, 300), Scalar(0, 0, 200), -1, 8);
  162. circle(canvas, Point(250, 250), 100, Scalar(200, 10, 10), -1, 8);
  163. ellipse(canvas, RotatedRect(Point(300, 100), Size(200, 100), 45.5), Scalar(0, 200, 10), -1, LINE_AA);
  164. imshow("convas", canvas);
  165. Mat rngImg = Mat::zeros(Size(500, 500), CV_8UC3);
  166. RNG rng(12345);
  167. while (true)
  168. {
  169. int x = rng.uniform(0, 500); int y = rng.uniform(0, 500);
  170. int x1 = rng.uniform(0, 500); int y1 = rng.uniform(0, 500);
  171. line(rngImg, Point(x, y), Point(x1, y1), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, LINE_AA);
  172. imshow("rng", rngImg);
  173. int key = waitKey(100);
  174. rngImg = Scalar(0, 0, 0);
  175. if (key == 27)
  176. {
  177. break;
  178. }
  179. }
  180. }
  181. void Person::splitMerge(Mat& img)
  182. {
  183. imshow("原图", img);
  184. vector<Mat> vec;
  185. split(img, vec);
  186. vec[0] = 0;
  187. Mat dst;
  188. merge(vec, dst);
  189. imshow("dst", dst);
  190. cout << img.cols << "高" << img.rows;
  191. Rect roi = Rect(100, 50, 300, 300);
  192. //浅拷贝ROI
  193. Mat roiImg = img(roi);
  194. //深拷贝ROI
  195. //Mat roiImg = img(roi).clone();
  196. imshow("ROI", roiImg);
  197. imshow("浅拷贝", img);
  198. }
  199. //直方图
  200. //void Person::histogram(Mat& img)
  201. //{
  202. // imshow("原图", img);
  203. // vector<Mat> vec;
  204. // split(img, vec);
  205. // Mat bImg; Mat gImg; Mat rImg;
  206. // //竖条个数
  207. // int bins = 256;
  208. // //范围
  209. // float rangs[] = {0,255};
  210. // //多个通道rangs
  211. // const float* rangsChannels = { rangs };
  212. // //直方图
  213. // calcHist(&vec[0], 1, 0, Mat(), bImg, 1, &bins, &rangsChannels, true, false);
  214. // calcHist(&vec[1], 1, 0, Mat(), gImg, 1, &bins, &rangsChannels, true, false);
  215. // calcHist(&vec[2], 1, 0, Mat(), rImg, 1, &bins, &rangsChannels, true, false);
  216. //
  217. // //归一化
  218. // Mat dst = Mat::zeros(Size(600, 500), CV_8UC3);
  219. // int margin = 50;
  220. // int dH = dst.rows - 2 * margin;
  221. // normalize(bImg, bImg, 0, dH, NORM_MINMAX, -1, Mat());
  222. // normalize(gImg, gImg, 0, dH, NORM_MINMAX, -1, Mat());
  223. // normalize(rImg, rImg, 0, dH, NORM_MINMAX, -1, Mat());
  224. //
  225. // //把直方图放到归一化的img
  226. //
  227. // //求bins
  228. // float xStep = (dst.cols - 2 * margin) / 256.0;
  229. // cout << xStep << endl;
  230. // //i最大值为256, 但是后面i++, so: i = 255
  231. // for (int i = 0; i < 255; i++)
  232. // {
  233. // //求dims
  234. // //float dims = bImg.at<float>(i, 0);
  235. // //line p1
  236. // /* Point p1 = Point(xStep * i, margin+(dst.rows - dims) );
  237. // dims = dst.at<float>(i+1, 0);
  238. // Point p2 = Point(xStep * i, margin + (dst.rows - dims) );*/
  239. //
  240. //
  241. // //line(dst, p1, p2,Scalar(255,0,0),2,8);
  242. // line(dst, Point(xStep * i + margin, margin + (dH - bImg.at<float>(i, 0))), Point(xStep * (i + 1) + margin, margin + (dH - bImg.at<float>(i + 1, 0))), Scalar(255, 0, 0),2,8,0);
  243. // line(dst, Point(xStep * i + margin, margin + (dH - gImg.at<float>(i, 0))), Point(xStep * (i + 1) + margin, margin + (dH - gImg.at<float>(i + 1, 0))), Scalar(0, 255, 0),2,8,0);
  244. // line(dst, Point(xStep * i + margin, margin + (dH - rImg.at<float>(i, 0))), Point(xStep * (i + 1) + margin, margin + (dH - rImg.at<float>(i + 1, 0))), Scalar(0, 0, 255),2,8,0);
  245. // }
  246. // imshow("直方图", dst);
  247. //}
  248. void Person::histogram(Mat& img)
  249. {
  250. imshow("原始", img);
  251. int bins = 256;
  252. float rangs[] = { 0,255 };
  253. const float* everyRangs = { rangs };
  254. vector<Mat> vec;
  255. split(img, vec);
  256. Mat bImg; Mat gImg; Mat rImg;
  257. calcHist(&vec[0], 1, 0, Mat(), bImg, 1, &bins, &everyRangs, true, false);
  258. calcHist(&vec[1], 1, 0, Mat(), gImg, 1, &bins, &everyRangs, true, false);
  259. calcHist(&vec[2], 1, 0, Mat(), rImg, 1, &bins, &everyRangs, true, false);
  260. Mat dst = Mat::zeros(Size(600, 400), img.type());
  261. float margin = 50;
  262. float height = dst.rows - 2 * 50;
  263. float xStep = (dst.cols - 2 * margin) / float(bins);
  264. cout << "步长" << xStep << endl;
  265. cout << "高度" << height << endl;
  266. normalize(bImg, bImg, 0, height, NORM_MINMAX, -1, Mat());
  267. normalize(gImg, gImg, 0, height, NORM_MINMAX, -1, Mat());
  268. normalize(rImg, rImg, 0, height, NORM_MINMAX, -1, Mat());
  269. for (int i = 0; i < bins-1; i++)
  270. {
  271. line(dst, Point(i * xStep + margin, margin + (height - bImg.at<float>(i, 0))), Point((i + 1) * xStep + margin, margin + (height - bImg.at<float>((i + 1) , 0))), Scalar(255, 0, 0), 2, 8, 0);
  272. line(dst, Point(i * xStep + margin, margin + (height - gImg.at<float>(i, 0))), Point((i + 1) * xStep + margin, margin + (height - gImg.at<float>((i + 1) , 0))), Scalar(0, 255, 0), 2, 8, 0);
  273. line(dst, Point(i * xStep + margin, margin + (height - rImg.at<float>(i, 0))), Point((i + 1) * xStep + margin, margin + (height - rImg.at<float>((i + 1) , 0))), Scalar(0, 0, 255), 2, 8, 0);
  274. }
  275. imshow("归一化", dst);
  276. }
  277. //直方图均衡化
  278. void Person::myEqualizeHist(Mat& img)
  279. {
  280. cvtColor(img, img, COLOR_BGR2GRAY);
  281. imshow("灰色", img);
  282. Mat equImg;
  283. equalizeHist(img, equImg);
  284. Mat src; Mat dst;
  285. int bins = 256;
  286. float rang[] = { 0,255 };
  287. const float* rangs = { rang };
  288. calcHist(&img, 1, 0, Mat(), src, 1, &bins, &rangs, true, false);
  289. calcHist(&equImg, 1, 0, Mat(), dst, 1, &bins, &rangs, true, false);
  290. Mat outImg = Mat::zeros(Size(600, 400), CV_8UC3);
  291. int margin = 50;
  292. float Hight = float(outImg.rows) - float(2 * margin);
  293. float step = (outImg.cols - 2 * margin) / float(bins);
  294. cout << Hight << "\t" << step << endl;
  295. normalize(src, src, 0, Hight, NORM_MINMAX, -1, Mat());
  296. normalize(dst, dst, 0, Hight, NORM_MINMAX, -1, Mat());
  297. for (int i = 0; i < bins - 1; i++)
  298. {
  299. line(outImg, Point(step * i + margin, margin + (Hight - src.at<float>(i, 0))), Point(step * (i + 1) + margin, margin + (Hight - src.at<float>(i + 1, 0))), Scalar(0, 0, 255), 2, 8, 0);
  300. line(outImg, Point(step * i + margin, margin + (Hight - dst.at<float>(i, 0))), Point(step * (i + 1) + margin, margin + (Hight - dst.at<float>(i + 1, 0))), Scalar(0, 255, 255), 2, 8, 0);
  301. }
  302. imshow("结果", outImg);
  303. }
  304. //直方图比较
  305. void Person::histCompare(Mat& img, Mat& img1)
  306. {
  307. Mat dst; Mat dst1;
  308. int bins[] = { 200,200,200 };
  309. float rang[] = { 0,255 };
  310. const float* rangs[] = { rang,rang,rang };
  311. int channls[] = { 0,1,2 };
  312. calcHist(&img, 1, channls, Mat(), dst, img.channels(), bins, rangs, true, false);
  313. calcHist(&img1, 1, channls, Mat(), dst1, img.channels(), bins, rangs, true, false);
  314. normalize(dst, dst, 0, 1, NORM_MINMAX, -1, Mat());
  315. normalize(dst1, dst1, 0, 1, NORM_MINMAX, -1, Mat());
  316. float result1 = compareHist(dst, dst1, HISTCMP_BHATTACHARYYA); // 越大越不像
  317. float resemble = compareHist(dst, dst, HISTCMP_BHATTACHARYYA);
  318. cout << "巴氏距离" << result1 << "\t" << resemble << endl;
  319. float result2 = compareHist(dst, dst1, HISTCMP_CORREL);
  320. float resemble1 = compareHist(dst, dst, HISTCMP_CORREL);
  321. cout << "相似性" << result2 << "\t" << resemble1 << endl;
  322. }
  323. void Person::colormap(Mat& img)
  324. {
  325. imshow("原始", img);
  326. Mat dst;
  327. applyColorMap(img, dst, COLORMAP_AUTUMN);
  328. imshow("颜色表", dst);
  329. }
  330. void Person::myblur(Mat& img)
  331. {
  332. imshow("img", img);
  333. float width = img.cols;
  334. float height = img.rows;
  335. Mat dst = img.clone(); Mat dst1 = img.clone();
  336. float b_value; float g_value; float r_value;
  337. for (int h = 1; h < height - 1; h++)
  338. {
  339. for (int w = 1; w < width - 1; w++)
  340. {
  341. dst.at<Vec3b>(h, w)[0] = (img.at<Vec3b>(h - 1, w - 1)[0] + img.at<Vec3b>(h - 1, w)[0] + img.at<Vec3b>(h - 1, w + 1)[0] +
  342. img.at<Vec3b>(h, w - 1)[0] + img.at<Vec3b>(h, w)[0] + img.at<Vec3b>(h, w + 1)[0] +
  343. img.at<Vec3b>(h + 1, w - 1)[0] + img.at<Vec3b>(h + 1, w)[0] + img.at<Vec3b>(h + 1, w + 1)[0])
  344. / 9;
  345. dst.at<Vec3b>(h, w)[1] = (img.at<Vec3b>(h - 1, w - 1)[1] + img.at<Vec3b>(h - 1, w)[1] + img.at<Vec3b>(h - 1, w + 1)[1] +
  346. img.at<Vec3b>(h, w - 1)[1] + img.at<Vec3b>(h, w)[1] + img.at<Vec3b>(h, w + 1)[1] +
  347. img.at<Vec3b>(h + 1, w - 1)[1] + img.at<Vec3b>(h + 1, w)[1] + img.at<Vec3b>(h + 1, w + 1)[1]) / 9;
  348. dst.at<Vec3b>(h, w)[2] = (img.at<Vec3b>(h - 1, w - 1)[2] + img.at<Vec3b>(h - 1, w)[2] + img.at<Vec3b>(h - 1, w + 1)[2] +
  349. img.at<Vec3b>(h, w - 1)[2] + img.at<Vec3b>(h, w)[2] + img.at<Vec3b>(h, w + 1)[2] +
  350. img.at<Vec3b>(h + 1, w - 1)[2] + img.at<Vec3b>(h + 1, w)[2] + img.at<Vec3b>(h + 1, w + 1)[2]) / 9;
  351. }
  352. }
  353. imshow("myBlur", dst);
  354. blur(img, dst1, Size(3, 3), Point(-1, -1), BORDER_DEFAULT);
  355. imshow("API", dst1);
  356. }
  357. void Person::borderBlur(Mat& img)
  358. {
  359. imshow("ipt", img);
  360. Mat dst;
  361. float margin = 9;
  362. //copyMakeBorder(img, dst, margin, margin, margin, margin, BORDER_DEFAULT);
  363. copyMakeBorder(img, dst, margin, margin, margin, margin, BORDER_CONSTANT,Scalar(0,0,200));
  364. imshow("卷积", dst);
  365. }
  366. void Person::GauBox(Mat& img)
  367. {
  368. imshow("ipt", img);
  369. Mat dst; Mat dst1;
  370. boxFilter(img, dst, -1, Size(5, 5), Point(-2, -2), true, BORDER_DEFAULT);
  371. GaussianBlur(img, dst1, Size(5, 5), BORDER_DEFAULT);
  372. imshow("高斯模糊", dst1);
  373. imshow("盒子模糊", dst);
  374. }
  375. void Person::customFilter(Mat& img)
  376. {
  377. imshow("原图", img);
  378. //自定义均值卷积
  379. Mat dst;
  380. int width = 15;
  381. int height = 15;
  382. //归一化
  383. Mat kernel = Mat::ones(width, height, CV_32F) / float(width * height);
  384. filter2D(img, dst, -1, kernel, Point(-1, -1), 0, BORDER_DEFAULT);
  385. imshow("自定义均值滤波", dst);
  386. //自定义高斯卷积
  387. Mat dst1;
  388. int gWidth = 2;
  389. int gHeight = 2;
  390. /*Mat kernel1 = (Mat_<int>(gWidth, gHeight) << 1, 0, 0, 0, 1, 0, 0, 0, -1);*/
  391. Mat kernel1 = (Mat_<int>(gWidth, gHeight) << 1, 0, 0,-1);
  392. filter2D(img, dst1, CV_32F, kernel1, Point(-1, -1), 200, BORDER_DEFAULT);
  393. convertScaleAbs(dst1, dst1);
  394. imshow("非均值滤波", dst1);
  395. }
  396. void Person::myRobot(Mat& img)
  397. {
  398. //robot
  399. imshow("原图", img);
  400. Mat xKernel = (Mat_<int>(2, 2) << 1, 0, 0, -1);
  401. Mat yKernel = (Mat_<int>(2, 2) << 0, 1, -1, 0);
  402. Mat xImg; Mat yImg; Mat dst; Mat dst1; Mat dst2;
  403. filter2D(img, xImg, CV_32F, xKernel, Point(-1, -1), 0, BORDER_DEFAULT);
  404. filter2D(img, yImg, CV_32F, yKernel, Point(-1, -1), 0, BORDER_DEFAULT);
  405. convertScaleAbs(xImg, xImg);
  406. convertScaleAbs(yImg, yImg);
  407. dst = xImg + yImg;
  408. imshow("robot", dst);
  409. //sobel
  410. Sobel(img, xImg, CV_32F, 1, 0);
  411. Sobel(img, yImg, CV_32F, 1, 0);
  412. convertScaleAbs(xImg, xImg);
  413. convertScaleAbs(yImg, yImg);
  414. addWeighted(xImg, 0.5, yImg, 0.5, 0, dst1);
  415. imshow("sobel", dst1);
  416. //scharr
  417. Scharr(img, xImg, CV_32F, 1, 0);
  418. Scharr(img, yImg, CV_32F, 1, 0);
  419. convertScaleAbs(xImg, xImg);
  420. convertScaleAbs(yImg, yImg);
  421. addWeighted(xImg, 0.5, yImg, 0.5, 0, dst1);
  422. imshow("scharr", dst1);
  423. }
  424. void Person::myLaplacian(Mat& img)
  425. {
  426. imshow("原图", img);
  427. Mat dst; Mat dst1;
  428. Laplacian(img, dst, -1, 3, 1, 123, BORDER_DEFAULT);
  429. imshow("拉普拉斯", dst);
  430. //图像锐化 = 拉普拉斯+img本身
  431. Mat kernel = (Mat_<int>(3,3)<<0, -1, 0,
  432. -1, 5, -1,
  433. 0, -1, 0);
  434. filter2D(img, dst1, CV_32F, kernel, Point(-1, -1), 0, BORDER_DEFAULT);
  435. convertScaleAbs(dst1, dst1);
  436. imshow("锐化", dst1);
  437. }
  438. void Person::sum(Mat& img)
  439. {
  440. //blur - lapla
  441. imshow("原图", img);
  442. Mat gaussImg; Mat laplaImg; Mat sumImg;
  443. GaussianBlur(img, gaussImg, Size(3, 3), 0);
  444. Laplacian(img, laplaImg, -1, 3,1.0,0,BORDER_DEFAULT);
  445. addWeighted(gaussImg, 1.0, laplaImg, -0.7, 0, sumImg);
  446. imshow("sum锐化", sumImg);
  447. }
  448. void Person::noise(Mat& img)
  449. {
  450. imshow("原图", img);
  451. //椒盐噪声
  452. Mat saltPepper = img.clone();
  453. RNG rng(123456);
  454. int width = img.cols;
  455. int height = img.rows;
  456. int number = 10000;
  457. for (int i = 0; i < number; i++) {
  458. int x = rng.uniform(0, width);
  459. int y = rng.uniform(0, height);
  460. if (i % 2)
  461. {
  462. saltPepper.at<Vec3b>(x, y) = Vec3b(255, 255, 255) ;
  463. }
  464. else
  465. {
  466. saltPepper.at<Vec3b>(x, y) = Vec3b(0, 0, 0) ;
  467. }
  468. }
  469. imshow("椒盐噪声", saltPepper);
  470. //高斯噪声
  471. Mat dst;
  472. Mat randnImg = Mat::zeros(img.size(), img.type());
  473. randn(randnImg, Scalar(20, 30, 40), Scalar(10, 15, 20));
  474. imshow("高斯原图", randnImg);
  475. add(img, randnImg, dst);
  476. imshow("高斯噪声", dst);
  477. Mat dst1; Mat dst2; Mat dst3;
  478. //利用中值去除椒盐噪声
  479. medianBlur(saltPepper, dst1, 3);
  480. imshow("中值去噪", dst1);
  481. //均值去噪
  482. GaussianBlur(dst, dst2, Size(3, 3), 0);
  483. medianBlur(dst, dst3, 3);
  484. imshow("高斯去噪", dst2);
  485. imshow("中值去噪高斯", dst3);
  486. }
  487. void Person::cleanNoise(Mat& img)
  488. {
  489. Mat dst; Mat dst1;
  490. imshow("原图", img);
  491. //双边模糊去噪
  492. bilateralFilter(img, dst, 10, 100, 10);
  493. imshow("高斯去噪", dst);
  494. //非局部均值滤波
  495. fastNlMeansDenoising(img, dst1, 10, 7, 21);
  496. imshow("非局部均值去噪", dst1);
  497. }
  498. void myCanny(int min, void* img)
  499. {
  500. Mat newImg = *(Mat*)img;
  501. Mat dst; Mat dst1;
  502. Canny(newImg, dst, min, 200, 3, false);
  503. bitwise_and(newImg, newImg, dst1, dst);
  504. imshow("边缘提取", dst1);
  505. }
  506. void Person::canny(Mat& img)
  507. {
  508. string barName = "提取范围";
  509. string winName = "边缘提取";
  510. namedWindow(winName, WINDOW_AUTOSIZE);
  511. imshow("原图", img);
  512. int min = 50;
  513. int max = 220;
  514. createTrackbar(barName, winName, &min, max, myCanny,(void*)&img);
  515. myCanny(0, (void*)&img);
  516. }
  517. //二值化分割
  518. void Person::myThreshold(Mat& img)
  519. {
  520. Mat dst;
  521. cvtColor(img, img, COLOR_BGR2GRAY);
  522. imshow("原图灰色图像", img);
  523. //二值化
  524. threshold(img, dst, 127, 255, THRESH_BINARY);
  525. imshow("二值化", dst);
  526. //反二值化
  527. threshold(img, dst, 127, 255, THRESH_BINARY_INV);
  528. imshow("反二值化", dst);
  529. //阈值化切割, 小于阈值化保持原数据, 否则为T
  530. threshold(img, dst, 127, 255, THRESH_TRUNC);
  531. imshow("阈值化切割", dst);
  532. //阈值化,大于T的保持原数据, 其他的为0
  533. threshold(img, dst, 127, 255, THRESH_TOZERO);
  534. imshow("阈值化", dst);
  535. //反阈值化,
  536. threshold(img, dst, 127, 255, THRESH_TOZERO_INV);
  537. imshow("反阈值化", dst);
  538. }
  539. //返回二值化分割
  540. Mat Person::myThresh(const Mat& img)
  541. {
  542. Mat newImg = img.clone();
  543. GaussianBlur(newImg, newImg, Size(3, 3), 0);
  544. cvtColor(newImg, newImg, COLOR_BGR2GRAY);
  545. Mat dst;
  546. threshold(newImg, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
  547. return dst;
  548. }
  549. //全局求阈值分割
  550. void Person::tThreshold(Mat& img)
  551. {
  552. Mat dst;
  553. cvtColor(img, img, COLOR_BGR2GRAY);
  554. imshow("原图", img);
  555. Scalar m = mean(img);
  556. threshold(img, dst, m[0], 255, THRESH_BINARY);
  557. imshow("均值", dst);
  558. //otsu
  559. double otsu = threshold(img, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
  560. imshow("otsu", dst);
  561. //三角法
  562. double angle = threshold(img, dst, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);
  563. imshow("三角法", dst);
  564. cout << "otsu切割阈值T: " << otsu << "\t" << "三角法: " << angle << endl
  565. <<"\t" << "均值:"<<m[0];
  566. }
  567. //自适应阈值分割
  568. void Person::myAdaptive(Mat &img)
  569. {
  570. Mat dst;
  571. cvtColor(img, img, COLOR_BGR2GRAY);
  572. imshow("原图", img);
  573. threshold(img, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
  574. imshow("otsu", dst);
  575. //自适应
  576. adaptiveThreshold(img, dst, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 21, 5);
  577. imshow("自适应", dst);
  578. }
  579. //联通组件
  580. void Person::connectComp(Mat& img)
  581. {
  582. RNG rn(12345);
  583. imshow("原图", img);
  584. Mat denoi;
  585. GaussianBlur(img, denoi, Size(11, 11), 0);
  586. imshow("去噪", denoi);
  587. Mat grey;
  588. cvtColor(denoi, grey, COLOR_BGR2GRAY);
  589. Mat cutting;
  590. threshold(grey, cutting, 0, 255, THRESH_BINARY | THRESH_OTSU);
  591. imshow("二值化", cutting);
  592. Mat labels = Mat::zeros(img.size(), CV_32S);
  593. int num = connectedComponents(cutting, labels, 8, CV_32S, CCL_DEFAULT);
  594. cout << "数量" << num << endl;
  595. //染色
  596. vector<Vec3b>color(num);
  597. color[0] = Vec3b(0, 0, 0);
  598. for (int index = 1; index < num; index++)
  599. {
  600. color[index] = Vec3b(rn.uniform(0, 256), rn.uniform(0, 256), rn.uniform(0, 256));
  601. }
  602. Mat result = Mat::zeros(img.size(), CV_8UC3);
  603. for (int x = 0; x < result.rows; x++)
  604. {
  605. for (int y = 0; y < result.cols; y++)
  606. {
  607. result.at<Vec3b>(x, y) = color[labels.at<int>(x, y)];
  608. }
  609. }
  610. //显示详细信息
  611. Mat stats; Mat centroids;
  612. int num1 = connectedComponentsWithStats(cutting, labels, stats, centroids, 8, CV_32S, CCL_DEFAULT);
  613. string numn = to_string(num1);
  614. for (int i = 1; i < num1; i++)
  615. {
  616. //center
  617. double centerX = centroids.at<double>(i, 0);
  618. double centerY = centroids.at<double>(i, 1);
  619. //ractangle
  620. int racLeft = stats.at<int>(i, CC_STAT_LEFT);
  621. int racTop = stats.at<int>(i, CC_STAT_TOP);
  622. int racWidth = stats.at<int>(i, CC_STAT_WIDTH);
  623. int racHeight = stats.at<int>(i, CC_STAT_HEIGHT);
  624. int area = stats.at<int>(i, CC_STAT_AREA);
  625. cout << "面积" << i << area << endl;
  626. string s = to_string(area);
  627. circle(result, Point(centerX, centerY), 3, Scalar(255, 20, 20), 2, 8);
  628. Rect rect = Rect(racLeft, racTop, racWidth, racHeight);
  629. rectangle(result, rect, Scalar(0, 0, 200), 2, LINE_8);
  630. putText(result, s, Point(centerX, centerY), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 2, 8);
  631. putText(result, numn, Point(50,50), FONT_HERSHEY_PLAIN, 3, Scalar(0, 255, 0), 2, 8);
  632. }
  633. imshow("切割染色", result);
  634. }
  635. //void Person::connectComp(Mat& img)
  636. //{
  637. // RNG rng(12345);
  638. // imshow("ipt", img);
  639. // GaussianBlur(img, img, Size(3, 3), 0);
  640. // Mat gray; Mat binary;
  641. // cvtColor(img, gray, COLOR_BGR2GRAY);
  642. // threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
  643. // imshow("二值化", binary);
  644. // Mat lables = Mat::zeros(binary.size(), CV_32S);
  645. // int num = connectedComponents(binary, lables, 8, CV_32S, CCL_DEFAULT);
  646. // vector<Vec3b>vec(num);
  647. // vec[0] = Vec3b(0, 0, 0);
  648. // for (int i = 0; i < num; i++)
  649. // {
  650. // vec[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
  651. // }
  652. // Mat result = Mat::zeros(img.size(), img.type());
  653. // for (int x = 0; x < result.rows; x++)
  654. // {
  655. // for (int y = 0; y < result.cols; y++)
  656. // {
  657. // int lab = lables.at<int>(x, y);
  658. // result.at<Vec3b>(x, y) = vec[lab];
  659. // }
  660. // }
  661. // imshow("颜色表", result);
  662. //}
  663. //轮廓提取
  664. void Person::myContour(Mat& img)
  665. {
  666. Mat binaryImg = this->myThresh(img).clone();
  667. Mat dst = Mat::zeros(img.size(),CV_8UC3);
  668. Mat dst1 = dst.clone();
  669. Mat dst2 = dst.clone();
  670. imshow("二值化", binaryImg);
  671. vector<vector<Point>>contours;
  672. vector<Vec4i>hierarchy;
  673. findContours(binaryImg, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
  674. for (int i = 0; i < contours.size(); i++)
  675. {
  676. drawContours(dst, contours, i, Scalar(0, 255, 0), 2, LINE_8);
  677. }
  678. imshow("轮廓", dst);
  679. findContours(binaryImg, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
  680. drawContours(dst1, contours, -1, Scalar(255, 0, 0), 2, 8);
  681. imshow("最大轮廓", dst1);
  682. }
  683. //轮廓细节
  684. void Person::contourDetails(Mat& img)
  685. {
  686. Mat result = Mat::zeros(img.size(), CV_8UC3);
  687. imshow("原图", img);
  688. GaussianBlur(img, img, Size(3, 3), 0);
  689. cvtColor(img, img, COLOR_BGR2GRAY);
  690. Mat dst;
  691. threshold(img, dst, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
  692. imshow("二值化分割", dst);
  693. vector<vector<Point>>contours;
  694. vector<Vec4i>hierarchy;
  695. //Mat result = Mat::zeros(img.size(), CV_8UC3);
  696. findContours(dst, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
  697. /*double minLength;
  698. cout << "输入最小周长" << endl;
  699. cin >> minLength;
  700. double minArea;
  701. cout << "输入最小面积" << endl;
  702. cin >> minArea;*/
  703. for (int i = 0; i < contours.size(); i++)
  704. {
  705. if (arcLength(contours[i],true) < 100 || contourArea(contours[i]) < 10) continue;
  706. //最大外接矩形
  707. Rect maxRect = boundingRect(contours[i]);
  708. rectangle(result, maxRect, Scalar(200, 20, 20), 2, 8);
  709. //最小外接矩形
  710. RotatedRect minRect = minAreaRect(contours[i]);
  711. ellipse(result, minRect, Scalar(20, 200, 20), 2, 8);
  712. Point2f pts[4];
  713. //通过点连接成线绘制最小外接矩形
  714. minRect.points(pts);
  715. for (int i = 0; i < 4; i++)
  716. {
  717. line(result, pts[i], pts[(i + 1)%4], Scalar(20, 20, 200), 2, 8);
  718. }
  719. drawContours(result, contours, -1, Scalar(100, 100, 100), 2, 8);
  720. cout << "轮廓" << i << "面积: " << contourArea(contours[i]) << "\t" << "轮廓" << i << "周长: " << arcLength(contours[i], true) << endl;
  721. }
  722. imshow("输出", result);
  723. }
  724. //轮廓比较
  725. void contoursFn( Mat &dst, const vector<vector<Point>> &imgContours, const vector<vector<Point>>& srcContours)
  726. {
  727. Moments srcMm = moments(srcContours[0]);
  728. Mat srcHu;
  729. HuMoments(srcMm, srcHu);
  730. for (int i = 0; i < imgContours.size(); i++)
  731. {
  732. Mat imgHu;
  733. Moments imgMm = moments(imgContours[i]);
  734. double pX = imgMm.m10 / imgMm.m00;
  735. double pY = imgMm.m01 / imgMm.m00;
  736. circle(dst, Point(pX, pY), 3, Scalar(200, 200, 20), 2, LINE_8);
  737. HuMoments(imgMm, imgHu);
  738. double ss = matchShapes(imgHu, srcHu, CONTOURS_MATCH_I1,0);
  739. //cout << ss << endl;
  740. if (ss < 2.0)
  741. {
  742. cout << ss << endl;
  743. drawContours(dst, imgContours, i, Scalar(20, 20, 200), 2, 8);
  744. }
  745. else
  746. {
  747. cout << "匹配不成功" << endl;
  748. }
  749. }
  750. imshow("axx", dst);
  751. /*for (int i = 0; i < srcContours.size(); i++)
  752. {
  753. moImg.push_back(moments(srcContours[i]));
  754. }*/
  755. }
  756. void Person::contourComp(Mat& img, Mat& src)
  757. {
  758. namedWindow("匹配轮廓图", WINDOW_FREERATIO);
  759. imshow("匹配轮廓图", src);
  760. Mat binaryImg = this->myThresh(img);
  761. Mat binarysrc = this->myThresh(src);
  762. vector<vector<Point>> imgContours;
  763. vector<vector<Point>> srcContours;
  764. vector<Vec4i> hierarchy;
  765. vector<Vec4i> hierarchy1;
  766. findContours(binaryImg, imgContours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
  767. findContours(binarysrc, srcContours, hierarchy1, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
  768. contoursFn(img, imgContours, srcContours);
  769. }
  770. //根据轮廓拟合
  771. void Person::contourProx(Mat& img)
  772. {
  773. imshow("原图", img);
  774. Mat binaryImg = this->myThresh(img);
  775. vector<vector<Point>> contours;
  776. vector<Vec4i> hierarchy;
  777. findContours(binaryImg, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
  778. for (int i = 0; i < contours.size(); i++)
  779. {
  780. Mat poly;
  781. approxPolyDP(contours[i], poly, 4, true);
  782. cout << "图形:" << i << "行数 " << poly.rows << "列数: " << poly.cols << endl;
  783. double len = arcLength(contours[i], true);
  784. double Area = contourArea(contours[i]);
  785. Moments mm = moments(contours[i]);
  786. double pX = mm.m10 / mm.m00;
  787. double pY = mm.m01 / mm.m00;
  788. //if (poly.rows = 4)
  789. //{
  790. // putText(img, "矩形", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
  791. // string Sarea = "面积: " + to_string(Area);
  792. // string Slen = "周长: " + to_string(len);
  793. // /*putText(img, Sarea, Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
  794. // putText(img, Slen, Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);*/
  795. // circle(img, Point(pX, pY), 4, Scalar(20, 20, 200), 2, LINE_8);
  796. //}
  797. //if (poly.rows = 3)
  798. //{
  799. // putText(img, "三角形", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
  800. // string Sarea = "面积: " + to_string(Area);
  801. // string Slen = "周长: " + to_string(len);
  802. // /*putText(img, Sarea, Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
  803. // putText(img, Slen, Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);*/
  804. // circle(img, Point(pX, pY), 4, Scalar(20, 20, 200), 2, LINE_8);
  805. //}
  806. //if (poly.rows = 6)
  807. //{
  808. // putText(img, "6边形", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
  809. // string Sarea = "面积: " + to_string(Area);
  810. // string Slen = "周长: " + to_string(len);
  811. ///* putText(img, Sarea, Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
  812. // putText(img, Slen, Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);*/
  813. // circle(img, Point(pX, pY), 4, Scalar(20, 20, 200), 2, LINE_8);
  814. //}
  815. //if (poly.rows > 12)
  816. //{
  817. // putText(img, "圆", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
  818. // string Sarea = "面积: " + to_string(Area);
  819. // string Slen = "周长: " + to_string(len);
  820. ///* putText(img, Sarea, Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
  821. // putText(img, Slen, Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);*/
  822. // circle(img, Point(pX, pY), 4, Scalar(20, 20, 200), 2, LINE_8);
  823. //}
  824. putText(img, "我", Point(pX, pY - 20), FONT_HERSHEY_PLAIN, 1, Scalar(20, 200, 20), 2, 8);
  825. }
  826. imshow("判断轮廓图像", img);
  827. }
  828. void Person::myImg(Mat& img)
  829. {
  830. if (img.empty())
  831. {
  832. cout << "图片路径错误" << endl;
  833. return ;
  834. }
  835. imshow("原图", img);
  836. }
  837. void Person::myThreshold(Mat& img)
  838. {
  839. Mat gray; Mat binary;
  840. cvtColor(img, gray, COLOR_BGR2GRAY);
  841. //通过mean求阈值T
  842. Scalar T = mean(gray);
  843. threshold(gray, binary, T[0], 255, THRESH_BINARY);
  844. cout << "全局阈值T: " << T[0] << endl;
  845. imshow("全局阈值", binary);
  846. //通过otsu求
  847. double otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
  848. imshow("otsu", binary);
  849. cout << "otsu: " << otsu << endl;
  850. //三角法
  851. double trian = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);
  852. imshow("trian", binary);
  853. cout << "triangle: " << trian << endl;
  854. }
  855. //返回除燥的灰色图像
  856. Mat Person::myGray(Mat& img)
  857. {
  858. Mat gray; Mat binary;
  859. GaussianBlur(img, img, Size(3, 3), 0);
  860. cvtColor(img, gray, COLOR_BGR2GRAY);
  861. return gray;
  862. }
  863. //返回二值化
  864. Mat Person::myBinary(Mat& img)
  865. {
  866. Mat binary;
  867. Mat gray = this->myGray(img);
  868. //threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
  869. threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
  870. return binary;
  871. }
  872. void Person::adpThreshold(Mat& img)
  873. {
  874. Mat dst; Mat dst1;
  875. imshow("原图", img);
  876. Mat binary = this->myGray(img);
  877. imshow("灰色", binary);
  878. double T = threshold(binary, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
  879. imshow("全局阈值", dst);
  880. adaptiveThreshold(binary, dst1, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 23, 5);
  881. imshow("自适应阈值", dst1);
  882. }
  883. //联通组件
  884. void Person::myCopNect(Mat& img)
  885. {
  886. RNG rng(12345);
  887. imshow("原图", img);
  888. Mat binary = this->myBinary(img);
  889. imshow("二值化", binary);
  890. Mat labels = Mat::zeros(img.size(), CV_32S);
  891. int num = connectedComponents(binary, labels, 8, CV_32S, CCL_DEFAULT);
  892. cout << "组件" << num - 1 << endl;
  893. vector<Vec3b> vec(num);
  894. vec[0] = Vec3b(0, 0, 0);
  895. for (int i = 1; i < vec.size(); i++)
  896. {
  897. vec[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
  898. }
  899. Mat src = Mat::zeros(img.size(), img.type());
  900. for (int y = 0; y < img.rows; y++)
  901. {
  902. for (int x = 0; x < img.cols; x++)
  903. {
  904. int label = labels.at<int>(y, x);
  905. src.at<Vec3b>(y, x) = vec[label];
  906. }
  907. }
  908. imshow("lable", src);
  909. }
  910. void Person::compnect1(Mat& img)
  911. {
  912. imshow("原图", img);
  913. RNG rng(12345);
  914. Mat binary = this->myBinary(img);
  915. Mat labels = Mat::zeros(img.size(),CV_32S);
  916. Mat stats; Mat centroids;
  917. int num = connectedComponentsWithStats(binary, labels, stats, centroids, 8, CV_32S, CCL_DEFAULT);
  918. Mat result = Mat::zeros(img.size(), CV_8UC3);
  919. vector<Vec3b> color(num);
  920. color[0] = Vec3b(0, 0, 0);
  921. for (int i = 1; i < num; i++)
  922. {
  923. color[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
  924. }
  925. for (int row = 0; row < img.rows; row++)
  926. {
  927. for (int col = 0; col < img.cols; col++)
  928. {
  929. int lable = labels.at<int>(row, col);
  930. result.at<Vec3b>(row, col) = color[lable];
  931. }
  932. }
  933. for (int i = 1; i < num; i++)
  934. {
  935. double pX = centroids.at<double>(i, 0);
  936. double pY = centroids.at<double>(i, 1);
  937. int left = stats.at<int>(i, CC_STAT_LEFT);
  938. int top = stats.at<int>(i, CC_STAT_TOP);
  939. int width = stats.at<int>(i, CC_STAT_WIDTH);
  940. int height = stats.at<int>(i, CC_STAT_HEIGHT);
  941. string area = to_string( stats.at<int>(i, CC_STAT_AREA));
  942. putText(result, area, Point(pX - 10, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(200, 20, 20), 2, 8);
  943. rectangle(result,Rect(left,top,width,height),Scalar(20,20,200),2,8);
  944. }
  945. putText(result, to_string(num - 1), Point(50, 50), FONT_HERSHEY_PLAIN, 2, Scalar(150, 150, 150));
  946. imshow("connect", result);
  947. }
  948. //轮廓发现
  949. void Person::myContours(Mat& img)
  950. {
  951. Mat result = Mat::zeros(img.size(), CV_8UC3);
  952. imshow("原图", img);
  953. Mat binary = this->myBinary(img);
  954. vector<vector<Point>> contours;
  955. vector<Vec4i> hierachy;
  956. findContours(binary, contours, hierachy, RETR_LIST,CHAIN_APPROX_SIMPLE, Point());
  957. //drawContours(result, contours, -1, Scalar(0, 0, 200), 2, 8);
  958. for (int i = 0; i < contours.size(); i++)
  959. {
  960. drawContours(result, contours, i, Scalar(0, 0, 200), 2, 8);
  961. }
  962. imshow("轮廓", result);
  963. }
  964. void Person::myContours1(Mat& img)
  965. {
  966. imshow("原图", img);
  967. Mat binary = this->myBinary(img);
  968. vector<vector<Point>> contours;
  969. vector<Vec4i> hierarchy;
  970. findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
  971. for (int i = 0; i < contours.size(); i++)
  972. {
  973. double area = contourArea(contours[i]);
  974. double length = arcLength(contours[i], true);
  975. if (area < 100 || length <10) continue;
  976. drawContours(img, contours, i,Scalar(0,0,200),-1,8);
  977. Rect box = boundingRect(contours[i]);
  978. rectangle(img, box, Scalar(200, 0, 0), 2, 8);
  979. ellipse(img, minAreaRect(contours[i]), Scalar(0, 200, 0), 2, 8);
  980. Point2f poin[4];
  981. RotatedRect roRec = minAreaRect(contours[i]);
  982. roRec.points(poin);
  983. for (int i = 0; i < 4; i++)
  984. {
  985. line(img, poin[i], poin[(i + 1) % 4], Scalar(157, 157, 157), 2, 8);
  986. }
  987. }
  988. imshow("轮廓", img);
  989. }
  990. void Person::momentCop(Mat& img,Mat &img1)
  991. {
  992. imshow("模板", img);
  993. imshow("匹配", img1);
  994. Mat binary = this->myBinary(img);
  995. Mat binary1 = this->myBinary(img1);
  996. vector<vector<Point>> contours;
  997. vector<vector<Point>> contours1;
  998. vector<Vec4i> hierarchy;
  999. vector<Vec4i> hierarchy1;
  1000. findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
  1001. findContours(binary1, contours1, hierarchy1, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
  1002. Mat src; Mat src1;
  1003. cout << contours.size() << endl;
  1004. for (int i = 0; i < contours.size(); i++)
  1005. {
  1006. Moments res = moments(contours[i]);
  1007. Moments res1 = moments(contours1[0]);
  1008. HuMoments(res, src);
  1009. HuMoments(res1, src1);
  1010. double num = matchShapes(src, src1, CONTOURS_MATCH_I1, 0);
  1011. if (num < 2)
  1012. {
  1013. drawContours(img, contours, i, Scalar(0, 0, 200), 2, 8);
  1014. }
  1015. cout << num << endl;
  1016. double pX = res.m10 / res.m00;
  1017. double pY = res.m01 / res.m00;
  1018. circle(img, Point(pX, pY), 3, Scalar(200, 0, 0), 2, 8);
  1019. }
  1020. imshow("模板", img);
  1021. }
  1022. void Person::approxP(Mat& img)
  1023. {
  1024. imshow("原图", img);
  1025. Mat binary = this->myBinary(img);
  1026. vector<vector<Point>> contours;
  1027. vector<Vec4i> hierarchy;
  1028. findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
  1029. Mat src;
  1030. for (int i = 0; i < contours.size(); i++)
  1031. {
  1032. double pX = moments(contours[i]).m10 / moments(contours[i]).m00;
  1033. double pY = moments(contours[i]).m01 / moments(contours[i]).m00;
  1034. approxPolyDP(contours[i], src, 4, true);
  1035. cout << "端点数量: " << src.rows << endl;
  1036. if (src.rows == 4)
  1037. {
  1038. putText(img, "rec", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 200), 2, 8);
  1039. circle(img, Point(pX, pY), 2, Scalar(250, 20, 20), 2, 8);
  1040. }
  1041. if (src.rows == 3)
  1042. {
  1043. putText(img, "triangle", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 200), 2, 8);
  1044. circle(img, Point(pX, pY), 2, Scalar(250, 20, 20), 2, 8);
  1045. }
  1046. if (src.rows == 6)
  1047. {
  1048. putText(img, "hex", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 200), 2, 8);
  1049. circle(img, Point(pX, pY), 2, Scalar(250, 20, 20), 2, 8);
  1050. }
  1051. if (src.rows > 10)
  1052. {
  1053. putText(img, "ploy", Point(pX, pY - 10), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 200), 2, 8);
  1054. circle(img, Point(pX, pY), 2, Scalar(250, 20, 20), 2, 8);
  1055. }
  1056. }
  1057. imshow("图形判断", img);
  1058. }
  1059. //返回二值化轮廓
  1060. vector<vector<Point>> Person::contourOne(Mat& img)
  1061. {
  1062. Mat binary = this->myBinary(img);
  1063. vector<vector<Point>> contours;
  1064. vector<Vec4i> hierarchy;
  1065. findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
  1066. return contours;
  1067. }
  1068. //拟合
  1069. void Person::myFitEllipse(Mat& img)
  1070. {
  1071. imshow("原图", img);
  1072. vector<vector<Point>> contours = this->contourOne(img);
  1073. for (int i = 0; i < contours.size(); i++)
  1074. {
  1075. RotatedRect rotRect = fitEllipse(contours[i]);
  1076. Point center = rotRect.center;
  1077. string height = to_string(rotRect.size.height);
  1078. string width = to_string(rotRect.size.width);
  1079. string are = to_string(rotRect.size.area());
  1080. ellipse(img, rotRect, Scalar(255, 0, 10), 2, 8);
  1081. circle(img, center, 3, Scalar(0, 255, 0), 2, LINE_8);
  1082. }
  1083. imshow("处理图", img);
  1084. }
  1085. //霍夫直线
  1086. void Person::Houline(Mat& img)
  1087. {
  1088. imshow("原图", img);
  1089. Mat binary = this->myBinary(img);
  1090. vector<Vec3f>lines;
  1091. HoughLines(binary, lines, 1, CV_PI / 180, 160, 0, 0);
  1092. Point p1; Point p2;
  1093. for (int i = 0; i < lines.size(); i++)
  1094. {
  1095. double step = lines[i][0];
  1096. double angle = lines[i][1];
  1097. double add = lines[i][2];
  1098. cout << "直线" << i << "\t" << "距离: " << step << "角度: " << angle << i << "累加点: " << add << endl;
  1099. double x = cos(angle);
  1100. double y = sin(angle);
  1101. double x0 = step * x;
  1102. double y0 = step * y;
  1103. p1.x = cvRound(x0 + 500 * -y);
  1104. p1.y = cvRound(y0 + 500 * x);
  1105. p2.x = cvRound(x0 - 500 * -y);
  1106. p2.y = cvRound(y0 - 500 * x);
  1107. line(img, p1, p2, Scalar(0, 0, 255), 2, 8);
  1108. }
  1109. imshow("霍夫直线", img);
  1110. }
  1111. //霍夫线段
  1112. void Person::houlineP(Mat& img)
  1113. {
  1114. Mat result = Mat::zeros(img.size(), img.type());
  1115. imshow("原图", img);
  1116. Mat binary = this->myBinary(img);
  1117. vector<Vec4i> lines;
  1118. imshow("binary",binary);
  1119. HoughLinesP(binary, lines, 1, CV_PI / 180, 80,30,10);
  1120. //Point p1; Point p2;
  1121. for (int i = 0; i < lines.size(); i++)
  1122. {
  1123. /*p1.x = lines[i][0];
  1124. p1.y = lines[i][1];
  1125. p2.x = lines[i][2];
  1126. p2.y = lines[i][3];*/
  1127. //line(result, p1, p2, Scalar(0, 0, 255), 1, 8);
  1128. line(result, Point(lines[i][0], lines[i][1]), Point(lines[i][2], lines[i][3]), Scalar(255, 0, 0), 1, 8);
  1129. }
  1130. imshow("霍夫直线", result);
  1131. }
  1132. //霍夫圆检测
  1133. void Person::houghCir(Mat &img)
  1134. {
  1135. imshow("原图", img);
  1136. Mat result = Mat::zeros(img.size(), CV_8UC3);
  1137. Mat gray;
  1138. cvtColor(img, gray, COLOR_BGR2GRAY);
  1139. GaussianBlur(gray, gray, Size(15,15), 2, 2);
  1140. vector<Vec3f> cir;
  1141. int dp = 2;
  1142. double cirSpace = 5;
  1143. int add = 100;
  1144. int maxThreshold = 100;
  1145. double cirMin = 15; double cirMax = 100;
  1146. HoughCircles(gray, cir, HOUGH_GRADIENT, dp, cirSpace, add, maxThreshold, cirMin, cirMax);
  1147. for (int i = 0; i < cir.size(); i++)
  1148. {
  1149. int cenX = round(cir[i][0]);
  1150. int cenY = round(cir[i][1]);
  1151. int radius = round(cir[i][2]);
  1152. circle(result, Point(cenX, cenY), radius, Scalar(0, 0, 200), 2, 8);
  1153. }
  1154. imshow("霍夫找园", result);
  1155. }
  1156. void Person::erodeDilate(Mat& img)
  1157. {
  1158. imshow("原图", img);
  1159. Mat result;
  1160. Mat result1;
  1161. Mat binary = this->myBinary(img);
  1162. Mat rect = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
  1163. erode(img, result1, rect);
  1164. imshow("腐蚀", result1);
  1165. dilate(img, result, rect);
  1166. imshow("膨胀", result);
  1167. }
  1168. //开闭操作
  1169. void Person::openCloss(Mat& img)
  1170. {
  1171. Mat dst;
  1172. imshow("原图", img);
  1173. Mat binary = this->myBinary(img);
  1174. imshow("二值化", binary);
  1175. Mat kernel = getStructuringElement(MORPH_RECT, Size(15, 1), Point(-1, -1));
  1176. morphologyEx(binary, dst, MORPH_OPEN, kernel, Point(-1, -1), 1);
  1177. imshow("腐蚀", dst);
  1178. }
  1179. //形态学梯度
  1180. void Person::gradi(Mat& img)
  1181. {
  1182. if (img.empty())
  1183. {
  1184. cout << "图片路径错误" << endl;
  1185. return;
  1186. }
  1187. imshow("原图", img);
  1188. Mat gray; Mat binary;
  1189. cvtColor(img, gray, COLOR_BGR2GRAY);
  1190. Mat Ksize = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
  1191. Mat grad; Mat inside; Mat extral; Mat src; Mat src1;
  1192. erode(gray, src, Ksize, Point(-1, -1));
  1193. dilate(gray, src1, Ksize, Point(-1, -1));
  1194. subtract(src1, src, grad);
  1195. subtract(gray, src, inside);
  1196. subtract(src1, gray, extral);
  1197. imshow("形态学", grad);
  1198. threshold(grad, grad, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
  1199. imshow("基本形态学梯度", grad);
  1200. }
  1201. //黑帽和顶帽
  1202. void Person::morph1(Mat& img)
  1203. {
  1204. imshow("原图", img);
  1205. Mat binary = this->myBinary(img);
  1206. Mat dst;
  1207. Mat rect = getStructuringElement(MORPH_ELLIPSE, Size(14, 14), Point(-1, -1));
  1208. imshow("二值化", binary);
  1209. //MORPH_TOPHAT
  1210. morphologyEx(binary, dst, MORPH_BLACKHAT, rect);
  1211. imshow("顶帽", dst);
  1212. }
  1213. //击中与不击中
  1214. void Person::morph2(Mat& img)
  1215. {
  1216. imshow("原图", img);
  1217. Mat dst;
  1218. Mat binary = this->myBinary(img);
  1219. Mat rect = getStructuringElement(MORPH_CROSS, Size(12, 12), Point(-1, -1));
  1220. morphologyEx(binary, dst, MORPH_HITMISS, rect);
  1221. imshow("匹配模板", dst);
  1222. }
  1223. //处理小案列
  1224. void Person::case1(Mat& img)
  1225. {
  1226. Mat dst = Mat::zeros(img.size(), img.type());
  1227. if (img.empty())
  1228. {
  1229. cout << "路径错误" << endl;
  1230. return;
  1231. }
  1232. imshow("原图", img);
  1233. Mat src; Mat gray; Mat binary;
  1234. GaussianBlur(img, src, Size(3, 3), 0);
  1235. cvtColor(src, gray, COLOR_BGR2GRAY);
  1236. threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
  1237. imshow("二值化", binary);
  1238. vector<vector<Point>> contours;
  1239. vector<Vec4i> hierarchy;
  1240. findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
  1241. double are1;
  1242. int maxAre = -1;
  1243. int index = -1;
  1244. cout << contours.size() << endl;
  1245. cout << "最终111" << "\t" << index << endl;
  1246. for (int i = 0; i < contours.size(); i++)
  1247. {
  1248. Rect rec = boundingRect(contours[i]);
  1249. if (rec.width >= img.cols || rec.height > img.rows) continue;
  1250. int area = round( contourArea(contours[i]));
  1251. cout << "面积:" << area << endl;
  1252. double leng = arcLength(contours[i],true);
  1253. if (maxAre < area)
  1254. {
  1255. maxAre = area;
  1256. index = i;
  1257. }
  1258. }
  1259. drawContours(dst, contours, index, Scalar(255, 0, 0), 2, 8);
  1260. Mat pts;
  1261. approxPolyDP(contours[index], pts, 4, false);
  1262. for (int i = 0; i < pts.rows; i++)
  1263. {
  1264. Vec2i pt = pts.at<Vec2i>(i, 0);
  1265. circle(dst, Point(pt[0], pt[1]), 3, Scalar(0, 0, 255), 2, 8);
  1266. }
  1267. imshow("shuchu ", dst);
  1268. }

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号