通过圆的颜色并结合霍夫变换检测目标圆的OpenCV代码

在实际应用场景中,我们遇到的图像一般是真彩色图像,即要检测的目标带有颜色信息,所以有必要知道如何利用目标的颜色信息来对目标进行检测。

在对图像的颜色进行处理时,RGB通道并不能很好地反映出物体具有的颜色信息,RGB颜色空间中存在的3个颜色分量与最终颜色联系不直观,而HSV颜色空间通过颜色、深浅及亮暗三个维度来描述颜色,更加符合人类感知颜色的方式,所以我们在检测颜色信息时往往用HSV空间而不用RGB空间。

HSV空间不仅更加符合人类感知颜色的方式,而且对颜色的描述也很简洁完备。比如红色在HSV颜色空间中的色度范围为0~10和160~180,而红色在RGB空间中就不好说范围了,当然纯红我们知道是(255,0,0),但是除了纯红还有那么多种红,在RGB空间中不好把红色系的范围界定出来。

HSV空间的三个通道分别为色调(Hue)通道、饱和度(Saturation)通道、和亮度(Value)通道。在标准HSV空间中,H通道的取值范围为0~360,S通道的取值范围为0~1(0%~100%),V通道的取值范围为0~1(0%~100%)。

在OpenCV的HSV空间中,H通道的取值范围为0~180;S通道的取值范围为0~255;V通道的取值范围为0~255。

在这里,我顺便给大家推荐一个取色和调色的小工具,这个小工具支持HSV空间的取色哦。不过这个工具用的是标准HSV空间。即H通道的取值范围为0~360,S通道的取值范围为0~1(0%~100%),V通道的取值范围为0~1(0%~100%)。所以在具体使用的时候要按比例转化一下!比如车牌蓝在标准HSV中是(225,100,81)那么转换到OpenCV中就是(225/360*180,100/255*100%,81/255*100%)

这个小工具的下载链接:https://pan.baidu.com/s/1qYpcU1u

这个小工具的截图如下

下面上代码:

代码中用到的图像的下载链接:https://pan.baidu.com/s/1bo6hEft

代码的目标是把下图中的红色圆检测出来并绘制在原图中。

 

思路是:先对输入图像进行HSV通道转换,然后利用红色的色度范围设置高、低阈值,根据各圆颜色不同从而检测原图中红色的两个圆。高、低阈值处理后各得到一个图像,将这两张图像合并后进行高斯滤波处理,完了之后再利用霍夫变换中的圆检测技术进行圆形区域提取。

//博主微信/QQ 2487872782
//有问题可以联系博主交流
//有图像处理需求也可联系博主
//图像处理技术交流QQ群 271891601

//OpenCV版本:3.0
//VS版本:2013

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <iostream>

using namespace std;


int main()
{
	cv::Mat srcImage = cv::imread("F:/material/images/P0043-circle.jpg");
	if (!srcImage.data)
		return -1;
	cv::imshow("srcImage", srcImage);
	cv::Mat resultImage = srcImage.clone();

	// 中值滤波(这个操作可视图像情况略去)
	//cv::medianBlur(srcImage, srcImage, 3);

	// 转换成hsv颜色空间
	cv::Mat hsvImage;
	cv::cvtColor(srcImage, hsvImage, cv::COLOR_BGR2HSV);

	// 颜色阈值化处理
	cv::Mat lowTempMat;
	cv::Mat upperTempMat;
	// 低阈值限定
	cv::inRange(hsvImage, cv::Scalar(0, 100, 100),cv::Scalar(10, 255, 255), lowTempMat);
	cout << "lowTempMat的通道数为" << lowTempMat.channels() << endl;

	// 高阈值限定
	cv::inRange(hsvImage, cv::Scalar(160, 100, 100),cv::Scalar(180, 255, 255), upperTempMat);

	cv::imshow("lowTempMat", lowTempMat);
	cv::imshow("upperTempMat", upperTempMat);

	// 颜色阈值限定合并
	cv::Mat redTempMat;
	cv::addWeighted(lowTempMat, 1.0, upperTempMat,1.0, 0.0, redTempMat);
	cv::imshow("redTempMat", redTempMat);

	// 高斯平滑
	cv::GaussianBlur(redTempMat, redTempMat, cv::Size(9, 9), 2, 2);

	// 霍夫变换检测圆
	std::vector<cv::Vec3f> circles;
	cv::HoughCircles(redTempMat, circles, CV_HOUGH_GRADIENT, 1, redTempMat.rows / 8, 100, 20, 0, 0);
	// 颜色圆检测结果判断
	if (circles.size() == 0)
		return 1;

	for (int i = 0; i < circles.size(); ++i)
	{
		// 绘制检测到颜色圆
		cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
		int radius = cvRound(circles[i][2]);
		cv::circle(resultImage, center, radius,cv::Scalar(0, 255, 0), 5);
	}
	cv::imshow("resultImage", resultImage);
	cv::waitKey(0);
	return 0;
}

注意:代码中函数inRange()的输出为单通道图像,满足阈值条件的像素点的值为255,不满足阈值条件的像素点的值为0,可不要以为inRange()的输出和输入图像的通道数一样。

运行结果如下图所示:

 

 

 

 从运行结果可以看出,代码成功检测出了原图中红色的圆。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值