一种基于OpenCV的多扇区圆检测方法
opencv 实时计算相机拍摄的圆半径的算法
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()`函数复制一份原始图片。
一种基于OpenCV的多扇区圆检测方法
根据 圆的特 性 , 究 学 者 们 进 行 了 广 泛 的研 究 , 研 提 出了几何 特征 的 圆检源自测方 法、 曲线 拟合 圆检 测技
术 、 度方 向角 的 圆 检 测 方 法 、 于 共 形 几 何 代 数 梯 基 与 R dn变换 的 圆 检 测 方 法 等 多 种 检 测 技 术 J ao ,
dw 和 Ma S操作 系统 上 。 目前 , 最新 版本 22 os cO 其 .
已发 布 。O e C pn V致 力 于 真 实 世 界 的 实 时 应 用 , 通
过 优化 的 c代 码 的编 写 对 其 执 行 速 度 带 来 了可 观 的提 升 , 且 可 以通 过 购买 Itl IP高 性 能 多媒 并 ne 的 P
1 1期
矣昕宝 , : 等 一种基于 O eC p n V的多扇 区圆检测方法
3 9 69
2 2 多扇 区 圆检测模 型 与算 法原 理 .
被检测 图像与模 板第 i 扇区对应 的区域用点集 表 个
@
2 1 SiT c. nn . 0 1 c. eh E g g
一
种 基 于 O e C 的 多 扇 区 圆检 测 方 法 pn V
矣 昕 宝 全 海 燕 许伶 俐
( 双版纳 职业技 术学 院 西 ,西双版纳 6 60 6 10;昆明理工大学信息工程 与 自动化学 院 ,昆明 6 0 5 ) 50 1
者 和研 究 单 位 仍 致 力 于 如 何 进 一 步 提 高 圆检 测 正
体识别 、 图象分割、 人脸识 别、 动作识别 、 运动跟踪、
机器 人 等领域 。
2 多扇 区圆检测 原理
2 1 常用 的 圆检测 方法 .
确 率 方 面 的研 究 。O eC 作 为 开 源 的 机 器 视 觉 pnV 库 , 图像 检 浸 中得到 了广 泛 的应 用 。 在 4
2017-5-28圆弧检测(opencv-qt)
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变换是一种常用的图像处理算法,它可以用来检测图像中的圆形。
在本文中,将介绍如何使用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直径的识别方法在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)()```请注意,这只是一个基本的示例,实际应用中可能需要根据具体情况进行调整和优化。
基于OpenCV的圆形标记点的提取
2 0 1 3年 5月
组 合 机 床 与 自 动 化 加 工 技 术
M o d ul a r M a c h i ne To ol& A ut o ma t i c M an uf a c t ur i ng Te c hn i qu e
NO . 5
M a y 2 01 3
O 引 言
多视点云拼 接是将不 同坐标 系下 采集到 的点云经 过空间变换 , 转 为一个坐 标系下 的点云 , 进而将 模 型各 个 部分拼接 在一 起 。近年 来 , 国际上 许 多学 者 做 了大 量 的研究 , 提 出大 量 的拼接 方 法 。标 记 点拼 接 法 以操 作 方便 , 稳定性 高 , 得到 了广泛的应用 。世界级 的 C r e - a f o r m公 司就 采 用 标 记 点 拼接 法 来 拼 接 扫 描 的 点 云 。 另外德 国的 A T O S系统也 是采用这种方 法 。 标 记 点拼 接方 法首 先 要对 贴在 被 测 物 上 的 一组 或多组 标 记 点 中 心 进 行 提 取 , 得 到 同 组 标 记 点 在 不 同坐标 系 下 的 坐标 位 置 , 换 算 出 两 组 坐 标 系 的变 换 矩阵 , 从而 将 两 组 坐 标 系 下 被测 物 的 点 云 转 换 到相
( S c h o o l o f Me c h a n i c a l E n g i n e e r i n g , U n i v e r s i t y o f S c i e n c e a n d T e c h n o l o g y B e i j i n g , B e i j i n g 1 0 0 0 8 3 , C h i n a )
od i s f a s t a n d e ic f i e nt t o e x t r a c t c i r c u l a r ma r k e r s . Ke y wor ds:Op e n CV ;c i r c ul a r ma r ke r s ;e x t r a c t i on
如何基于OpenCVPython实现霍夫变换圆形检测
如何基于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 生成圆的原理概述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--检测图片中的圆形
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提取圆形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是一个图像处理算法库,全称是Open SourceComputer Vision Library ,opencv拥有强大的图像处理能力,本课题利用它完成图像处理并利用hough变换对获得的圆形工件检测圆形特征。本课题使用的产品开发环境是vsiual studio 2010,并调用opencv计算机视觉开源库。完成对圆形工件的圆形特征检测。
This topicwasdetailed introduction the principle of circular part detection based on machine vision .thatincludedimage preprocessing method and Hough transform circle detection principle. Andusedthe opencv library for image processing and Hough transform circle detection. And in the ideal case of system calibration, will obtain the circle parameters for the actual size, and standard parts size comparison, thus obtains the error between the two, seen from the results, the precision of measurement is still can be accepted,to meet the basic requirements.
opencv圆半径 -回复
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()`可以用于拟合点集到椭圆曲线,进而可以估计出椭圆的参数,包括圆心位置、长轴和短轴的长度等。
通过合适的参数选择和模型拟合,可以将椭圆曲线近似为圆形,从而得到圆的半径。
基于OpenCV的圆点blob识别函数圆个数检测
基于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学习笔记(八)边缘、线与圆的检测
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识别定位五个圆的标识物进行定位和位姿确定
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是一个开源的计算机视觉库,它提供了许多图像处理和计算机视觉方面的功能,包括检测圆环缺口的角度方法。
在OpenCV 中,可以使用霍夫变换来检测圆形物体,然后通过一些数学计算来确定圆环缺口的角度。
首先,你需要使用霍夫变换来检测圆环。
霍夫变换是一种常用的圆检测方法,可以通过cv2.HoughCircles()函数来实现。
该函数会返回检测到的圆的圆心坐标和半径。
一旦检测到圆环,你可以计算圆环的缺口角度。
通常情况下,可以通过计算缺口两侧的点与圆心的连线与水平方向的夹角来确定缺口的角度。
具体的步骤包括:
1. 找到圆环的圆心坐标和半径。
2. 在圆环上选择两个点作为缺口的起始点和结束点。
3. 计算起始点和结束点与圆心的连线与水平方向的夹角。
4. 如果需要,可以进行坐标变换来将角度转换为所需的坐标系。
另外,还可以考虑使用图像处理技术,如边缘检测和直线检测,来进一步精确定位圆环缺口的角度。
通过检测缺口两侧的直线并计
算其夹角,也可以得到圆环缺口的角度。
总之,通过OpenCV提供的霍夫变换等功能,结合数学计算和图
像处理技术,可以有效地检测圆环缺口的角度。
希望这些信息能够
帮助你解决问题。
一种基于OpenCV的多扇区圆检测方法
能,通过设定判据门限 τ,可以将由于噪声干扰而残
缺的圆重新绘制,进而起到修复功能。
2. 3 多扇区圆检测步骤
根据多扇区圆检测原理,基于 OpenCV 多扇区
圆检测步骤如下:
( 1) 原始图像预处理。首先对原始图像进行中
3700
科学技术与工程
11 卷
值滤波,然后进行二值化处理; ( 2) 对二值化图形进行边缘检测,然后进行膨
本方法的检测流程图如图 2 所示。
3 实验结果及分析
为测试该多扇区圆检测方法的准确性,对如图 3 所示的原始图像分别使用随机 Hough 变换和本方 法进行圆检测与识别。测试主机处理器为 Intel( R) Pentium( R) T2390 双核处理器,主频 1. 86 GHz,内 存 1 GB,原始图片为 640 × 480 的装有 100 个小钢 管的产品盒,实验目的就是利用多扇区圆检测方法 对产品盒中的小钢管进行识别统计。使用 VC6. 0 开发环境,通过调用 OpenCV 函数库,使用 C++ 语言 实现对多扇区圆检测方法的描述。
方为 x 轴的正方向,正上方为 y 轴的正方向,那么圆
环中的任意点可以用到横轴和纵轴的距离 x、y 表示
为点( x,y) ,将点( x,y) 与 x 轴正方向的夹角记为 α。
根据 x,y 的符号及点与 x 轴的夹角的正切值,可将该
模板划分为如下 8 个扇区。
[ ] 扇区 1: 0,π4 ( x > 0,y > 0,0 < tanα ≤ 1) ;
11 期
矣昕宝,等: 一种基于 OpenCV 的多扇区圆检测方法
3699
2. 2 多扇区圆检测模型与算法原理 为进一步提高圆检测识别效率,本文提出了一
OpenCV圆与矩形识别的方法
OpenCV圆与矩形识别的⽅法最近⼀个项⽬⽤到了图像识别,之前从未接触过OpenCV,经过各种找教程,终于是搞懂了⼀些。
整个具体流程⼤概是获取图像-->图像⼆值化,灰度图(cvtColor)-->图像降噪(GaussianBlur)->轮廓识别(cvFindContours)-->形状判断。
⼤多数教程很专业,各种参数分析看不懂,经过各种搜索终于是搞懂了。
识别圆在识别圆⽅⾯,OpenCV有内置的⽅法:霍夫圆变化:HoughCircles(edges, circles, CV_HOUGH_GRADIENT, 1.5, 10, 200, 100, 0, 0);参数分析:edges:灰度图像circles: std::vector<Vec3f> circles;数组,⽤来存储圆的坐标信息CV_HOUGH_GRADIENT:Hough 变换⽅式,⽬前只⽀持CV_HOUGH_GRADIENT, which is basically 21HT, described in [Yuen03].默认⽤这个1.5:累加器图像的分辨率,1的时候是与获取到的图像相同,1.5就是1.5倍10:圆与圆的最⼩距离,两个圆⼼距离如果在范围内则被认定为1个圆200:100-200两个参数选就够了100:默认100,数值越低识别圆越不精确(圆的数量识别变多可能有个弧线就被识别是圆)最后两个参数分别是识别圆的最⼩,最⼤的⾯积。
矩形识别矩形识别并没有内置⽅法,需要⾃⼰⼿写。
最主要的⽅法是⼆值化。
通过⼆值化来调节识别的强度。
cvThreshold(tgray, gray, 75, 250, CV_THRESH_BINARY);参数分析:src:原始数组 (单通道 , 8-bit of 32-bit 浮点数)。
dst:输出数组,必须与 src 的类型⼀致,或者为 8-bit。
threshold:阈值max_value:使⽤ CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最⼤值。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
11 期
矣昕宝,等: 一种基于 OpenCV 的多扇区圆检测方法
3699
2. 2 多扇区圆检测模型与算法原理 为进一步提高圆检测识别效率,本文提出了一
种多扇区圆检测方法。在对数字图形进行圆检测 前,首先生成一个多扇区模板,如图 1 所示。
图 1 多扇区圆检测模板
该模板为一圆环点集,规定圆环圆心 o 的正右
( 5) 若检测结果不是圆,在步骤二的结果图上 滑动多扇区模板,重复执行步骤( 4) ,一次的步进量 由具体情况决定; 若检测结果为圆,滑动模板,重复 步骤( 4) 进行再检测。若再次检测的结果为圆,计 算上次检测到圆的质心与本次检测到圆的质心间
的距离,若 其 距 离 小 于 某 一 设 定 值,认 为 两 次 检 测 到的是同一 个 圆,放 弃 本 次 检 测 结 果,根 据 需 要 决 定是否重绘检测到圆; 若检测到不是圆,滑动模板, 重复步骤( 4) ,直至模板滑动到图像尾部。
1 OpenCV 简介
OpenCV 是一个基于 BSD 许可证授权( 开源) 发 行的跨平台开源计算机视觉库于 1999 年由 Intel 建 立,现在由 Willow Garage 提供支持。它由一系列 C 函数和少量 C++ 类构成,同时提供了 Python、Ruby、 MATLAB 等语言的接口,实现了图像处理和计算机 视觉方面的很多通用算法,可以运行在 Linux、Win-
本检测方 法 将 不 存 在 该 问 题,根 据 算 法 原 理 可 知,
对内存的需求几乎不变,在进行检测时仅执行简单
的数学运算不会带来大的计算开销。在工程应用
中,干扰同时满足检测阈值 η 和判决门限 τ 的概率
极小,因此,该算法具有较高的识别准确率,具有很
强的抗 干 扰 能 力。同 时,该 方 法 具 有 检 测 修 复 功
图 5 多扇区圆检测结果
而使用随机 Hough 变换检测结果如图 6 所示, 检测出圆的数目为 101 个,检测耗时 514 ms 通过对 比原图发现,产 生 两 次 错 误 检 测 和 一 次 漏 检,如 图 中绿色圆圈标记所示。
图 6 随机 Hough 变换检测结果
通过实验发现,虽然原始图像经过与处理后含 有很大的干扰成分,但使用多扇区圆检测方法仍然 能将其中的圆准确无误的识别出来,并对有残缺的 圆进行了修复,与常用的随机 Hough 变换圆检测相 比,具有较高的识别准确率,算法计算开销小,耗时 较少,达到了通过计算机准确识别检测物体目的。
参考文献
1 Lam W C Y; Yuen S Y. Efficient technique for circle detection using hypothesis filtering and Hough transform. IEEE Transactions on Image and Signal,1996; 143( 5) : 292—300
2 多扇区圆检测原理
2. 1 常用的圆检测方法 圆形特征是自然界中的基本元素,成功地从数
字图像中检测与识别圆在机器视觉领域有着重要 的意义。人 们 相 继 提 出 了 很 多 圆 检 测 方 法,其 中, 最基础,使用最广泛的是基于 Hough 变换的圆检测 技术。但常规的 Hough 变换存有不少缺憾[1],于是 很多改进 的 Hough 变 换 圆 检 测 技 术 被 相 继 提 出。 根据圆的特 性,研 究 学 者 们 进 行 了 广 泛 的 研 究,提 出了几何 特 征 的 圆 检 测 方 法、曲 线 拟 合 圆 检 测 技 术、梯度方 向 角 的 圆 检 测 方 法、基 于 共 形 几 何 代 数 与 Radon 变换的圆检测方法等多种检测技术[2—5], 根据计算机图形学中圆的生成算法理论,有人提出 了亚像素 圆 检 测 方 法[6]。 虽 然,圆 检 测 算 法 很 多, 且各自取的了一定的研究效果,但目前还没有一种 能将圆的识别与检测做到完美的算法[7]。
[ ] 扇区 6: 54π,32π ( x < 0,y < 0,0 < tanα ≤ 1) ;
[ ] 扇区 7: 32π,74π ( x > 0,y < 0,tanα ≤ - 1) ;
[ ] 扇区 8: 74π,2π ( x > 0,y < 0,- 1 < tanα ≤0) 。
设第 i 个扇区对应点集 Mi。当对数字图像进行圆 检测时,将模板坐标系作为图像的局部坐标系,将模板
4 结束语
结合 OpenCV,使用本文提出的多扇区圆检测 方法,可以 准 确 的 识 别 出 数 字 图 像 中 圆 形,该 方 法 具有较高的识别准确率,在图像干扰较大情况下仍 然将各个圆形无误的识别出来。因此,该方法用于 工业现场或生产流水线,通过机器视觉来达到监控 识别的目 的。 然 而,本 方 法 还 存 有 一 些 不 足 之 处, 即使用本方法进行圆检测时,要根据具体情况实验 估计阈值和判决门限,这将是本论文以后继续研究 的方向。
的各个扇区分别与图像的对应区域执行相关运算,设
被检测图像与模板第 i 个扇区对应的区域用点集 Ni 表 示,那么 Mi 和 Ni 的相关值 Ri 可由如下公式求得。
j=p
∑ Ri = mij·nij ( i = 1,2,…,8) 。 j =1
其中,p 表示点集中点数目,mij 表示 Mi 的第 j 个点, nij 表示 Ni 的第 j 个点。
检测出来,与随机 Hough 变换相比,有较高的识别准确率和较小的计算开销。
关键词 圆检测 OpenCV 多扇区 Hough 变换
中图法分类号 TP391. 41;
文献标志码 A
在工业控制现场或生产流水线上,常常需要检 测设备运行状况或记录流水线上产品数目。然而, 很多工业控制现场环境不适于人作业,流水线上靠 人工清点产品数目又存在着效率低下且容易出错 等诸多问题。长期以来,人们一直探索解决此类问 题的方法。计算机视觉的出现与发展,给解决此类 问题带来了全新的视角。通过实时采集图像,利用 图像检测 技 术,即 可 让 计 算 机 完 成 识 别 与 检 测 任 务。虽然计算机视觉技术已应用于不少领域,但其 识别检测效 率 始 终 是 被 研 究 的 热 点,目 前,不 少 学 者和研究单位仍致力于如何进一步提高圆检测正 确率方 面 的 研 究。OpenCV 作 为 开 源 的 机 器 视 觉 库,在图像检测中得到了广泛的应用。
时,第一扇区检测结束,开始第二扇区检测。
根据检测精度要求,可设定一检测阈值 η。当相
关值 Ri ≥ η 时,令扇区检测结果 si 的值为 1,否则, 将其结果置为 0,然后计算各个扇区检测结果 S: S =
8
∑si,S 最大可取值为 8。最后,根据圆的判决门限
i =1
τ( τ ∈ { 1,2,3,…,8} ) 来判决图形是否为圆。若 S ≥
[ ] 扇区 2:
π 4
,π2
(x
> 0,y
> 0,1
<
tanα) ;
[ ] 扇区 3:
π 2
,34π
(x
<
0,y
>
0,tanα ≤ - 1)
;
[ ] 扇区 4: 34π,π ( x < 0,y > 0,- 1 < tanα ≤ 0) ;
[ ] 扇区 5: π,54π ( x < 0,y < 0,1 < tanα) ;
在进行相关运算的同时,计算点到两坐标轴的
距离 x,y,以及点与 x 轴正方向的夹角 α 的 tanα,( 为
了计算方便,可使用 y / x 的值代替 tanα) ,当点不满
足扇区约束条件时,当前扇区检测结束,例如在执行
第一扇区检测时,从 x 轴正方向起按逆时针方向开始
检测,当点( x,y) 不满足( x > 0,y > 0,0 < tanα ≤ 1)
胀处理,为多扇区圆检测做准备; ( 3) 根据边缘检测的结果确定多扇区圆检测的
阈值 η 和判决门限 τ,η 和 τ 的确定需要根据轮廓 的周长和 轮 廓 的 残 缺 度 进 行 测 试 估 计,一 般 情 况 下,轮廓越清晰、周长越长,η 的取值越大,轮廓的残 缺度越小,τ 的取值越小;
( 4) 在步骤( 2) 的结果图上执行多扇区相关运 算,根据运算结果判断是否为圆;
图 3 待检测源图像
通过使用 OpenCV 函数库对源图像进行中值滤 波、二值化、边缘提取、轮廓过滤和膨胀处理等预处 理后,得到预处理后的图像如图 4 所示。
图 2 多扇区圆检测流程图
图 4 预处理后图像
11 期
矣昕宝,等: 一种基于 OpenCV 的多扇区圆检测方法
ห้องสมุดไป่ตู้
3701
对预处理后的图像进行多扇区圆检测后的结 果如图 5 所示,在进行试验中,阈值设定为 13,判决 门限设置为 6,检测出圆的数目为 100 个,检测耗时 123 ms 并对有残缺的圆进行了修复。
方为 x 轴的正方向,正上方为 y 轴的正方向,那么圆
环中的任意点可以用到横轴和纵轴的距离 x、y 表示
为点( x,y) ,将点( x,y) 与 x 轴正方向的夹角记为 α。
根据 x,y 的符号及点与 x 轴的夹角的正切值,可将该
模板划分为如下 8 个扇区。
[ ] 扇区 1: 0,π4 ( x > 0,y > 0,0 < tanα ≤ 1) ;
第 11 卷 第 16 期 2011 年 6 月 1671—1815( 2011) 16-3698-05
科学技术与工程
Science Technology and Engineering
Vol. 11 No. 16 June 2011 2011 Sci. Tech. Engng.
一种基于 OpenCV 的多扇区圆检测方法
本方法的检测流程图如图 2 所示。
3 实验结果及分析
为测试该多扇区圆检测方法的准确性,对如图 3 所示的原始图像分别使用随机 Hough 变换和本方 法进行圆检测与识别。测试主机处理器为 Intel( R) Pentium( R) T2390 双核处理器,主频 1. 86 GHz,内 存 1 GB,原始图片为 640 × 480 的装有 100 个小钢 管的产品盒,实验目的就是利用多扇区圆检测方法 对产品盒中的小钢管进行识别统计。使用 VC6. 0 开发环境,通过调用 OpenCV 函数库,使用 C++ 语言 实现对多扇区圆检测方法的描述。