博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《图像处理实例》 之 精确寻找一个圆
阅读量:4287 次
发布时间:2019-05-27

本文共 4903 字,大约阅读时间需要 16 分钟。

以下是素材照片,就是寻找中间那个圆就可以了,说起来很简单,做起来不那么容易:

代码很简单,主要是预处理,下面会基体说明!

 处理过程的例子:

处理结果:


首先说明一下怎么寻找一个圆?(本来都忘记这篇博文没写完了,还是一个同志发邮件给我才想起来)

A.寻找圆的大方向

预处理好的话,下面哪种方法都可以得到精确的圆!

1.霍夫圆检测

    小伙伴们是不是有这种感觉,刚开始用霍夫的时候很兴奋,调调参数就能找到圆,但是随着你要求找的圆越来越复杂,是不是发现霍夫没用了?

  真的不是霍夫没用了,是你预处理没做好,看看霍夫的原理(极坐标的转换方式,我另一篇博文有说)

  一句话你处理的越好检测的就越好!!

2.拟合圆

  利用圆的函数去拟合,当然这里分为两种方案:

      a.点在圆的边缘,这个需要圆的函数拟合。

      b.点在圆内,这个需要圆的面积+函数拟合。

3.最小外接圆

  注意这不是和方法2相同!!这个方法是找到一个圆然后使得圆面积最小且包含所有点,算法实现应该有很多了,我个人认为用k-means寻找质心然后再找最小圆。

4.分水岭算法

  这个方法在另一篇博文实现,不在阐述:

B.预处理

--------->>>>>感觉没多大意义,貌似任何算法的基础都是预处理,具体问题具体对待


上代码:

 (代码写到一半就没写了,原因不想说了,后面也不想改进了,其实针对具体问题还有很多改进的地方,精确寻找圆不是很困难的事)

1 #include
2 #include
3 #include
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 imshow("Sourse Image", input_image); 22 blur(input_image, Middle_image, Size(3, 3), Point(-1, -1), 4); 23 cvtColor(Middle_image, Middle_image, COLOR_RGB2GRAY); 24 const float init_pointx = saturate_cast
(Middle_image.cols / 7); 25 const float init_pointy = saturate_cast
(Middle_image.rows / 7); 26 Rect roi_rect = Rect(Point2f(2 * init_pointx, 2 * init_pointy), Point2f(6 * init_pointx, 6 * init_pointy)); 27 Mat roi_Image = Middle_image(roi_rect); 28 Middle_image = roi_Image; 29 threshold(Middle_image, threshold_image, 0, 255, THRESH_BINARY_INV | THRESH_OTSU); 30 Mat kernel_rect = getStructuringElement(MORPH_ELLIPSE, Size(30, 30), Point(-1, -1)); 31 Mat kernel_circle = getStructuringElement(MORPH_ELLIPSE, Size(10, 10), Point(-1, -1)); 32 morphologyEx(threshold_image, threshold_image, MORPH_CLOSE, kernel_circle); 33 Mat RedImage = threshold_image.clone(); 34 morphologyEx(RedImage, threshold_image, MORPH_OPEN, kernel_rect); 35 for (size_t i = 0; i < threshold_image.rows; i++) 36 { 37 for (size_t j = 0; j < threshold_image.cols; j++) 38 { 39 RedImage.at
(i, j) = saturate_cast
(RedImage.at
(i, j) - threshold_image.at
(i, j)); 40 } 41 } 42 vector
> contours; 43 vector
hierarchy; 44 Mat showImage = Mat::zeros(RedImage.size(), CV_8UC1); 45 findContours(RedImage, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1, -1)); 46 for (size_t i = 0; i < contours.size(); i++) 47 { 48 if (minAreaRect(contours[i]).size.area() > 10000 && minAreaRect(contours[i]).size.height > 80 && minAreaRect(contours[i]).size.width > 80)//这个参数大概就可以 49 { 50 drawContours(showImage, contours, static_cast
(i), Scalar(255, 255, 255), 1); 51 } 52 } 53 vector
points; 54 for (int i = 0; i < showImage.rows; i++) 55 { 56 for (int j = 0; j < showImage.cols; j++) 57 { 58 if (showImage.at
(i, j) == 255) 59 { 60 points.push_back(Point(j, i)); 61 } 62 } 63 } 64 Point2f center; 65 float radius; 66 if (points.data() == 0) 67 { 68 printf("Don't detecte point"); 69 return -1; 70 } 71 minEnclosingCircle(points, center, radius); 72 center.x += 2 * init_pointx; 73 center.y += 2 * init_pointy; 74 Mat result = Mat::zeros(RedImage.size(), CV_8UC3); 75 circle(input_image, center, radius, Scalar(0, 0, 255), 2); 76 waitKey(0); 77 return 0; 78 } 79 void Threshold_Image_Bar(int, void *) 80 { 81 threshold(Middle_image, threshold_image, 65, 255,THRESH_BINARY_INV);//110,65 82 imshow("Threshold Image", threshold_image); 83 Mat kernel = getStructuringElement(MORPH_RECT, Size(50, 50), Point(-1, -1)); 84 Mat RedImage = threshold_image.clone(); 85 morphologyEx(RedImage, threshold_image, MORPH_OPEN, kernel); 86 for (size_t i = 0; i < threshold_image.rows; i++) 87 { 88 for (size_t j = 0; j < threshold_image.cols; j++) 89 { 90 RedImage.at
(i, j) = saturate_cast
(RedImage.at
(i, j) - threshold_image.at
(i, j)); 91 } 92 } 93 vector
> contours; 94 vector
hierarchy; 95 Mat showImage = Mat::zeros(RedImage.size(), CV_8UC1); 96 findContours(RedImage, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1, -1)); 97 for (size_t i = 0; i < contours.size(); i++) 98 { 99 if (boundingRect(contours[i]).area() > 20000)100 {101 drawContours(showImage, contours, static_cast
(i), Scalar(255, 255, 255), 1);102 }103 }104 vector
points;105 for (int i = 0; i < showImage.rows; i++)106 {107 for (int j = 0; j < showImage.cols; j++)108 {109 if (showImage.at
(i, j) == 255)110 {111 points.push_back(Point(j, i));112 }113 }114 }115 Point2f center;116 float radius;117 minEnclosingCircle(points, center, radius);118 Mat result = Mat::zeros(RedImage.size(), CV_8UC3);119 circle(input_image, center, radius, Scalar(0, 0, 255), 2);120 }

转载地址:http://iitgi.baihongyu.com/

你可能感兴趣的文章
2021-06-12
查看>>
论文笔记| The Emergence, Advancement and Future of Textual Answer Triggering
查看>>
论文笔记|Open Set Text Classification using Convolutional Neural Networks
查看>>
论文笔记: Hierarchical Chinese Legal event extraction via Pedal Attention Mechanism
查看>>
论文笔记 | Enhancing Pre-Trained Language Representations with Rich Knowledge for MRC
查看>>
论文笔记 | Text Summarization with Pretrained Encoders
查看>>
论文笔记:Document-level Event Extraction via Heterogeneous Graph-based Interaction Model with a Tracker
查看>>
论文笔记丨Inductive Unsupervised Domain Adaptation for Few-Shot Classification via Clustering
查看>>
论文笔记|GSum: A General Framework for Guided Neural Abstractive Summarization
查看>>
论文笔记 | Does Structure Matter? Encoding Documents for Machine Reading Comprehension
查看>>
论文笔记|Self-Supervised Test-Time Learning for Reading Comprehension
查看>>
论文笔记|Open-world Learning and Application to Product Classification
查看>>
论文笔记 _ ELECTRA_ Pre-training Text Encoders as Discriminators Rather than Generators
查看>>
【论文笔记】
查看>>
论文笔记:Exploring Pre-trained Language Models for Event Extraction and Generation
查看>>
论文解读 | QANET: COMBINING LOCAL CONVOLUTION WITH GLOBAL SELF-ATTENTION FOR READING COMPREHENSION
查看>>
论文笔记|Get To The Point: Summarization with Pointer-Generator Networks
查看>>
linux安装MySQL主从同步(一主两从)搭建与配置
查看>>
linux上mysql从库故障恢复步骤(删除数据重新同步)
查看>>
linux上安装jdk
查看>>