基于VS2019和Opencv4,对hsv颜色空间的图像分割原理以及实现

基于hsv颜色空间的图像分割原理以及实现

HSV颜色空间模型是倒锥形模型:

在这里插入图片描述

这个模型是按色调(Hue)、饱和度(Saturation)、明暗(Value)来描述的。

H值代表色调、S值代表饱和度、V值代表亮度。

在圆锥上,角度代表色调H,饱和度S表示为点到中心竖线的距离,而亮度值V用中心竖线表示。

可以理解为:以圆锥底面圆心出发,沿着半径所在直线走越走色彩越鲜艳(S越大)。沿这当前点所在同心圆旋转则代表颜色改变(V改变),沿这母线往下则越大明暗程度越暗(V变大)

HSV对用户来说是一种直观的颜色模型。我们可以从一种纯彩色开始,即指定彩色角H,并让V=S=1,然后我们就可以通过向其中加入黑色和白色来得到我们需要的颜色。增加黑色可以减小v而s不变,同样增加白色可以减小S而V不变。例如,要想得到深蓝色,V=0.4 S=1 H=240,要想得到淡蓝色,V=1 S=0.4 H=240.

HSV在用于指定颜色分割时,有比较大的作用。
因为,一般同类事物的颜色一般相同/相近。所以,当所求对象颜色稳定,且其他干扰项没有相似颜色/有相似颜色不过区域面积小,就可以通过颜色HSV色彩空间来将这个对象提取出来。

很好,很有精神!这样理论完备,下面“魔法”开始!

注:跑的程序配置:VS2019,Opencv4.
opencv环境配置可以看这个视频:
https://www.bilibili.com/video/BV1i54y1m7tw?p=1

一、在知道目标对象颜色的HSV最小阀值和最大阀值的情况下如何在图像中标注出来?

功能:将颜色在h ( 91 ~91),s(255 ~ 255),v(203 ~203)这一色彩空间的图像用白色显示出来。

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
int hmin = 91, smin = 255, vmin = 203;
	int hmax = 91, smax = 255, vmax = 203;
	Mat imgHSV, Mask;
	Mat image = imread("D:/imagic/shapes.png");
	cvtColor(image, imgHSV, COLOR_BGR2HSV);//映射到HSV色彩空间
	Scalar lower(hmin, smin, vmin);//得到色彩空间的最小阀值
	Scalar upper(hmax, smax, vmax);//得到色彩空间的最大阀值
	inRange(imgHSV, lower, upper, Mask);//在这一空间内的显示白色,否则显示黑色并保存在Mask里面。

	imshow("image HSV", imgHSV);
	imshow("image Mask", Mask);
	waitKey(0);
	return 0;
}

可是很多时候,我们是不知道对象具体所属的色彩空间范围到底是多少的,这就需要我们去测了。测试方法如下:

二、对图片中物体HSV色彩空间范围测试。

调节方法:
1、从第一行往下依次调。
2、min的就往右调大,max往左调小。
3、这一滑动条,调整到恰当位置现象是,移动到该点时候如果(min调大一点/max调小一点),那目标对象/图片就从白色变为黑色(表示颜色区间排除了这个颜色)那么这行就算调好了。
图示:
在这里插入图片描述
那么hmin=91就是最合适的,下一行是hmax,我们开始调hmax
在这里插入图片描述
很明显,hmax=91时候也是最好的,就这样一行行调过去,就得到hmin,hmax,smin,smax,vmin,vmax,这六个参数了。
得到之后,用法就跟上面一样,可以在图片中直接显示出这个图像

以下是提取照片中的三角形栗子:
功能:
创建6个createTrackbar()滑动条分别代表hmin,hmax,smin,smax,vmin,vmax。



#include<iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
int hmin = 0, smin = 0, vmin = 0;
	int hmax = 179, smax = 255, vmax = 255;
	Mat imgHSV, Mask;
	Mat image = imread("下面那个图片的地址");
	
	namedWindow("Trackbars", (600, 200));
	createTrackbar("Hue Min", "Trackbars", &hmin, 179);//创建createTrackbar
	createTrackbar("Hue Max", "Trackbars", &hmax, 179);
	//从左到右分别代bar也就是滑动条的名字,滑动条在哪一个窗口,滑动条指的值就是&hmax的值动态修改,最大上限是179
	createTrackbar("Sat Min", "Trackbars", &smin, 255);
	createTrackbar("Sat Max", "Trackbars", &smax, 255);
	createTrackbar("Val Min", "Trackbars", &vmin, 255);
	createTrackbar("Val Max", "Trackbars", &vmax, 255);
	cvtColor(image, imgHSV, COLOR_BGR2HSV);//映射到HSV空间
	while (true)
	{
	Scalar lower(hmin, smin, vmin);
	Scalar upper(hmax, smax, vmax);
	inRange(imgHSV, lower, upper, Mask);//获取涂层蒙版

	imshow("image HSV", imgHSV);
	imshow("image Mask", Mask);
	waitKey(1);
	}
	return 0;
}

测试图片:
在这里插入图片描述

三、视频/相机的单个物体颜色提取

test.code功能:
如果是笔记本输入0,打开内置摄像头。
将想要识别的物体图像放到相机前,然后用类似获取单个图像中目标对象的最大最小阀值的方法,获取视频中物体的hmin,hmax,smin,smax,vmin,vmax。

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;
int main()
{
	int num;
	cout << "please cin the number thar you want to test the VideoCaptureNumuber" << endl;
	cout << "如果你有内置摄像机比如是笔记本那么就输入0,否则如果是连接了外置摄像机请输入1" << endl;
	cin >> num;
	Mat imgHSV, Mask, image;
	VideoCapture capture(num);
	int hmin = 0, smin = 0, vmin = 0;
	int hmax = 178, smax = 255, vmax = 255;
	namedWindow("Trackbars", (600, 200));
	createTrackbar("Hue Min", "Trackbars", &hmin, 179);
	createTrackbar("Hue Max", "Trackbars", &hmax, 179);
	createTrackbar("Sat Min", "Trackbars", &smin, 255);
	createTrackbar("Sat Max", "Trackbars", &smax, 255);
	createTrackbar("Val Min", "Trackbars", &vmin, 255);
	createTrackbar("Val Max", "Trackbars", &vmax, 255);
	while (true)
	{
		capture >> image;
		flip(image, image, 1);
		cvtColor(image, imgHSV, COLOR_BGR2HSV);
		Scalar lower(hmin, smin, vmin);
		Scalar upper(hmax, smax, vmax);
		inRange(imgHSV, lower, upper, Mask);//获取涂层蒙版
		//cout << hmin << "," << smin << "," << vmin << "," << hmax << "," << smax << "," << vmax << endl;
		imshow("image", image);
		//imshow("image HSV", imgHSV);
		imshow("image Mask", Mask);
		waitKey(1);
	}
	capture.release();
}

四、视频/相机的多个物体颜色提取出来后并保存的方法

未完待续~~~最迟今天或明天更新

五、得到mask之后的部分应用场景:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风吹落叶花飘荡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值