利用opencv找圆和计算两圆之间角度

这是我毕业设计的找资料与完成论文历程,第一次写博客,有错的地方希望大家给予理解。
我开始是利用IDS工业相机对图片进行拍照得到图片之后,利用opencv对图片进行处理,得到图中的两个圆形,然后利用两个圆心的坐标连成一条直线,计算直线与水平面之间的夹角就可以得到夹角。

OPENCV学习

我是在VS2013的开发环境下
首先是进行openCV开发环境的配置,这里我建议看一下浅墨大神的opencv入门教程,我开始就是从浅墨大神那里开始学习如何进行opencv配置和基础学习的知识。
【 专栏 】- 【OpenCV】入门教程 - 【浅墨的游戏编程Blog】毛星云(浅墨)的专栏(Keep Reading , Keep Writing , Keep Coding.) - CSDN博客
从这里面我学到了对图像的底层识别预处理,给了我很多的启发与帮助。
如果想要更加深入的了解OPENCV可以加入下面这样网站,里面有中文资料PDF,可以打印下来学习,而且那里有一个论坛知道一些最新的问题和解决办法关于opencv
OpenCV中文网站-论坛 - Powered by Discuz!

圆形标记点检测

当学会了使用opencv的使用之后就开始载入一张图片进行圆形标记点的检测,进行圆形标记点的检测方法有多种多样,但是在一个大的方向是可以分为两种。
1.霍夫圆梯度检测,在这里我参考的是下面两位大神的博客,讲解非常清晰
Opencv2.4.9源码分析——HoughCircles - 赵春江的专栏 - CSDN博客

【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑 - 【浅墨的游戏编程Blog】毛星云(浅墨)的专栏 - CSDN博客

2.检测轮廓跟踪拟合找圆,这是因为在现实的生活中圆形物体可能因为我们拍照技术或者是本身的缺陷变得不是一个完整圆形,差不多可以算成一个椭圆形,那么在这种时候单单使用霍夫梯度找圆就会出现很大的误差,这种时候就要用到第二种方法。
Opencv 找圆的方法(椭圆拟合) - fanfan513的专栏 - CSDN博客
原理进行讲解我是参考下面
opencv学习(四十)之寻找图像轮廓findContours() - 烟雨博客 - CSDN博客
总结:这两种方法是现在流行的最多,使用也最好的方法,其他方法差不多是在这两种方法之上进行优化与变形,例如还有第三种和第四种方法就可以在第二种方法之上变形得到,是第三种cvFindContours+Least Square和第四种cvFindContours+Least Square+SubPixle方法,这仅仅是我现在查找到的方法,可能还有更多更好的方法我没有找到,希望大家留言给我,我会继续丰富一下,谢谢。

利用霍夫梯度找圆参数矫正

在本次设计中我是使用opencv的霍夫梯度找圆方法,但是在利用这个方法找圆时会遇到很多问题,这使得我开始根本找不到圆形的位置,之后利用单步调试检查之后发现我的圆一个都没有找到,于是我利用显示图像得到原图的canny边缘检测图像,发现问题就是出在这里面,我的边缘检测里面根本就没有圆形的轮廓,之后怎么办呢,经过又回顾查看浅墨大神关于canny边缘检测的函数整理,知道可能是阈值选择的问题,但是阈值又有那么多,我也不知道哪种阈值是我的图像所需要的,又经过一番查找文献和思考之后我决定利用轨迹条设置不同阈值查看我找圆时圆的轮廓,当出现完整圆时的阈值就是我所需要的阈值。关于轨迹条我是参考了下面这位大神的博客。
opencv(九)之轨迹条条创建和使用createTrackbar - 烟雨博客 - CSDN博客
在利用轨迹条找到最佳圆的轮廓之后就可以直接利用霍夫梯度法找到圆了,然后直接利用画圆函数画出圆,标记出圆心就可以。

利用圆心得到角度

在找到圆心之后,利用画直线的函数在两个圆心之间画出一条线,这样显示更加直观。接下来的问题就是得到两个圆之间与水平面之间的夹角,这图片中圆心的位置是图片左上角,纵坐标表示y轴,横坐标表示x轴。指点两点坐标,知道圆心位置,水平面就是x轴方向,利用数学求角度方法就可以得到扭转角,角度变换是利用atan2()函数,是从下面大神整理的博客中理解用法。
atan函数与atan2函数的一点区别 - chinabinlang的专栏 - CSDN博客

下面是暂时完成完整代码

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
/** @function main */
int main(int argc, char** argv)
{
	Mat src, src_gray, src_gray_thr, src_gray_can;

	/// Read the image
	src = imread(argv[1], 1);

	if (!src.data)
	{
		return -1;
	}

	/// Convert it to gray

	cvtColor(src, src_gray, CV_BGR2GRAY);
		Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
		//进行膨胀操作
		dilate(src_gray, src_gray, element);
	/// Reduce the noise so we avoid false circle detection
	GaussianBlur(src_gray, src_gray, Size(9, 9), 2, 2);
	threshold(src_gray, src_gray_thr, 142, 255, THRESH_BINARY);
	namedWindow("Hough Circle", CV_WINDOW_NORMAL);
	imshow("Hough Circle", src_gray_thr);

	//Mat edges = cvCreateMat(src_gray.rows, src_gray.cols, CV_8UC1);//边缘图像
	double canny_threshold = 40;
	Canny(src_gray, src_gray_can, MAX(canny_threshold / 2, 1), canny_threshold, 3);//调用canny,变为二值图像,0和非0即0和255
	namedWindow("Hough Circle5", CV_WINDOW_NORMAL);
	imshow("Hough Circle5", src_gray_can);


	vector<Vec3f> circles;

	/// Apply the Hough Transform to find the circles
	HoughCircles(src_gray, circles, CV_HOUGH_GRADIENT, 1.7, src_gray.rows / 10, 50, 70, 0, 0);

	/// Draw the circles detected
	for (size_t i = 0; i < circles.size(); i++)
	{
		Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
		int radius = cvRound(circles[i][2]);
		// circle center
		circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0);
		// circle outline
		circle(src, center, radius, Scalar(0, 0, 255), 3, 8, 0);
	}
	/// Show your results
	Point center0(cvRound(circles[0][0]), cvRound(circles[0][1]));
	Point center1(cvRound(circles[1][0]), cvRound(circles[1][1]));
	line(src, center0, center1, CV_RGB(255, 0, 0));
	namedWindow("Hough Circle Transform Demo", CV_WINDOW_NORMAL);
	imshow("Hough Circle Transform Demo", src);
	double theda = atan2(center0.y - center1.y, center0.x - center1.x)*180/3.1415926;
	cout << "center0" <<"    "<< center0.x << "   " << center0.y << endl;
	cout << "center1" << "    "<< center1.x << "   " << center1.y << endl;
	cout << theda << endl;
	waitKey(0);
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这是我利用手机先拍下来的要检测的东西,可能拍照技术不好吧,算法也没有进行好大的优化,所以检测不是非常标准。现在还没有学会如何配置相机,等下一个博客我会接着写。

猜你喜欢

转载自blog.csdn.net/qq_40584593/article/details/85094233