1. 程式人生 > >精確尋找一個圓(接的一個小外包)

精確尋找一個圓(接的一個小外包)

blog std lin name ret radius truct tro math.h


這是在群裏接的一個外包,本來屬於工業檢測不能對外公布的,媽的!給了定金之後,人就跑了,我那麽相信他居然騙我,500塊錢打水漂了。。。。。。圖像處理出了這樣的人,是我們行業的敗類,要是說幫個忙,我可以給你寫半天程序,要是給錢那就錢貨兩清,這種人給了定金後面拿了程序直接走人了,啥也不說了,就當自己學習吧!

以下是他的QQ小號和支付寶,希望大家別再上當:

技術分享

技術分享


以下是素材照片,就是尋找中間那個圓就可以了,說起來很簡單,做起來不那麽容易:

技術分享

技術分享

處理過程的例子:

技術分享

技術分享

處理結果:

技術分享

技術分享

上代碼:

  1 #include<iostream>
  2 #include <opencv2/opencv.hpp>
  3 #include <math.h>
  4 using namespace cv;
  5 using namespace std;
  6 
  7 int Threshold_Value = 176;
  8 const int Threshold_Max_value = 255;
  9 const int Threshold_type_value = 3;
 10 
 11 Mat input_image, threshold_image, output_image, Middle_image;
12 13 void Threshold_Image_Bar(int, void *); 14 15 int main(int argc, char**argv) 16 { 17 input_image = imread("b.jpg"); 18 if (input_image.data == NULL) { 19 return -1; cout << "can‘t open image.../"; 20 } 21 //----------簡單預處理 22 imshow("Sourse Image
", input_image); 23 blur(input_image, Middle_image, Size(3, 3), Point(-1, -1), 4); 24 imshow("Blur Image", Middle_image); 25 cvtColor(Middle_image, Middle_image, COLOR_RGB2GRAY); 26 imshow("Gray Image", Middle_image); 27 //-----------利用比例對圖像進行ROI操作 28 const float init_pointx = saturate_cast<float>(Middle_image.cols / 7); 29 const float init_pointy = saturate_cast<float>(Middle_image.rows / 7); 30 Rect roi_rect = Rect(Point2f(2 * init_pointx, 2 * init_pointy), Point2f(6 * init_pointx, 6 * init_pointy)); 31 Mat roi_Image = Middle_image(roi_rect); 32 Middle_image = roi_Image; 33 //----------這裏使用大法定律自適應操作圖像,程序的穩定性很高 34 threshold(Middle_image, threshold_image, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);//這個65可以更改看效果 35 imshow("Threshold Image", threshold_image); 36 //----------這裏通過形態學操作對圖像稍作調整 37 Mat kernel_rect = getStructuringElement(MORPH_ELLIPSE, Size(30, 30), Point(-1, -1)); 38 Mat kernel_circle = getStructuringElement(MORPH_ELLIPSE, Size(10, 10), Point(-1, -1)); 39 morphologyEx(threshold_image, threshold_image, MORPH_CLOSE, kernel_circle); 40 Mat RedImage = threshold_image.clone(); 41 /*--------這是當時求外面圓的代碼,這裏不需要了,求外面的圓不準確 42 Mat otherImage; 43 Canny(threshold_image, otherImage, 50, 200); 44 vector<vector<Point>> contours; 45 vector<Vec4i> hierarchy; 46 Mat showImage = Mat::zeros(RedImage.size(), CV_8UC1); 47 findContours(RedImage, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(-1, -1)); 48 for (size_t i = 0; i < contours.size(); i++) 49 { 50 if (boundingRect(contours[i]).area() > 10000)//這個參數大概就可以 51 { 52 drawContours(showImage, contours, static_cast<int>(i), Scalar(255, 255, 255), 1); 53 Point2f center; 54 float radius; 55 minEnclosingCircle(contours[i], center, radius); 56 Mat result = Mat::zeros(RedImage.size(), CV_8UC3); 57 circle(input_image, center, radius, Scalar(0, 0, 255), 2); 58 } 59 } 60 */ 61 morphologyEx(RedImage, threshold_image, MORPH_OPEN, kernel_rect); 62 //---------圖像刪除旁邊幹擾區域 63 for (size_t i = 0; i < threshold_image.rows; i++) 64 { 65 for (size_t j = 0; j < threshold_image.cols; j++) 66 { 67 RedImage.at<uchar>(i, j) = saturate_cast<uchar>(RedImage.at<uchar>(i, j) - threshold_image.at<uchar>(i, j)); 68 } 69 } 70 vector<vector<Point>> contours; 71 vector<Vec4i> hierarchy; 72 Mat showImage = Mat::zeros(RedImage.size(), CV_8UC1); 73 findContours(RedImage, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1, -1)); 74 for (size_t i = 0; i < contours.size(); i++) 75 { 76 //------如果圓找的位置太離譜,這裏可進行優化 77 //------如果找的圓位置不精確這裏更改數字 78 if (minAreaRect(contours[i]).size.area() > 10000 && minAreaRect(contours[i]).size.height > 80 && minAreaRect(contours[i]).size.width > 80)//這個參數大概就可以 79 { 80 drawContours(showImage, contours, static_cast<int>(i), Scalar(255, 255, 255), 1); 81 } 82 } 83 //-----------將點存入容器進行點集操作 84 vector<Point> points; 85 for (int i = 0; i < showImage.rows; i++) 86 { 87 for (int j = 0; j < showImage.cols; j++) 88 { 89 if (showImage.at<uchar>(i, j) == 255) 90 { 91 points.push_back(Point(j, i)); 92 } 93 } 94 } 95 //----------點擬合圓,這裏代碼只是找一個圓,也可優化成找多個圓 96 Point2f center; 97 float radius; 98 if (points.data() == 0) 99 { 100 printf("Don‘t detecte point"); 101 return -1; 102 } 103 minEnclosingCircle(points, center, radius); 104 center.x += 2 * init_pointx; 105 center.y += 2 * init_pointy; 106 Mat result = Mat::zeros(RedImage.size(), CV_8UC3); 107 circle(input_image, center, radius, Scalar(0, 0, 255), 2); 108 109 /*namedWindow("Threshold Image", 1); 110 createTrackbar("閾值調整", "Threshold Image", &Threshold_Value, 255, Threshold_Image_Bar); 111 Threshold_Image_Bar(0, 0);*/ 112 imshow("result", input_image); 113 waitKey(0); 114 return 0; 115 } 116 //------這是調試用的滑塊,已經調試好了,代碼搬上去了,如果你需要調試那就再使用 117 void Threshold_Image_Bar(int, void *) 118 { 119 threshold(Middle_image, threshold_image, 65, 255,THRESH_BINARY_INV);//110,65 120 imshow("Threshold Image", threshold_image); 121 Mat kernel = getStructuringElement(MORPH_RECT, Size(50, 50), Point(-1, -1));//這個參數無所謂的 122 Mat RedImage = threshold_image.clone(); 123 /* 124 Mat otherImage; 125 Canny(threshold_image, otherImage, 50, 200); 126 vector<vector<Point>> contours; 127 vector<Vec4i> hierarchy; 128 Mat showImage = Mat::zeros(RedImage.size(), CV_8UC1); 129 findContours(RedImage, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(-1, -1)); 130 for (size_t i = 0; i < contours.size(); i++) 131 { 132 if (boundingRect(contours[i]).area() > 10000)//這個參數大概就可以 133 { 134 drawContours(showImage, contours, static_cast<int>(i), Scalar(255, 255, 255), 1); 135 Point2f center; 136 float radius; 137 minEnclosingCircle(contours[i], center, radius); 138 Mat result = Mat::zeros(RedImage.size(), CV_8UC3); 139 circle(input_image, center, radius, Scalar(0, 0, 255), 2); 140 } 141 } 142 */ 143 morphologyEx(RedImage, threshold_image, MORPH_OPEN, kernel); 144 for (size_t i = 0; i < threshold_image.rows; i++) 145 { 146 for (size_t j = 0; j < threshold_image.cols; j++) 147 { 148 RedImage.at<uchar>(i, j) = saturate_cast<uchar>(RedImage.at<uchar>(i, j) - threshold_image.at<uchar>(i, j)); 149 } 150 } 151 vector<vector<Point>> contours; 152 vector<Vec4i> hierarchy; 153 Mat showImage = Mat::zeros(RedImage.size(), CV_8UC1); 154 findContours(RedImage, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1, -1)); 155 for (size_t i = 0; i < contours.size(); i++) 156 { 157 if (boundingRect(contours[i]).area() > 20000)//這個參數大概就可以 158 { 159 drawContours(showImage, contours, static_cast<int>(i), Scalar(255, 255, 255), 1); 160 } 161 } 162 vector<Point> points; 163 for (int i = 0; i < showImage.rows; i++) 164 { 165 for (int j = 0; j < showImage.cols; j++) 166 { 167 if (showImage.at<uchar>(i, j) == 255) 168 { 169 points.push_back(Point(j, i)); 170 } 171 } 172 } 173 Point2f center; 174 float radius; 175 minEnclosingCircle(points, center, radius); 176 Mat result = Mat::zeros(RedImage.size(), CV_8UC3); 177 circle(input_image, center, radius, Scalar(0, 0, 255), 2); 178 }

如需要原工程發送到郵箱:[email protected]

精確尋找一個圓(接的一個小外包)