一种基于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 作为一个功能强大的计算机视觉库,为圆形检测提供了便捷的方法。
基于数字图像处理的圆形检测的开题报告一、选题背景随着现代技术的不断发展,数字图像处理已成为一项广泛应用的技术。
在众多的应用中,圆形检测一直是一个十分重要的问题。
圆形检测在计算机视觉、机器人技术、医学成像等众多领域都得到了广泛的应用。
圆形检测的目的是在给定的图像中寻找其中的圆形,并找出其圆心和半径等信息。
然而,由于图像噪声和复杂度等因素的干扰,圆形检测一直是一个十分具有挑战性的问题。
二、研究内容本项目旨在基于数字图像处理技术进行圆形检测,主要包括以下研究内容:1.图像预处理对于输入的图像,需要先进行必要的预处理,包括去噪、图像增强等,以提高圆形检测的准确性。
2.圆形检测算法设计本项目将设计一种基于边缘检测和霍夫变换的圆形检测算法。
首先利用边缘检测算法检测出所有可能的圆形边缘,并采用霍夫变换对圆心和半径进行估计,从而得到最终的圆形检测结果。
3.算法实现和优化在圆形检测算法的实现过程中,需要考虑到算法复杂度和精度之间的平衡,以保证算法能够在实际应用中得到有效的使用。
为了优化算法效率,将采用多线程并行计算等方法进行优化。
三、研究意义圆形检测是数字图像处理领域中的一个重要问题,其应用广泛,并且涉及的技术难点很多。
针对该问题的研究旨在提高圆形检测的精度和效率,从而为实际应用提供帮助。
本项目的研究结果可以应用于计算机视觉、机器人技术、医学成像等领域,具有广泛的应用价值。
四、研究方法本项目采用文献调研、理论分析和实验研究相结合的方法,对圆形检测算法进行研究。
首先通过文献调研了解各种现有的圆形检测算法的优缺点,对其中的一些经典算法进行理论分析,并进一步设计和优化自己的圆形检测算法。
最后,通过实验验证本项目的算法性能和效果。
五、预期结果本项目将提出一种基于数字图像处理的高效准确的圆形检测算法,并在大量实验数据验证下,得出其性能和效果的具体指标,包括检测精度、处理速度等。
同时,本项目将实现该算法,并将开发出一个基于该算法的圆形检测软件,以验证算法的实际应用效果。
opencv圆半径-回复Opencv(Open Source Computer Vision Library)是一个开源的计算机视觉库,广泛应用于图像处理、计算机视觉和机器学习等领域。
本文将着重讨论Opencv中关于圆半径的操作和应用。
一、介绍圆半径的基本概念和意义圆半径是指从圆心到圆上任意一点的距离,也是决定圆的大小的重要参数。
在图像处理和计算机视觉中,圆半径常常用于检测和描述图像中的圆形物体,如目标检测、目标跟踪和图像分析等应用。
Opencv提供了一系列函数和方法,可以方便地对图像中的圆进行检测、拟合和描述。
二、Opencv中的圆半径检测方法1. 霍夫圆变换(Hough Circle Transform)霍夫圆变换是一种经典的圆检测方法,可以在图像中检测出各种大小和位置的圆。
Opencv中的函数`HoughCircles()`可以实现霍夫圆变换,并返回检测到的圆的位置和半径等信息。
通过调整函数参数可以控制圆检测的灵敏度和准确性。
2. 阈值分割和形态学操作另一种常用的方法是使用图像的阈值分割和形态学操作来检测圆。
例如,可以通过对图像进行二值化处理,然后应用形态学操作(如腐蚀和膨胀)来消除噪声和连接成圆形的边缘。
最后,通过计算图像中连通区域的面积和周长等特征,可以估计出圆的半径。
三、Opencv中的圆半径测量和描述方法1. 最小外接圆(Minimum Enclosing Circle)最小外接圆是指在给定点集中,能够包含所有点,并且半径最小的圆。
在Opencv中,可以使用函数`minEnclosingCircle()`来计算点集的最小外接圆的圆心和半径,从而实现对圆的测量和描述。
2. 拟合圆形曲线除了最小外接圆外,还可以通过拟合圆形曲线来测量和描述圆。
Opencv中的函数`fitEllipse()`可以用于拟合点集到椭圆曲线,进而可以估计出椭圆的参数,包括圆心位置、长轴和短轴的长度等。
通过合适的参数选择和模型拟合,可以将椭圆曲线近似为圆形,从而得到圆的半径。
基于O p e n C V的圆点b l o b识别函数圆个数检测周萌,王军民,刘威,周蕾(长江大学地球物理与石油资源学院,武汉430100)摘要:目前,最热门的技术无非是机器学习和人工智能,O p e n C V是开源的计算机视觉和机器学习库,是计算机视觉领域学者和开发人员的首选工具,本文设计了一种检测圆形的嵌入式综合方案,即结合拥有完善操作系统的树莓派2代㊁带U S B接口的高速摄像头实时捕获图像并得出结果㊂实验结果表明,此方法效果良好㊁准确便捷㊁操作简单,是一种可行的方案㊂关键词:计算机视觉;树莓派;O p e n C V;圆形检测中图分类号:T N919.8文献标识码:AC i r c l e s N u m b e r o fD e t e c t i o n B a s e d o n C i r c l e b l o b R e c o g n i t i o n F u n c t i o n o f O p e n C VZ h o u M e n g,W a n g J u n m i n,L i u W e i,Z h o u L e i(C o l l e g e o f G e o p h y s i c s a n d P e t r o l e u m R e s o u r c e s,Y a n g t z e U n i v e r s i t y,W u h a n430100,C h i n a)A b s t r a c t:N o w,t h e m o s t p o p u l a r t e c h n o l o g i e s a r e m a c h i n e l e a r n i n g a n d a r t i f i c i a l i n t e l l i g e n c e,O p e n C V i s a n o p e n s o u r c e l i b r a r y o f c o m-p u t e r v i s i o n a n d m a c h i n e l e a r n i n g.I t i s t h e p r e f e r r e d t o o l f o r s c h o l a r s a n d d e v e l o p e r s i n t h e f i e l d o f c o m p u t e r v i s i o n.I n t h e p a p e r,a n e m-b e d d e d i n t e g r a t e d s c h e m e f o r d e t e c t i n g c i r c l e s i s d e s i g n e d,w h i c h c o m b i n e s t h e r a s p b e r r y p i2w i t h a p e r f e c t o p e r a t i n g s y s t e m a n d t h e h i g h-s p e e d c a m e r a w i t h U SB t o c a p t u r e i m a g e s i n r e a l t i m e a n d g e t t h e r e s u l t s.T h e e x p e r i m e n t r e s u l t s s h o w t h a t t h e m e t h o d i s e f f e c-t i v e,a c c u r a t e,c o n v e n i e n t a n d s i m p l e t o o p e r a t e a n d i t i s a f e a s i b l e s c h e m e.K e y w o r d s:c o m p u t e r v i s i o n;R a s p b e r r y P i2;O p e n C V;c i r c u l a r d e t e c t i o n引言生活中随处都可以看到圆形的物体,圆有圆心㊁半径㊁周长及面积等㊂圆的这些特征很容易被检测出来,比较成熟的技术包含基于H o u g h变换的圆检测技术,参考文献[3]中已将其成功运用于工业控制,另外还有应用更特殊的,如参考文献[6]中介绍了体育比赛播报中跟踪球运动的一种更好的视觉体验方案㊂现在,跨界合作非常盛行,树莓派小巧㊁功能强大,运行O p e n C V库函数进行图像处理也比较流畅,并且可以随时按照客户需求增加后更改项目功能㊂本文基于此想法,设计了圆形检测小系统,主要实现的功能为:调取摄像头检测被测物体;选取本地图片识别计数;根据识别的圆自动得出结果并显示㊂1工作原理制作搭载在模型上的图传系统所需要的硬件主要有树莓派2代㊁普通U S B摄像头㊁上位机V S c o d e编辑器,使用O p e n C V的特征提取b l o b算法,将一张纸上的不同位置的圆检测出来,并且求得其数量㊁大小㊁形状及面积,最后利用P y Q t5编写显示界面得出圆的个数㊂2智能检测圆形系统的制作2.1树莓派树莓派是火热的创客硬件之一,用它搭建的图传系统不仅可以传输更清晰的图像,而且可以扩展出其他更有趣的功能㊂树莓派2代价格低廉,它的性价比非常高,以相同的价格买一台可以装进你口袋里的迷你计算机,它配备了一张T F卡,是树莓派的存储设备㊂树莓派是一款基于L i n u x设计而成的主机,所以它的操作系统自然也是基于L i n u x内核的㊂工程师可以烧写入不同的操作系统到T F 卡上,玩转更有趣的东西,因为本文在将树莓派作为图传系统的硬件时需要图形界面,所以本文烧录的是R a s p b i-a n,该系统附带着35000多个软件包,并集成了轻量级图形界面L X D E,为本系统摄像头驱动和界面设计P y Q t5提供了更加便捷的操作,易于上手㊂本文选取的树莓派如图1所示㊂2.2b l o b算法b l o b算法是对图像中相同像素的连通域进行分析,该图1 树莓派硬件连通域称为b l o b ㊂b l o b 分析可为机器视觉应用提供图像中斑点的数量㊁位置㊁形状和方向,还可以提供相关斑点间的拓扑结构㊂b l o b 算法执行步骤如下:①图像分割㊂目标像素被赋值为1,背景像素被赋值为0,多种技术可将图像分割为目标像素和背景像素㊂相关技术包括:二元阈值㊁空间量化误差㊁软件二元阈值和像素加权㊁相关阈值㊁阈值图像㊂②连通性分析㊂连通性分析的三种类型如下:全图像连通性分析,被分割图像的所有目标像素均被视为构成单一斑点的像素,即使斑点像素彼此并不相连,它们仍被视为单一的斑点,所有的b l o b 统计和测量均通过图像中的目标像素进行计算;连接b l o b 分析,通过连通性标准将图像中目标像素聚合为离散的斑点连接体,连接性分析通过连接所有邻近的目标像素构成斑点,不邻近的目标像素则不被视为是斑点的一部分;标注连通性分析,在机器视觉应用中,由于所进行的图像处理过程不同,可能需要对某些已被分割的图像进行b l o b 分析,而这些图像并未被分割为目标像素和背景像素,例如图像可能被分为4个不同像素集合,每一集合代表不同的像素值范围,这类分割称为标注连通性分析,当对标注分割的图像进行连通性分析时,将连接所有具有同一标注的图像,标注连通分析不再有目标和背景的概念㊂③b l o b 工具㊂此工具是用来从背景中分离出目标,并测量任意形状目标物的形态参数㊂b l o b 并不是分析单个的像素,而是对图形的行进行操作㊂图像的每一行都用游程长度编码来表示相邻的目标范围㊂④分类器设计㊂检测目标需要进行分类,这就涉及到分类器的使用㊂S VM 方法是把样本点升维 ,即映射到高维甚至无穷维空间,再在高维空间中采用处理线性问题的方法㊂本文使用O p e n C V 提供的S i m pl e b l o b d e t e c t o r 的A P I 接口㊂O pe n C V 实现的算法如下:对[m i n T h r e s h o l d ,m a x T h r e s h o l d )区间,以t h r e s h o l d S t e p 为间隔,做多次二值化;对每张二值图片,使用f i n d C o n t o u r s ()提取连通域并计算每一个连通域的中心;根据得到的中心,全部放在一起,一些很接近的点[由t h e m i n D i s t B e t w e e n B l o b s 控制多少才算接近]被归为一个g r o u p ,对应一个b l o b 特征;根据得到的点估计最后的b l o b 特征和相应半径,并以k e y-po i n t s 返回㊂2.3 P yQ t 5工具包P y Q t 5是一个用于创建G U I 应用程序的跨平台工具包,它将P y t h o n 编辑语言和Q t 库成功融合在一起㊂也就是说P y Q t 5是Q t 框架的P y t h o n 语言实现㊂由于P yt h o n 是一种面向对象的语言,语法简单㊁高效,相对于C ++而言,使用P y t h o n 编写程序可以提高开发效率,减少开发成本㊂P y Q t 5向P y t h o n 程序员提供了使用完整的Q t 应用程序接口函数,几乎可以用P y t h o n 做任何Q t 能做的工作㊂本文使用P yQ t 5搭建界面,所使用的语言开发环境是P y t h o n 3,在树莓派命令行中输入命令:s u d o a pt g e t i n s a t l l p y t h o n 3p y q t 5就可以使用P yQ t 5相关功能,命令行输入:s u d o a p t g e t i n s a t l l p y t h o n 3就可以使用P yt h o n 编程(命令行输入:p y t h o n m p i p i n s t a l l u s e r n u m p ys c i p y m a t p l o t l i b i p y t h o n j u p y t e r p a n d a s s y m p y no s e ),安装程序所需要的各种支持库(例如C V 2㊁n u m p y)打开树莓派操作系统自带的P y t h o n 编译器T h o n n y ,T h o n n y 是基于P yt h o n 内置图形库t k i n t e r 开发出来的支持多平台W i n -d o w s \M a c \L i n u x 的P yt h o n I D E ,支持语法着色㊁代码自动补全㊁d e b u g 等功能,本文T h o n n y ID E 主要用于编译调试P yQ t 5程序㊂2.4 V N C v i e w e r 无线连接投屏通过V N C 可以实现树莓派与计算机之间的双向投影,既可以将树莓派的界面投影到计算机屏幕,也可以将计算机界面投影到树莓派连接的显示器,省去了物理连线的困扰,只需给树莓派供电即可㊂进入树莓派的命令行界面,然后输入命令 s u d o a p t g e t i n s t a l l t i gh t v n c s e r v e r 来安装V N C 服务端应用㊂输入命令 v n c pa s s w d 设置登录密码和名称,输入命令 t i g h t v n c s e r v e r g e o m e t r y 800ˑ600:1 启动V N C 服务,完成服务端的配置后,需要在计算机上安装客户端来连接树莓派,在计算机上下载安装V N C v i e w e r 这个软件,此软件不到10M B ,安装完成后打开软件㊂在软件的f i l e 下创建新的连接,V N C s e r v e r 栏输入树莓派I P 地址,n a m e 一栏输入名称,完成后单击,就可以看到树莓派的图形界面已经成功投影到计算机屏幕,这样就可以远程操作树莓派了㊂结 语进行软件调试后,本文最终结果如图2所示,识别效果良好,满足了动态变化的要求㊂在设计整体方案时要注意,外部光线对图像62在整体性能上相比于D C F N e t 算法有一定的提升㊂改进的算法性能提升部分主要体现在改进的算法对于那些目标物有被遮挡的视频序列上㊂这也符合本文改进D C F -N e t 算法的初衷,同时可以得出局部跟踪与全局检测相结合是长时间跟踪的一个很好的研究方向㊂图12 O T B ㊁V O T数据集上的不同阈值的跟踪成功率图13 O T B ㊁V O T 数据集上的不同阈值的跟踪精确率结 语D C F N e t 建立在相关滤波类方法之上,相关滤波类方法每帧都是在局部区域内寻找目标㊂一方面这种思路为快速跟踪提供了保障,但另一方面也限制了跟踪的鲁棒性㊂在T L D 和E B T 等相关算法的启发下,本文为D C F -N e t 算法增添了跟踪置信度评价㊁模版更新策略和全局检测模块㊂其中跟踪置信度评测采用MO S S E 算法提出的峰值旁瓣比来评估,模版更新策路根据当前帧跟踪结果的峰值旁瓣比来制定,同时当峰值旁瓣比低于一定值后,就开启全局检测模块来弥补跟踪模块的不足㊂参考文献[1]W a n g N ,S h i J ,Y e u n g D Y ,e t a l .U n d e r s t a n d i n g a n d d i a gn o -s i n g v i s u a l t r a c k i n g s ys t e m s [C ]//I C C V ,2015.[2]H e n r i q u e s J F ,R u i C ,M a r t i n s P ,e t a l .H i g h -s p e e d T r a c k i n gw i t hK e r n e l i z e dC o r r e l a t i o nF i l t e r s[C ]//I E E ET P AM I ,2015.[3]W a n g Q ,G a o J ,X i n g J,e t a l .D C F N e t :D i s c r i m i n a n t C o r r e l a -t i o n F i l t e r s N e t w o r k f o r V i s u a l T r a c k i n g[C ]//I C I P ,2017.[4]Z h u G ,P o r i k l i F ,L i H.B e y o n d l o c a l s e a r c h :T r a c k i n g o b je c t s e v e r y w h e r e w i t h i n s t a n c e -s p e c if i c p r o po s a l s [C ]//C V P R ,2016.[5]K a l a l Z ,M i k o l a j c z y k K ,M a t a s J .T r a c k i n g -l e a r n i n g-d e t e c t i o n [C ]//I E E E T P AM I ,2012.熊纹洋(硕士研究生),主要研究方向为嵌入式与物体跟踪;杨斌(硕士生导师),主要研究方向为嵌入式系统应用㊂(责任编辑:薛士然收稿日期:2018-12-25)图2 识别效果的摄取影响非常大,后期需要经过更精细的算法进行改进,并且这次设计只是一个开端,可以在此基础上多加改进,给树莓派增加O L E D 屏并且配置蜂鸣器得到真实的图像效果并播报,会更加有实际意义㊂根据图片显示结果可知所得结果还是比较满意的㊂最后,开源O p e n C V 集成框架提供了更多详细的算法,可以进一步检测其他形状的物体并应用在实践中,期待下次有新的尝试㊂参考文献[1]任浩博.基于树莓派Z e r o W 的图传系统[J ].无线电,2017.[2]沈理强,周张涛,王泽南,等.基于树莓派的交通灯实时控制系统[J ].电子世界,2018(3):164166.[3]杨娜,陈后金,李志林,等.复杂背景图像中圆检测的新算法[J ].北京交通大学学报,2010,34(2):6.[4]朱桂英,张瑞林.基于H o u gh 变换的圆检测方法[J ].计算机工程与设计,2008,29(6):14621464.[5]高峰,陈雄,陈婉秋.基于树莓派B+微处理器的视频检测跟踪系统[J ].电视技术,2015,39(19):105108.[6]杨东桥,王万秋,鲁真妍,等.基于O pe n C V 的足球场上运动物体的识别[J ].信息与电脑:理论版,2018(14):128129.周萌(研究生),主要研究方向为物理仪器;王军民(副教授),主要研究方向为检测技术与自动化㊂(责任编辑:薛士然 收稿日期:2019-01-07)。
OpenCV学习笔记(⼋)边缘、线与圆的检测边缘检测对图像进⾏边缘检测之前,⼀般都需要先进⾏降噪(可调⽤GaussianBlur函数)。
Sobel算⼦与 Scharr算⼦都是⼀个离散微分算⼦ (discrete differentiation operator),⽤来计算图像灰度函数的近似梯度。
结合了⾼斯平滑和微分求导。
Sobel算⼦与Scharr算⼦的内核不同,Sobel内核产⽣误差⽐较明显,Scharr更为准确⼀些。
Sobel算⼦的计算步骤:1. 在两个⽅向求导:将原图分别与两个3x3的内核进⾏卷积计算,得到Gx与Gy2. 在图像的每⼀点,结合Gx与Gy求出近似梯度:或者 (简单公式)/// 求 X⽅向梯度//Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );convertScaleAbs( grad_x, abs_grad_x );/// 求Y⽅向梯度//Scharr( src_gray, grad_y, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );convertScaleAbs( grad_y, abs_grad_y );/// 合并梯度(近似)addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );src_gray: 在本例中为输⼊图像,元素类型CV_8Ugrad_x/grad_y: 输出图像.ddepth: 输出图像的深度,设定为CV_16S避免外溢。
openCV识别定位五个圆的标识物进行定位和位姿确定#include <iostream>// 载入OpenCV头文件#include 'opencv2/opencv.hpp'#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/objdetect/objdetect.hpp>#include <opencv2/features2d/features2d.hpp>#include <opencv2/calib3d/calib3d.hpp>#include <opencv2/nonfree/nonfree.hpp>#include <opencv2/legacy/legacy.hpp>#include <opencv2/legacy/compat.hpp>#include <vector>using namespace std;using namespace cv;//vector<pair<int,int> >centers;vector<Point2f> centers;vector<double> longAxisCVec;struct EllipsePara{CvPoint m_Pt;CvSize m_size;float m_angle;};vector<EllipsePara> Oval;//Some defines we left out of the book//void f(// IplImage* src,// IplImage* dst// )//{// CvMemStorage* storage = cvCreateMemStorage(0);// CvSeq* comp = NULL;//// cvPyrSegmentation( src, dst, storage, &comp, 4, 200, 50 );// int n_comp = comp->total;//// for( int i=0; i<n_comp; i++ ) {// CvConnectedComp* cc = (CvConnectedComp*) cvGetSeqElem( comp, i );// // do_something_with( cc );// }// cvReleaseMemStorage( &storage );//}int main(int argc, char** argv)cvNamedWindow('Example_pre', CV_WINDOW_AUTOSIZE);cvNamedWindow('Example_post',CV_WINDOW_AUTOSIZE);cvNamedWindow('Example', CV_WINDOW_AUTOSIZE);const char* filename = 'caise6.jpg';IplImage* src= cvLoadImage(filename, 1);IplImage* ddd = cvCreateImage( cvGetSize(src), src->depth, src->nChannels);cvCopy(src,ddd);/*cvZero(ddd);*/if(!src) { printf('Couldn't seem to Open %s, sorry\n',argv[1]); return -1;}cvShowImage( 'Example_pre', src);//IplImage* dst = cvCreateImage( cvGetSize(src), src->depth, src->nChannels);//IplImage* dst = cvCreateImage( cvSize( src->width*2, src->height*2 ), src->depth, src->nChannels);//用于缩放图像/*f( src, dst);*/IplImage* dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);//创建目标图像cvCvtColor(src,dst,CV_BGR2GRAY);cvSmooth(dst,dst,CV_GAUSSIAN,3,0,0,0);//模糊处理cvThreshold( dst, dst, 100, 255, CV_THRESH_BINARY );//二值化//IplConvKernel*element=cvCreateStructuringElementEx(3,1,0.5,0.5,CV_SHAPE_ RECT,0);//自定义核//cvMorphologyEx( dst, dst, NULL,element, CV_MOP_CLOSE, 8);//形态学开运算//cvCanny( dst, dst, 10, 100, 3 );//canny边缘检测cvCanny( dst, dst, 100, 150, 3 );//canny边缘检测CvMemStorage* storage = cvCreateMemStorage();/*CvSeq* contour = NULL;*/CvSeq* contour=cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , storage);cvFindContours(dst,storage, //所获得的轮廓点&contour,sizeof(CvContour),CV_RETR_EXTERNAL, //获取轮廓的方法CV_CHAIN_APPROX_NONE, cvPoint(0,0)); //轮廓近似的方法// Draw current contour.//绘制当前轮廓//cvDrawContours(dst,contour,CV_RGB(0,255,255),CV_RGB(0 ,255,255),0,2,8,cvPoint(0,0));for(;contour;contour = contour->h_next){CvBox2D32f* box;CvPoint* PointArray;CvPoint2D32f* PointArray2D32f;int i; // Indicator of cycle.int count = contour->total; // This is number point in contour//轮廓个数CvPoint center;CvSize size;// Number point must be more than or equal to 6 (for cvFitEllipse_32f).if( count < 6 )continue;// Alloc memory for contour point set.PointArray = (CvPoint*)malloc( count*sizeof(CvPoint) );PointArray2D32f=(CvPoint2D32f*)malloc( count*sizeof(CvPoint2D32f) );// Alloc memory for ellipse data.//分配内存给椭圆数据box = (CvBox2D32f*)malloc(sizeof(CvBox2D32f));// Get contour point set.cvCvtSeqToArray(contour, PointArray, CV_WHOLE_SEQ);// Convert CvPoint set to CvBox2D32f set.for(i=0; i<count; i++){PointArray2D32f[i].x = (float)PointArray[i].x;PointArray2D32f[i].y = (float)PointArray[i].y;}// Fits ellipse to current contour.//拟合当前轮廓cvFitEllipse(PointArray2D32f, count, box);// Convert ellipse data from float to integer representation.center.x = cvRound(box->center.x);center.y = cvRound(box->center.y);/*cout<< center.x<<' ';cout<< center.y<<'\n';*/size.width = cvRound(box->size.width*0.5);size.height = cvRound(box->size.height*0.5);/*cout<< size.width<<' ';cout<< size.width<<'\n';*/box->angle = -box->angle;// Draw ellipse. //画椭圆//if ((size.height <= 2 * size.width) && size.width < dst->width/32 && size.width > dst->width/128)//{// cvEllipse(ddd, center, size,// box->angle, 0, 360,// CV_RGB(255,255,255), 1, CV_AA, 0);// cout<< center.x<<' '<< center.y<<'\n';//}if((size.width*size.height>30)&&(size.width*size.height<800))//像素面积{if ((size.height/size.width<1.01) &&(size.height/size.width>0.99))//长短轴比例{if ((box->angle<0)&&(box->angle>-180))//角度{/* cvEllipse(ddd, center, size,box->angle, 0, 360,CV_RGB(255,255,255), 1, CV_AA, 0);*/cout<< center.x<<' '<< center.y<<'\n';EllipsePara m_oval;m_oval.m_Pt=center;m_oval.m_angle=box->angle;m_oval.m_size=size;Oval.push_back(m_oval);Point2f cen;cen.x = center.x;cen.y = center.y;centers.push_back(cen);//将元素添加到个矢量的末尾。
opencv圆环缺口的角度方法
OpenCV是一个开源的计算机视觉库,它提供了许多图像处理和计算机视觉方面的功能,包括检测圆环缺口的角度方法。
在OpenCV 中,可以使用霍夫变换来检测圆形物体,然后通过一些数学计算来确定圆环缺口的角度。
首先,你需要使用霍夫变换来检测圆环。
霍夫变换是一种常用的圆检测方法,可以通过cv2.HoughCircles()函数来实现。
该函数会返回检测到的圆的圆心坐标和半径。
一旦检测到圆环,你可以计算圆环的缺口角度。
通常情况下,可以通过计算缺口两侧的点与圆心的连线与水平方向的夹角来确定缺口的角度。
具体的步骤包括:
1. 找到圆环的圆心坐标和半径。
2. 在圆环上选择两个点作为缺口的起始点和结束点。
3. 计算起始点和结束点与圆心的连线与水平方向的夹角。
4. 如果需要,可以进行坐标变换来将角度转换为所需的坐标系。
另外,还可以考虑使用图像处理技术,如边缘检测和直线检测,来进一步精确定位圆环缺口的角度。
通过检测缺口两侧的直线并计
算其夹角,也可以得到圆环缺口的角度。
总之,通过OpenCV提供的霍夫变换等功能,结合数学计算和图
像处理技术,可以有效地检测圆环缺口的角度。
希望这些信息能够
帮助你解决问题。