SemicircularMeter.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include "SemicircularMeter.h"
  2. #include "DoublePointerAlgorithm.h"
  3. #include <iostream>
  4. #include <SegDetector.h>
  5. #include <NanoDetector.h>
  6. #include <opencv2\imgproc\types_c.h>
  7. #include<opencv2/imgproc/imgproc_c.h>
  8. #include "LineHandle.h"
  9. #include<numeric>
  10. #include<windows.h>
  11. using namespace std;
  12. using namespace cv;
  13. double SemicircularMeter::GetResult(cv::Mat sourceMat,bool IsShowWnd)
  14. {
  15. Mat mat;
  16. sourceMat.copyTo(mat);
  17. if (IsShowWnd) {
  18. imshow("原图", mat);
  19. waitKey(1);
  20. }
  21. int matCols = 400;
  22. Size size;
  23. resize(mat, mat, size, (float)matCols / mat.cols, (float)matCols / mat.cols);
  24. /* if (mat.cols - matCols >0)
  25. {
  26. resize(mat, mat, size, (float)matCols/mat.cols , (float)matCols / mat.cols);
  27. }
  28. else if (mat.cols - matCols < 0)
  29. {
  30. resize(mat, mat, size, (float)matCols /mat.cols , (float)matCols /mat.cols );
  31. }*/
  32. int width = mat.cols;// .width;
  33. int height = mat.rows;
  34. Mat grayMat;
  35. cvtColor(mat, grayMat, COLOR_BGR2GRAY); // 转换为灰度图
  36. //Mat thMat;
  37. adaptiveThreshold(grayMat, grayMat, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 201, 1);
  38. if (IsShowWnd) {
  39. imshow("二值化图adaptiveThreshold", grayMat);
  40. waitKey(1);
  41. }
  42. Mat biMat;
  43. bilateralFilter(grayMat, biMat, 9, 50, 50);
  44. if (IsShowWnd) {
  45. imshow("滤波去噪图", biMat);
  46. waitKey(1);
  47. }
  48. //Mat gaussMat;
  49. GaussianBlur(biMat, grayMat, Size(3, 3), 0, 0);
  50. if (IsShowWnd) {
  51. imshow("高斯模糊图", grayMat);
  52. waitKey(1);
  53. }
  54. medianBlur(grayMat, grayMat, 3);//中值滤波
  55. if (IsShowWnd) {
  56. imshow("中值滤波图", grayMat);
  57. waitKey(1);
  58. }
  59. double t1 = getTickCount();
  60. Mat ROI_1 = Mat(height, width, CV_8UC3, Scalar::all(255));
  61. cvtColor(ROI_1, ROI_1, COLOR_BGR2GRAY); // 转换为灰度图
  62. vector<Mat> vImgs;
  63. Mat result;
  64. vImgs.push_back(grayMat);
  65. vImgs.push_back(ROI_1);
  66. vconcat(vImgs, result); //垂直方向拼接
  67. //hconcat(vImgs, result); //水平方向拼接
  68. if (IsShowWnd)
  69. {
  70. imshow("拼接图", result);
  71. waitKey(1);
  72. }
  73. vector<Vec3f> circles;
  74. Mat whiteMat(height, width, CV_8UC3, Scalar::all(255));
  75. //Mat resizeMat(,)
  76. /* for (size_t i = 0; i < 200; i++)
  77. {
  78. hough_value += i;
  79. HoughCircles(grayMat, circles, HOUGH_GRADIENT, 1, 10, 100, hough_value);
  80. }*/
  81. Mat cannyMat;
  82. Canny(result, cannyMat, 50, 100);//边缘检测
  83. if (IsShowWnd) {
  84. imshow("边缘检测图", cannyMat);
  85. waitKey(1);
  86. }
  87. HoughCircles(cannyMat, circles, HOUGH_GRADIENT, 3, 30, 100,200, 150);
  88. vector<Vec4i> mylines;
  89. //HoughLinesP(grayMat, mylines, 1, CV_PI / 180, 100,5, 1);
  90. //for (size_t i = 0; i < mylines.size(); i++)
  91. //{
  92. // Vec4i cho_l = mylines[i];
  93. // //cho_l
  94. // line(whiteMat, Point(cho_l[0], cho_l[1]), Point(cho_l[2], cho_l[3]), Scalar(255, 0, 0), 1);
  95. //}
  96. vector<Vec3f> rightCircles;
  97. Mat resultCopy;
  98. result.copyTo(resultCopy);
  99. int distance2Center = 40;
  100. for (size_t i = 0; i < circles.size(); i++)
  101. {
  102. if (circles[i][1]>height)
  103. {
  104. if (abs(circles[i][0]-width/2)< distance2Center) //圆心横坐标和纵坐标在拼接后图像中心附近
  105. {
  106. if (abs(circles[i][1] - height) < distance2Center)
  107. {
  108. rightCircles.push_back(circles[i]);
  109. if (IsShowWnd)
  110. {
  111. Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
  112. int radius = cvRound(circles[i][2]);
  113. // circle center
  114. circle(resultCopy, center, 3, Scalar(0, 0, 0), -1, 5, 0);
  115. // circle outline
  116. circle(resultCopy, center, radius, Scalar(0, 0, 0), 3, 3, 0);
  117. }
  118. }
  119. }
  120. }
  121. }
  122. if (IsShowWnd) {
  123. namedWindow("霍夫圆图");
  124. imshow("霍夫圆图", resultCopy);
  125. waitKey(1);
  126. }
  127. adaptiveThreshold(result, result, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 151, 1);
  128. if (IsShowWnd) {
  129. imshow("二次二值化图", result);
  130. waitKey(1);
  131. }
  132. //int w = result.cols;
  133. //int h = result.rows;
  134. //uchar* uc_pixel;
  135. //for (int row = 0; row < h; row++) {
  136. // uc_pixel = result.data + row * result.step;
  137. // for (int col = 0; col < w; col++) {
  138. // //uc_pixel[0];
  139. // //sum += uc_pixel[0];
  140. // uc_pixel[1] = 255;
  141. // uc_pixel[2] = 255;
  142. // uc_pixel[0] = 255;
  143. // uc_pixel += 3;
  144. // }
  145. //}
  146. vector<int> zeroPositions;
  147. vector<pair<int, int>> rightNumSums;
  148. for (size_t j = 0; j < rightCircles.size(); j++)
  149. {
  150. Point ptCenter(cvRound(rightCircles[j][0]), cvRound(rightCircles[j][1]));
  151. int radius = cvRound(rightCircles[j][2]);
  152. Mat darkMatCopy;
  153. result.copyTo(darkMatCopy);
  154. vector<pair<int, int>> num_sum;
  155. //vector<,>
  156. for (size_t i = 300; i < 421; i++)
  157. {
  158. //Point ptStart(ptCenter.x - radius - 10, ptCenter.y);
  159. Point ptStart1(ptCenter.x + sin(i* CV_PI / 180) * (radius + 15), ptCenter.y - cos(i* CV_PI / 180) * (radius + 15));
  160. Point ptStart2(ptCenter.x + sin(i * CV_PI / 180) * (radius - 35), ptCenter.y - cos(i * CV_PI / 180) * (radius - 35));
  161. line(darkMatCopy, ptStart2, ptStart1, Scalar(0, 0, 0), 3);
  162. if (IsShowWnd)
  163. {
  164. imshow("SemicircularMeter", darkMatCopy);
  165. //Sleep(1000);
  166. waitKey(100);
  167. /*string str;
  168. std::cin >> str;*/
  169. }
  170. int matdis = abs( LineHandle::CalcMatSum(darkMatCopy) - LineHandle::CalcMatSum(result)) ;
  171. /* cout << "像素综合darkMatCopy" << i << ":" << LineHandle::CalcMatSum(darkMatCopy) << endl;
  172. cout << "像素综合result" << i << ":" << LineHandle::CalcMatSum(result) << endl;
  173. cout << "像素综合cha " << i << ":" << matdis << endl;*/
  174. num_sum.push_back(make_pair(i, matdis));
  175. if (num_sum.size()>3)
  176. {
  177. if (num_sum[num_sum.size()-3].second - matdis > 20000&& zeroPositions.size() <=j+1)
  178. {
  179. zeroPositions.push_back(i);
  180. }
  181. }
  182. result.copyTo(darkMatCopy);
  183. }
  184. std::sort(num_sum.begin(), num_sum.end(), LineHandle::ComparePairSecond);
  185. if (num_sum.size()>0)
  186. {
  187. rightNumSums.push_back(num_sum[0]);
  188. }
  189. }
  190. std::sort(rightNumSums.begin(), rightNumSums.end(), LineHandle::ComparePairSecond);
  191. if (rightNumSums.size() ==0)
  192. {
  193. return 0.01;
  194. }
  195. std::sort(zeroPositions.begin(), zeroPositions.end());
  196. if (zeroPositions.size() == 0)
  197. {
  198. zeroPositions.push_back( 310);
  199. }
  200. if (zeroPositions[0]>330)
  201. {
  202. zeroPositions[0] = 310;
  203. }
  204. float resutValue = (float)(rightNumSums[0].first - zeroPositions[0]) / 30 + 0.01;
  205. /*if (IsShowWnd) {
  206. imshow("霍夫直线图", whiteMat);
  207. waitKey(1);
  208. }*/
  209. /*if (IsShowWnd) {
  210. waitKey(1000*100);
  211. destroyAllWindows();
  212. }*/
  213. return abs(resutValue);
  214. }