一种基于OpenCV的多扇区圆检测方法
- 格式:pdf
- 大小:364.70 KB
- 文档页数:5
opencv 实时计算相机拍摄的圆半径的算法好的,下面是使用`opencv`计算相机拍摄的圆半径的算法步骤:1. 导入图片,将其转换为灰度图。
2. 使用`cv2.HoughCircles()`函数对图片中的圆形进行检测。
3. 循环遍历检测到的圆形,使用`cv2.circle()`函数绘制出检测到的圆形。
下面是上述步骤的代码实现:```pythonimport numpy as npimport cv2# 读取图片image = cv2.imread("123.jpg")# 复制图片output = image.copy()# 将图片转换为灰度图gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 检测图片中的圆形circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.2, 100)# 如果检测到圆形if circles is not None:# 将检测到的圆形转换为整数类型circles = np.round(circles(0, :)).astype("int")# 遍历检测到的圆形for (x, y, r) in circles:# 绘制检测到的圆形cv2.circle(output, (x, y), r, (0, 255, 0), 4)# 绘制圆形轮廓cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)# 显示结果cv2.imshow("output", np.hstack((image, output)))# 等待用户按下任意键cv2.waitKey(0)```在上述代码中,首先使用`cv2.imread()`函数读取图片,并通过`cv2.copy()`函数复制一份原始图片。
2017-5-28圆弧检测(opencv-qt)F:\学科、技能、编程\【编程-⽂件\proj\圆弧检测(opencv-qt)可以⾃动或者⼿动测量圆弧液柱的⾓度:使⽤说明:找圆⼼(最⼩⼆乘拟合)相关代码#include <iostream>#include <opencv2/opencv.hpp>using namespace std;using namespace cv;bool circleLeastFit(CvSeq* points, double ¢er_x, double ¢er_y, double &radius);//最⼩⼆乘法拟合函数int main(){const char* winname ="winname";//const char* winname1 ="winname1";//const char* winname2 ="winname2";//const char* winname3 ="winname3";char * picname = "P11.jpg";//加载原图IplImage * pImage = cvLoadImage(picname);//分量图像IplImage *pR = cvCreateImage(cvGetSize(pImage),IPL_DEPTH_8U,1);IplImage *pG = cvCreateImage(cvGetSize(pImage),IPL_DEPTH_8U,1);IplImage *pB = cvCreateImage(cvGetSize(pImage),IPL_DEPTH_8U,1);IplImage *temp = cvCreateImage(cvGetSize(pImage),IPL_DEPTH_8U,1);IplImage *binary = cvCreateImage(cvGetSize(pImage),IPL_DEPTH_8U,1);//trackbar的变量值 //对应各个通道int b_low =20;int b_high = 100;int g_low = 20;int g_high = 100;int r_low = 0;int r_high = 100;//轮廓相关CvMemStorage *storage = cvCreateMemStorage(0);CvSeq * seq = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint), storage);//窗⼝cvNamedWindow(winname);cvShowImage(winname, pImage); //显⽰原图cvNamedWindow("r",2);cvNamedWindow("g",2);cvNamedWindow("b",2); //各个通道cvNamedWindow("binary",2);//⼆值化图//在相应的窗⼝建⽴滑动条cvCreateTrackbar( "b1","b", &b_low, 254, NULL); //H通道分量范围0-180cvSetTrackbarPos("b1","b",0 ); //设置默认位置cvCreateTrackbar( "b2","b", &b_high, 254, NULL);//H通道分量范围0-180cvSetTrackbarPos("b2","b",110 );cvCreateTrackbar( "g1","g", &g_low, 254, NULL);cvSetTrackbarPos("g1","g",0 );cvCreateTrackbar( "g2","g", &g_high, 254, NULL);cvSetTrackbarPos("g2","g",158 );cvCreateTrackbar( "r1","r", &r_low, 254, NULL);cvSetTrackbarPos("r1","r",68 );cvCreateTrackbar( "r2","r", &r_high, 254, NULL);cvSetTrackbarPos("r2","r",137);while(1){//各个通道分离cvSplit(pImage,pB,pG,pR,NULL);//阈值化cvThreshold(pB, temp,b_low , 255, CV_THRESH_BINARY);cvThreshold(pB, pB,b_high , 255, CV_THRESH_BINARY_INV);cvAnd(temp,pB,pB,NULL);//与操作,合成⼀张图cvThreshold(pG, temp,g_low , 255, CV_THRESH_BINARY);cvThreshold(pG, pG,g_high , 255, CV_THRESH_BINARY_INV);cvAnd(temp,pG,pG,NULL);//与操作,合成⼀张图cvThreshold(pR, temp,r_low , 255, CV_THRESH_BINARY);cvThreshold(pR, pR,r_high , 255, CV_THRESH_BINARY_INV);cvAnd(temp,pR,pR,NULL);//与操作,合成⼀张图//显⽰各个通道的图像cvShowImage("b",pB);cvShowImage("g",pG);cvShowImage("r",pR);//合成到⼀张图⾥cvAnd(pB, pG, binary, NULL);cvAnd(pR, binary, binary, NULL);//膨胀腐蚀操作去除⿊点//cvDilate(binary,binary);//cvErode(binary,binary);//显⽰合成的⼆值化图cvShowImage("binary",binary);//cvSaveImage("erzhitu.jpg",binary);// 处理轮廓int cnt = cvFindContours(binary,storage,&seq,sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);//返回轮廓的数⽬ CvSeq* _contour =seq;cout<<"number of contours "<<cnt<<endl;////////////////////_//找到长度最⼤轮廓;double maxarea=0;int ind_max = -1;int m=0;for( ; seq != 0; seq = seq->h_next ){m++;double tmparea = abs(cvArcLength(seq,CV_WHOLE_SEQ,-1));//double contArea = fabs(cvContourArea(pcontour,CV_WHOLE_SEQ));if(tmparea > maxarea){maxarea = tmparea;ind_max=m;}// cout<<"seqfor: "<<seq->total<<endl;}m=0;seq = _contour;for( ; seq != 0; seq = seq->h_next ){m++;if(m == ind_max){break;}}CvSeq* cur_cont = seq;cout<<"seq: "<<seq->total<<endl;cout<<"cur_cont: "<<cur_cont->total<<endl;//for (int i=0;i<cur_cont->total;++i)//{// CvPoint* p = CV_GET_SEQ_ELEM(CvPoint,cur_cont,i);//输出轮廓上点的坐标// printf("(%d,%d)\n",p->x,p->y);//}//cvWaitKey(0);//建⽴彩⾊输出图像IplImage *pOutlineImage = cvCreateImage(cvGetSize(pImage), IPL_DEPTH_8U, 3);cvCopy(pImage,pOutlineImage);//int nLevels = 5;//获取最⼤轮廓的凸包点集CvSeq* hull=NULL;hull = cvConvexHull2(cur_cont,0,CV_CLOCKWISE,0);cout<<"hull total points number:"<<hull->total<<endl;CvPoint pt0 = **(CvPoint**)cvGetSeqElem(hull,hull->total - 1);for(int i = 0;i<hull->total;++i){CvPoint pt1 = **(CvPoint**)cvGetSeqElem(hull,i);cvLine(pOutlineImage,pt0,pt1,CV_RGB(0,0,255));pt0 = pt1;}//最⼩⼆乘法拟合圆double center_x=0;double center_y=0;double radius=0;cout<<"nihe :"<<circleLeastFit(hull, center_x, center_y, radius);cout<<"canshu: "<<center_x<<endl<<center_y<<endl<<radius<<endl;//绘制圆cvCircle(pOutlineImage,Point2f(center_x,center_y),radius,CV_RGB(0,100,100));////////////////////////////////////////////////////////////////////////////绘制轮廓//cvDrawContours(pOutlineImage, cur_cont, CV_RGB(255,0,0), CV_RGB(0,255,0),0);//cvDrawContours(dst,contour,CV_RGB(255,0,0),CV_RGB(0,255,0),0);cvShowImage(winname, pOutlineImage); //显⽰原图jiangshang luokuoif (cvWaitKey(1000) == 27){cvSaveImage("tutu.jpg",pOutlineImage);break;}cvClearMemStorage( storage ); //清除轮廓所占⽤的内存cvReleaseImage(&pOutlineImage);//清除彩⾊输出图像}cvDestroyAllWindows();cvReleaseImage(&pImage);cvReleaseImage(&pR);cvReleaseImage(&pG);cvReleaseImage(&pB);cvReleaseImage(&temp);cvReleaseImage(&binary);return0;}//最⼩⼆乘法拟合,输出圆⼼的xy坐标值和半径⼤⼩;bool circleLeastFit(CvSeq* points, double ¢er_x, double ¢er_y, double &radius) {center_x = 0.0f;center_y = 0.0f;radius = 0.0f;if (points->total < 3){return false;}double sum_x = 0.0f, sum_y = 0.0f;double sum_x2 = 0.0f, sum_y2 = 0.0f;double sum_x3 = 0.0f, sum_y3 = 0.0f;double sum_xy = 0.0f, sum_x1y2 = 0.0f, sum_x2y1 = 0.0f;int N = points->total ;for (int i = 0; i < N; i++){CvPoint pt1 = **(CvPoint**)cvGetSeqElem(points,i);double x =pt1.x;double y = pt1.y ;double x2 = x * x;double y2 = y * y;sum_x += x;sum_y += y;sum_x2 += x2;sum_y2 += y2;sum_x3 += x2 * x;sum_y3 += y2 * y;sum_xy += x * y;sum_x1y2 += x * y2;sum_x2y1 += x2 * y;}double C, D, E, G, H;double a, b, c;C = N * sum_x2 - sum_x * sum_x;D = N * sum_xy - sum_x * sum_y;E = N * sum_x3 + N * sum_x1y2 - (sum_x2 + sum_y2) * sum_x;G = N * sum_y2 - sum_y * sum_y;H = N * sum_x2y1 + N * sum_y3 - (sum_x2 + sum_y2) * sum_y;a = (H * D - E * G) / (C * G - D * D);b = (H * C - E * D) / (D * D - G * C);c = -(a * sum_x + b * sum_y + sum_x2 + sum_y2) / N;center_x = a / (-2);center_y = b / (-2);radius = sqrt(a * a + b * b - 4 * c) / 2;return true;}标定相关代码#include "opencv2/core/core.hpp"#include "opencv2/imgproc/imgproc.hpp"#include "opencv2/calib3d/calib3d.hpp"#include "opencv2/highgui/highgui.hpp"#include <iostream>#include <fstream>using namespace cv;using namespace std;#define MAX_GRAY_VALUE 255#define MIN_GRAY_VALUE 0using namespace cv;using namespace std;#include <opencv2/imgproc/imgproc.hpp>#include <iostream>#include <stdio.h>using namespace std;using namespace cv;bool check_line_state=false;IplImage* workImg;IplImage* imgshow;CvRect ROI_rect;IplImage* src=0;void on_mouse( int event, int x, int y, int flags, void* ustc){CvFont font;cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA);if( event == CV_EVENT_LBUTTONDOWN ){CvPoint pt = cvPoint(x,y);char temp[16];sprintf(temp,"(%d,%d)",pt.x,pt.y);cout<<"("<<pt.x<<","<<pt.y<<")"<<endl;x1=pt.x;y1=pt.y;cvPutText(src,temp, pt, &font, cvScalar(255, 255, 255, 0));cvCircle( src, pt, 2,cvScalar(255,0,0,0) ,CV_FILLED, CV_AA, 0 );cvShowImage( "src", src );}}int main(){//获取端点的坐标src=cvLoadImage("dst7.png",1);cvNamedWindow("src",1);cvSetMouseCallback( "src", on_mouse, 0 );cvShowImage("src",src);cvWaitKey(0);cvDestroyAllWindows();cvReleaseImage(&src);return0;}/*//寻找圆⼼坐标int main(int args,char** argv){ static double radius;static int i;Mat srcImage = imread("dst7.png");if (!srcImage.data)return -1;imshow("srcImage", srcImage);Mat srcGray;cvtColor(srcImage, srcGray, COLOR_BGR2GRAY);//⾼斯平滑滤波GaussianBlur(srcGray, srcGray, Size(9, 9), 2,2);static vector<Vec3f> circles;//Hough圆检测HoughCircles(srcGray, circles, CV_HOUGH_GRADIENT,1,srcGray.rows/8,200,16,0,0);//将得到的结果绘图for (size_t i = 0; i < circles.size(); i++){Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));cout<<center<<endl;radius = cvRound(circles[i][2]);cout<<radius<<endl;//检测圆中⼼circle(srcImage, center, 3, Scalar(0, 255, 0), -1, 8, 0);//检测圆轮廓circle(srcImage, center, radius, Scalar(120, 120, 120), 3, 8, 0);}imshow("HoughResult", srcImage);imwrite("HoughResult.jpg",srcImage);IplImage* image=cvLoadImage("dst5.png");int p=0;int q=0;for (int k=0;k<=360;k++){double m = 3.1415926535*2*k/360;CvScalar s;s=cvGet2D(image,cvRound(circles[i][0])+radius*cos(m),cvRound(circles[i][1])+radius*sin(m)); if(s.val[0]!=255){p++;q++;}elseq++;cout<<m<<p<<q<<endl;}waitKey(0);return 0;}//⼆值化部分//otsu函数计算最佳阈值int otsu(Mat dst){int i, j;int tmp;double u0, u1, w0, w1, u, uk;double cov;double maxcov = 0.0;int maxthread = 0;int hst[MAX_GRAY_VALUE] = { 0 };double pro_hst[MAX_GRAY_VALUE] = { 0.0 };int height = dst.cols;int width = dst.rows;//统计每个灰度的数量for (i = 0; i<width; i++){for (j = 0; j<height; j++){tmp = dst.at<uchar>(i, j);hst[tmp]++;}}//计算每个灰度级占图像中的概率for (i = MIN_GRAY_VALUE; i<MAX_GRAY_VALUE; i++) pro_hst[i] = (double)hst[i] / (double)(width*height);//计算全局平均灰度值u = 0.0;for (i = MIN_GRAY_VALUE; i<MAX_GRAY_VALUE; i++) u += i*pro_hst[i];//统计前景和背景的平均灰度值,并计算类间⽅差for (i = MIN_GRAY_VALUE; i<MAX_GRAY_VALUE; i++){ w0 = 0.0; w1 = 0.0; u0 = 0.0; u1 = 0.0; uk = 0.0;for (j = MIN_GRAY_VALUE; j < i; j++){uk += j*pro_hst[j];w0 += pro_hst[j];//前景占图像画幅⽐例}u0 = uk / w0;//前景平均灰度w1 = 1 - w0;//背景占图像画幅⽐例u1 = (u - uk) / (1 - w0);//背景平均灰度//计算类间⽅差cov = w0*w1*(u1 - u0)*(u1 - u0);if (cov > maxcov){maxcov = cov;maxthread = i;}}cout << maxthread << endl;return maxthread;}int main(){int width, height;int i, j;Mat obj = imread("22.jpg");Mat dst1;cvtColor(obj, dst1, CV_RGB2GRAY);//灰度化height = dst1.cols;//计算图像⾼度width = dst1.rows;//计算图像宽度int thd = otsu(dst1);imshow("原图", dst1);for (i = 0; i < width; i++)for (j = 0; j< height; j++)if (dst1.at<uchar>(i, j) > thd)dst1.at<uchar>(i, j) = MAX_GRAY_VALUE-1;elsedst1.at<uchar>(i, j) = MIN_GRAY_VALUE;imwrite("dst1.png",dst1);imshow("⼆值化", dst1);//膨胀(闭运算消除内部⽶粒)Mat dst2=imread("dst1.png");Mat dst3;Mat element = getStructuringElement(MORPH_RECT,Size(3,3));//imshow("闭运算消除内部空隙原图", dst2);dilate( dst2,dst3,element); //膨胀imshow("闭运算消除内部空隙效果图", dst3);imwrite("dst3.png",dst3);//腐蚀(开运算去除⽑刺)Mat dst4=imread("dst3.png");Mat dst5;//imshow("开运算去除⽑刺原图",dst4);erode(dst4,dst5,element);imshow("开运算去除⽑刺效果图",dst5);imwrite("dst5.png",dst5);//边缘检测Mat dst6=imread("dst5.png");Mat dst7;//imshow("边缘检测原图",dst6);Canny(dst6,dst7,150.100,3);imshow("边缘检测效果图",dst7);imwrite("dst7.png",dst7);waitKey(0);return 0;}int main(){cv::Mat image, Extractcorner;cv::vector<cv::Point2f> corners; //⽤来储存所有⾓点坐标cv::Size board_size = cv::Size(7, 7); //标定板每⾏,每列⾓点数image = cv::imread("2.jpg");Extractcorner = image.clone();cv::Mat imageGray;cv::cvtColor(image, imageGray, CV_RGB2GRAY);bool patternfound = cv::findChessboardCorners(image, board_size, corners, cv::CALIB_CB_FAST_CHECK + cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE);if (!patternfound){std::cout << "can not find chessboard corners!" << std::endl;exit(1);}else{//亚像素精确化cv::cornerSubPix(imageGray, corners, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));}//⾓点检测图像显⽰for (int i = 0; i < corners.size(); i++){cv::circle(Extractcorner, corners[i], 5, cv::Scalar(255, 0, 255), 2);}cv::imshow("Extractcorner", Extractcorner);cv::imwrite("Extractcorner.jpg", Extractcorner);//输出⾓点坐标cout<<corners<<endl;//参考图像cv::Mat image2, Extractcorner2;cv::vector<cv::Point2f> corners2; //⽤来储存所有⾓点坐标cv::Size board_size2 = cv::Size(7, 7); //标定板每⾏,每列⾓点数image2 = cv::imread("1.jpg");Extractcorner2 = image2.clone();cv::Mat imageGray2;cv::cvtColor(image2, imageGray2, CV_RGB2GRAY);bool patternfound2 = cv::findChessboardCorners(image2, board_size, corners2, cv::CALIB_CB_FAST_CHECK + cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE); if (!patternfound2){std::cout << "can not find chessboard corners!" << std::endl;exit(1);}else{//亚像素精确化cv::cornerSubPix(imageGray2, corners2, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));}//⾓点检测图像显⽰for (int i = 0; i < corners2.size(); i++){cv::circle(Extractcorner2, corners2[i], 5, cv::Scalar(255, 0, 255), 2);}cv::imshow("Extractcorner2", Extractcorner2);cv::imwrite("Extractcorner2.jpg", Extractcorner2);//输出⾓点坐标cout<<corners2<<endl;//仿射变换1Mat src = imread("2.jpg");Mat dst_warp;Point2f srcPoints[3];//原图中的三点Point2f dstPoints[3];//⽬标图中的三点//三个点对的值srcPoints[0] = Point2f(142.52786,115.98566);srcPoints[1] = Point2f(110.28358,409.29211);srcPoints[2] = Point2f(438.46851,126.58415);dstPoints[0] = Point2f(44.506947, 46.233685);dstPoints[1] = Point2f(44.496399, 325.76706);dstPoints[2] = Point2f(314.50659, 46.230354);Mat M1 = getAffineTransform(srcPoints,dstPoints);//由三个点对计算变换矩阵warpAffine(src,dst_warp,M1,src.size());//仿射变换imshow("src",src);imshow("dst_warp",dst_warp);imwrite("dst_warp.jpg",dst_warp);//⼀次变换后图像cv::Mat image3, Extractcorner3;cv::vector<cv::Point2f> corners3; //⽤来储存所有⾓点坐标cv::Size board_size3 = cv::Size(7, 7); //标定板每⾏,每列⾓点数image3 = cv::imread("dst_warp.jpg");Extractcorner3 = image3.clone();cv::Mat imageGray3;cv::cvtColor(image3, imageGray3, CV_RGB2GRAY);bool patternfound3 = cv::findChessboardCorners(image3, board_size, corners3, cv::CALIB_CB_FAST_CHECK + cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE); if (!patternfound3){std::cout << "can not find chessboard corners!" << std::endl;exit(1);}else{//亚像素精确化cv::cornerSubPix(imageGray3, corners3, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));}//⾓点检测图像显⽰for (int i = 0; i < corners3.size(); i++){cv::circle(Extractcorner3, corners3[i], 5, cv::Scalar(255, 0, 255), 2);}cv::imshow("Extractcorner3", Extractcorner3);cv::imwrite("Extractcorner3.jpg", Extractcorner3);//输出⾓点坐标cout<<corners3<<endl;ofstream outfile;outfile.open("date.txt");outfile<<corners<<endl<<endl<<endl<<corners2<<corners3<<endl;outfile.close();//仿射变换2Mat src2 = imread("dst_warp.jpg");Mat dst_warp2;Point2f src2Points[3];//原图中的三点Point2f dst2Points[3];//⽬标图中的三点//三个点对的值src2Points[0] = Point2f(395.12207, 306.01523);src2Points[1] = Point2f(44.515686, 325.73227);src2Points[2] = Point2f(314.53482, 46.279831);dst2Points[0] = Point2f(314.49469, 325.76535);dst2Points[1] = Point2f(44.496399, 325.76706);dst2Points[2] = Point2f(314.50659, 46.230354);Mat M2 = getAffineTransform(src2Points,dst2Points);//由三个点对计算变换矩阵warpAffine(src2,dst_warp2,M2,src2.size());//仿射变换imshow("src2",src);imshow("dst_warp2",dst_warp2);imwrite("dst_warp2.jpg",dst_warp2);cv::waitKey(0);return 0;}*/。
opencv中的Hough变换是一种常用的图像处理算法,它可以用来检测图像中的圆形。
在本文中,将介绍如何使用opencv的Hough变换算法来找到图像中的圆。
1. 算法原理Hough变换是一种常用的图像处理算法,它可以用来检测图像中的直线、圆形等几何形状。
Hough变换的原理是将图像空间中的像素点映射到参数空间中,从而能够在参数空间中找到拟合图像中特定几何形状的参数。
对于找圆算法来说,Hough变换的参数空间通常是圆心坐标和半径。
具体而言,对于一幅图像,我们需要在参数空间中建立一个累加器数组,数组的每一个元素表示一个可能的圆心坐标和半径。
然后对图像中的每一个像素点,我们计算它到每一个可能的圆心的距离,如果距离小于某个阈值,则在累加器数组中相应的位置加一。
我们就可以在累加器数组中找到累加值最大的位置,从而得到图像中的圆。
2. opencv中的实现在opencv中,我们可以使用HoughCircles函数来实现找圆算法。
该函数原型如下:void HoughCircles(InputArray image, OutputArray circles, int method, double dp, double minDist, double param1=100, double param2=100, int minRadius=0, int maxRadius=0 )其中,InputArray表示输入图像,OutputArray表示输出的圆的参数,method表示检测方法,dp表示累加器分辨率和图像分辨率的比值,minDist表示检测到的圆之间的最小距离,param1和param2分别表示Canny边缘检测的两个阈值,minRadius和maxRadius表示圆的最小半径和最大半径。
使用HoughCircles函数,我们可以简单地找到图像中的圆。
下面是一个示例代码:Mat src = imread("circle.jpg");Mat gray;cvtColor(src, gray, COLOR_BGR2GRAY);GaussianBlur(gray, gray, Size(9, 9), 2, 2);vector<Vec3f> circles;HoughCircles(gray, circles, HOUGH_GRADIENT, 1, gray.rows / 8, 200, 100, 0, 0);在这段示例代码中,我们首先读入一张图像,并将其转换为灰度图像。
opencv直径的识别方法在OpenCV中,识别图像中的圆并测量其直径通常涉及以下几个步骤:1. 加载图像并转换为灰度图像:首先,需要将图像加载到OpenCV中,并将其转换为灰度图像。
这样可以简化后续的处理步骤并减少计算量。
2. 高斯模糊减少噪声:为了减少图像中的噪声,可以使用高斯模糊。
这有助于提高后续圆检测的准确性。
3. 霍夫圆变换:使用霍夫圆变换来检测图像中的圆。
OpenCV提供了`HoughCircles`函数,该函数可以检测图像中的圆,并返回其中心点和半径。
4. 计算直径:一旦获得了圆的中心点和半径,就可以计算其直径。
在OpenCV中,`HoughCircles`函数返回的半径值就是圆的直径。
以下是一个简单的Python代码示例,展示了如何使用OpenCV识别图像中的圆并测量其直径:```pythonimport cv2import numpy as np1. 加载图像并转换为灰度图像img = ('')gray = (img, _BGR2GRAY)2. 高斯模糊减少噪声gray = (gray, (5, 5), 0)3. 霍夫圆变换circles = (gray, _GRADIENT, 1, / 8, 200, 100, 0, 0)4. 计算直径并绘制圆if circles is not None:circles = (circles[0, :]).astype('int')for i in circles:绘制外圆(img, (i[0], i[1]), i[2], (0, 255, 0), 2)绘制圆心(img, (i[0], i[1]), 2, (0, 0, 255), 3)计算并打印直径diameter = 2 i[2]print(f"Diameter of circle {i[0]} is {diameter}")('Detected circles', img)(0)()```请注意,这只是一个基本的示例,实际应用中可能需要根据具体情况进行调整和优化。
如何基于OpenCVPython实现霍夫变换圆形检测简述基于python使⽤opencv实现在⼀张图⽚中检测出圆形,并且根据坐标和半径标记出圆。
不涉及理论,只讲应⽤。
霍夫变换检测圆形的原理其实检测圆形和检测直线的原理差别不⼤,只不过直线是在⼆维空间,因为y=kx+b,只有k和b两个⾃由度。
⽽圆形的⼀般性⽅程表⽰为(x-a)²+(y-b)²=r²。
那么就有三个⾃由度圆⼼坐标a,b,和半径r。
这就意味着需要更多的计算量,⽽OpenCV中提供的cvHoughCircle()函数⾥⾯可以设定半径r的取值范围,相当于有⼀个先验设定,在每⼀个r来说,在⼆维空间内寻找a和b就可以了,能够减少计算量。
相关函数函数说明:Python: cv2.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) →circles参数说明:image- 8位,单通道,灰度输⼊图像。
circles- 找到的圆的输出向量。
每个向量被编码为3元素的浮点向量(x,y,半径)。
circle_storage - 在C函数中,这是⼀个将包含找到的圆的输出序列的内存存储。
method- 使⽤检测⽅法。
⽬前,唯⼀实现的⽅法是 CV_HOUGH_GRADIENT,基本上是 21HT,在[Yuen90]中有描述。
dp - 累加器分辨率与图像分辨率的反⽐。
例如,如果 dp = 1,则累加器具有与输⼊图像相同的分辨率。
如果 dp = 2,则累加器的宽度和⾼度都是⼀半。
minDist -检测到的圆的中⼼之间的最⼩距离。
如果参数太⼩,除了真正的参数外,可能会错误地检测到多个邻居圈。
如果太⼤,可能会错过⼀些圈⼦。
param1 - 第⼀个⽅法特定的参数。
在CV_HOUGH_GRADIENT的情况下,两个传递给Canny()边缘检测器的阈值较⾼(较⼩的两个⼩于两倍)。
opencv生成圆原理(原创实用版)目录一、OpenCV 生成圆的原理概述二、霍夫圆检测原理三、霍夫圆检测在 OpenCV 中的应用四、总结正文一、OpenCV 生成圆的原理概述OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它包含了大量的图像处理和计算机视觉方面的算法。
在OpenCV 中,生成圆的方法主要是通过霍夫圆变换来实现的。
霍夫圆变换是一种基于极坐标的图像变换方法,它可以将图像中的圆转换为霍夫空间中的点,从而实现对圆的检测和分析。
二、霍夫圆检测原理霍夫圆检测的原理基于极坐标系下的圆的数学表达式。
在极坐标系中,一个圆可以表示为:x = a * cos(theta)y = b * sin(theta)其中,a 和 b 分别是圆心的横纵坐标,r 是圆的半径。
通过将极坐标转换为直角坐标,我们可以得到圆的一般方程:(x - a) + (y - b) = r在霍夫空间中,一个点可以唯一确定一个圆。
因此,通过将图像中的所有点映射到霍夫空间,我们可以检测出所有可能的圆。
三、霍夫圆检测在 OpenCV 中的应用在 OpenCV 中,霍夫圆检测是通过调用 cv::HoughCircles 函数来实现的。
这个函数接受两个参数,一个是输入图像,另一个是霍夫圆参数。
霍夫圆参数包括圆的阈值、圆心距阈值、半径比阈值等。
通过调整这些参数,我们可以控制圆检测的灵敏度和准确性。
以下是一个使用 OpenCV 进行霍夫圆检测的示例代码:```cpp#include <iostream>#include <opencv2/opencv.hpp>using namespace std;using namespace cv;int main(){// 读取输入图像Mat img = imread("input_image.jpg", IMREAD_GRAYSCALE);// 将图像转换为霍夫空间Mat hough_img;cv::HoughTransform(img, hough_img, CV_HOUGH_GRADIENT, 1, 60, 100, 20, 10, 60);// 检测圆vector<Vec4i> circles;cv::HoughCircles(hough_img, circles, CV_HOUGH_CIRCLE, 0, 0, 0, 0, 0, 0);// 绘制检测到的圆Mat result;drawCircles(img, circles, result, Scalar(0, 255, 0), 2);// 显示结果imshow("Result", result);waitKey(0);return 0;}```四、总结通过使用 OpenCV 库中的霍夫圆检测方法,我们可以在图像中检测出所有的圆。
opencv--检测图⽚中的圆形说明完整代码import cv2.cv2 as cv2import numpy as nppath='a.jpg'img = cv2.imread(path,0)gaussimg=cv2.GaussianBlur(img,(3,3),0) #⾼斯滤波,(3,3)为⾼斯半径medianimg = cv2.medianBlur(gaussimg, 7) #中值滤波cannyimg=cv2.Canny(medianimg,0,148) #canny边缘检测temp = np.ones(cannyimg.shape,np.uint8)*255 #创建⼀个空的画布contours= cv2.findContours(cannyimg,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)contour = contours[0] #提取轮廓cv2.drawContours(temp,contour,-1,(0,0,0),3) #把轮廓画到画布上cv2.imshow('image',temp)cv2.waitKey(1000)circle = cv2.HoughCircles(temp,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=10,minRadius=0,maxRadius=800) #按照画布上的轮廓⽣成霍夫圆circle = np.uint16(np.around(circle))img2bgr=cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)count=1 #终⽌信号,只取第⼀个霍夫圆,试着⽤数组取了但是没成功for i in circle[0]:#得到的霍夫圆是默认按照投票结果的累加值排序,⼀般取第⼀个就是与轮廓最拟合的那个#如果有多个圆识别,可以试试⽤多次霍夫圆,试着⽤半径过滤到同⼀块的圆,再取最为拟合的第⼀个圆,不过这样不稳定cv2.circle(img2bgr,(i[0],i[1]),i[2],(0,0,255),5) #在图像上画出这个霍夫圆count+=1if count==2:breakcv2.imshow('image',img2bgr)cv2.waitKey(1000)。
opencv提取圆形findcontours摘要:一、OpenCV 简介1.OpenCV 的背景与作用2.OpenCV 在计算机视觉领域的应用二、圆形检测的重要性1.圆形在图像处理中的常见场景2.检测圆形对于图像识别与分析的意义三、使用OpenCV 提取圆形1.findContours 函数的作用2.使用findContours 检测圆形的方法四、实例演示1.安装与配置OpenCV2.圆形检测代码演示五、总结1.OpenCV 在圆形检测中的应用优势2.圆形检测在实际项目中的应用前景正文:一、OpenCV 简介OpenCV,全称Open Source Computer Vision Library,是一款开源的计算机视觉和机器学习软件库。
它包含了大量的图像处理、视频分析和计算机视觉方面的功能。
OpenCV 具有强大的性能和灵活性,被广泛应用于计算机视觉领域,如人脸识别、目标追踪、图像分割、形状识别等。
二、圆形检测的重要性在图像处理和计算机视觉领域,圆形常常作为基本的几何形状出现。
例如,在目标检测和识别任务中,圆形通常表示物体的轮廓。
此外,圆形也是许多图像特征的重要表现形式,如角点、中心点等。
因此,提取圆形对于图像分析和理解具有重要意义。
三、使用OpenCV 提取圆形在OpenCV 中,我们可以通过findContours 函数来检测图像中的圆形。
该函数可以找到图像中所有轮廓,并将其存储在轮廓数组中。
我们可以通过以下方法使用findContours 检测圆形:1.转换图像颜色空间:将图像从BGR 转换为灰度图像,以便更好地检测边缘。
2.应用阈值处理:通过设置阈值,将图像中的像素值转换为二进制数,从而简化图像并突显圆形轮廓。
3.查找轮廓:调用findContours 函数,检测图像中的轮廓。
4.筛选圆形:根据轮廓的属性(如面积、长宽比等),筛选出圆形轮廓。
四、实例演示以下是一个使用Python 和OpenCV 检测圆形的简单示例:```pythonimport cv2# 读取图像image = cv2.imread("example.jpg")# 转换为灰度图像gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 应用阈值处理_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)# 查找轮廓contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)# 筛选圆形circles = []for contour in contours:area = cv2.contourArea(contour)if area > 100: # 筛选面积大于100 的轮廓perimeter = cv2.arcLength(contour, True)if area / (perimeter * perimeter) <= 0.5: # 筛选长宽比小于0.5 的轮廓circles.append(contour)# 在原始图像上绘制圆形for circle in circles:cv2.circle(image, cv2.centerOfMass(circle), 2, (0, 255, 0), -1) # 显示结果cv2.imshow("Detected Circles", image)cv2.waitKey(0)cv2.destroyAllWindows()```五、总结OpenCV 作为一个功能强大的计算机视觉库,为圆形检测提供了便捷的方法。