精确寻找一个圆(接的一个小外包)



这是在群里接的一个外包,本来属于工业检测不能对外公布的,妈的!给了定金之后,人就跑了,我那么相信他居然骗我,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]

时间: 2024-10-11 04:56:58

精确寻找一个圆(接的一个小外包)的相关文章

每天一点点之css - 动画-一个圆绕着另一个圆动(绕着轨迹运动)

最近要开发一个类似星河的效果,需要小圆绕着一定的轨迹运动,这个时候我首先想到的是使用canvas来实现,在实现过程中发现这个实现起来不是很灵活,然后想到css3有动画也可以实现,下面是效果 注:图2是多个的效果,没有代码 html <div class="s"> <div class="m"> <div class="small small1"> <div class="small-p smal

装在匣子里的雪(一个流浪作者的自费小册)

<在路上> 当秋雨敲打我孤苦的心怀 当别人的热情化为我的无奈 也许只须伫立在雨中 一切都随风飘散 当心里堆起了天空的阴霾 当我挣脱不了那孤独的悲哀 也许只须轻轻地一呵 一切都重头再来 当我向秋天索要美丽的花环 编织纯净的梦幻 当我向自己渴求大雁的自在 也许只须在内心里寻找 一切都已存在 2005年9月3日 作者 北河浜 (www.561.cn) 2009年1月11日的下午,在莲坂外文书店的一侧,有一个面目清秀的男孩,局促自然的在角落里,地板上是一小叠他自己写的结集自印的有着牛皮纸封面的薄薄的小

AndroidStudio制作一个简易的订餐交易小demo【日常小练习】

AndroidStudio模拟制作一个简易的订餐交易小demo[日常小练习]     ————安德风 一.最终效果图: 二.布局设计activity_main.xml 1 <?xml version="1.0" encoding="utf-8"?> 2 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/a

[ jquery 过滤器 .first() | .last() ] 此方法用于在选择器的基础之上精确筛选出第一个(最后一个)元素(可以使用前导限制范围)

此方法用于在选择器的基础之上精确筛选出第一个(最后一个)元素(可以使用前导限制范围): 实例: <!DOCTYPE html> <html lang='zh-cn'> <head> <title>Insert you title</title> <meta http-equiv='description' content='this is my page'> <meta http-equiv='keywords' content

如何检测一个圆在多个圆内?

问题定义: 存在多个半径相同的圆,和一个半径不同的圆,如何判断半径不同的圆完全在一群圆内.下图演示了几种情况,左边是完全在圆内,右边不是. 解决方法之一: 对于红圆在某个黑圆之内或者在所有黑圆之外等的特例情形,可以用简单的圆圆之间的几何判断算法得到结果,对于其余部分相交的一般情形,如果同时满足以下两个条件则红圆在黑圆内: 1. 红圆与所有黑圆的交点都在黑圆内: 2. 黑圆之间的交点如果在红圆内,则其也必然在黑圆内. 否则,红圆不在黑圆内.

一个简单的“贪吃蛇”小游戏

一个简单的“贪吃蛇”小游戏 页面结构 简单的21x21的方块,页面结构 id为container的div包含所21个class名为row的div,每个row代表贪吃蛇的一整行,每个row中又包含21个div,代表这一行的每一个div方格,如果这个方格是空的话,div的类名为blank,如果这一个方格表示“贪吃蛇”的“食物”,div的类名为food,如果这一个方格表示“蛇”,div的类名为snake. CSS JS 然后我们思考下一个贪吃蛇游戏需要那些参数, 首先,界面中可见的元素无非就是空方格,

温故知新,基础复习(一个有序从大到小不重复的数列,任意给出一个sum值,求出数列中所有满足和为sum的数对)

温故知新,基础复习(一个有序从大到小不重复的数列,任意给出一个sum值,求出数列中所有满足和为sum的数对) #include<stdio.h> #include<stdlib.h> void PrintSumNumbers(int Arra[],int ASize,int Sum) { //O(1) if (ASize<2) { printf("The size of the Arra is invalid.\n"); return; } if(Sum&

一个,关于textarea的小问题。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <style> *{margin:0; padding:

看opengl 写代码(4) 画一个圆

opengl 编程指南 P30 下面代码 是 用 直线 连起来 画一个圆. // circle.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <gl/glut.h> #include <cmath> #define LENGTH 100 #define PI 3.1415926 void init(){ glClearColor(0,0,0,0); } void display(){ glColor3f