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

简介: 这篇文章介绍了基于HSV颜色空间的图像分割原理,包括HSV模型的基本概念和如何在OpenCV中通过设置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之后的部分应用场景:

相关文章
|
6月前
|
算法 计算机视觉
OpenCV(四十一):图像分割-分水岭法
OpenCV(四十一):图像分割-分水岭法
97 0
|
6月前
|
算法 计算机视觉
OpenCV(四十):图像分割—漫水填充
OpenCV(四十):图像分割—漫水填充
162 0
|
4月前
|
计算机视觉 Python
opencv识别颜色
opencv识别颜色
|
20天前
|
计算机视觉 Python
Opencv学习笔记(七):如何根据opencv将BGR转换为HSV
使用OpenCV库在Python中将BGR图像转换为HSV颜色空间的两种方法:一种是直接使用cv2.cvtColor函数,另一种是手动实现RGB到HSV的转换。
22 0
Opencv学习笔记(七):如何根据opencv将BGR转换为HSV
|
3月前
|
并行计算 算法 Java
cmake+vs2019编译OpenCV
cmake+vs2019编译OpenCV
39 0
|
3月前
|
计算机视觉 Windows
VS2019配置OpenCV
VS2019配置OpenCV
36 0
|
5月前
|
存储 Cloud Native Linux
OpenCV随机数与随机颜色绘制
OpenCV随机数与随机颜色绘制
|
5月前
|
计算机视觉
OpenCV图像色彩空间转换
OpenCV图像色彩空间转换
|
6月前
|
前端开发 计算机视觉 C++
【OpenCV】—分离颜色通道、多通道图像混合
【OpenCV】—分离颜色通道、多通道图像混合
|
6月前
|
算法 计算机视觉
【OpenCV】仿射变换中cv2.estimateAffine2D 的原理
【OpenCV】仿射变换中cv2.estimateAffine2D 的原理
249 0