opencv图像分割合成_【3】OpenCV图像处理模块(10)inRange函数实现阈值化,HSV图像分割...

本篇博客介绍了如何利用OpenCV的inRange函数结合HSV色彩空间进行阈值化处理,以此实现物体检测。通过设置HSV的色相、饱和度和值的范围,可以有效地在图像中分割特定颜色的物体。文中包含HSV色彩空间的原理解释,代码示例以及不同参数下的分割效果展示。
摘要由CSDN通过智能技术生成

f6bba0283c1c0997ca78e325f95ac967.png

本节使用inRange函数来实现阈值化。跟前面的阈值化方法一样,只不过在实现时用阈值范围来替代固定阈值。

本节还提供了一种物体检测的手段,用基于像素值范围的方法,在HSV色彩空间检测物体。


HSV色彩空间

HSV(hue,saturation,value的首字母,分别表示颜色的色相、饱和度、强度)色彩空间是一种类似于RGB的颜色表示方式。hue通道是颜色类型,在需要根据颜色来分割物体的应用中,非常有效。saturation 的变化从不饱和到完全饱和,对应下图中灰色过度到阴影(没有白色成分)。Value描述了颜色的强度或者说亮度。下面是HSV圆柱体,表示HSV的颜色空间。

a21e4ec65f1b8959e6c48e72c7bffc91.png
HSV色彩空间By SharkDderivative work: SharkD [CC BY-SA 3.0 or GFDL], via Wikimedia Commons

由于RGB色彩空间是由三个来编码颜色,所以难以根据颜色来分割物体。

e550007c56f6cb6f5524ce27318a5c86.png
RGB色彩空间By SharkD [GFDL or CC BY-SA 4.0], from Wikimedia Commons

颜色空间的转换可使用cvtColor函数。

代码

// @tutorials imgproc module 10
// @文件 Threshold_inRange.cpp
// @主题 HSV图像的阈值分割,检测目标
// @修改 CVer
// @日期 2019年12月27日
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"
#include <iostream>

using namespace cv;

const int max_value_H = 360/2;
const int max_value = 255;
const String window_capture_name = "Video Capture";
const String window_detection_name = "Object Detection";
int low_H = 0, low_S = 0, low_V = 0;
int high_H = max_value_H, high_S = max_value, high_V = max_value;

//下面6个函数分别设置HSV三个通道分量的范围,每个通道最低值和最高值
static void on_low_H_thresh_trackbar(int, void *)
{
    low_H = min(high_H-1, low_H);
    setTrackbarPos("Low H", window_detection_name, low_H);
}

static void on_high_H_thresh_trackbar(int, void *)
{
    high_H = max(high_H, low_H+1);
    setTrackbarPos("High H", window_detection_name, high_H);
}

static void on_low_S_thresh_trackbar(int, void *)
{
    low_S = min(high_S-1, low_S);
    setTrackbarPos("Low S", window_detection_name, low_S);
}

static void on_high_S_thresh_trackbar(int, void *)
{
    high_S = max(high_S, low_S+1);
    setTrackbarPos("High S", window_detection_name, high_S);
}

static void on_low_V_thresh_trackbar(int, void *)
{
    low_V = min(high_V-1, low_V);
    setTrackbarPos("Low V", window_detection_name, low_V);
}

static void on_high_V_thresh_trackbar(int, void *)
{
    high_V = max(high_V, low_V+1);
    setTrackbarPos("High V", window_detection_name, high_V);
}

int main(int argc, char* argv[])
{//这里可以选择打开视频文件或者摄像头
    String videofile = samples::findFile("D:/opencv/sources/doc/js_tutorials/js_assets/cup.mp4");
    VideoCapture cap(videofile);//打开视频文件
    //VideoCapture cap(0);//打开摄像头

    namedWindow(window_capture_name);
    namedWindow(window_detection_name);

    //Trackbar分别设置HSV三个分量大小
    createTrackbar("Low H", window_detection_name, &low_H, max_value_H, on_low_H_thresh_trackbar);
    createTrackbar("High H", window_detection_name, &high_H, max_value_H, on_high_H_thresh_trackbar);
    createTrackbar("Low S", window_detection_name, &low_S, max_value, on_low_S_thresh_trackbar);
    createTrackbar("High S", window_detection_name, &high_S, max_value, on_high_S_thresh_trackbar);
    createTrackbar("Low V", window_detection_name, &low_V, max_value, on_low_V_thresh_trackbar);
    createTrackbar("High V", window_detection_name, &high_V, max_value, on_high_V_thresh_trackbar);

    Mat frame, frame_HSV, frame_threshold;
    while (true)
    {//获取图像帧
        cap >> frame;
        if(frame.empty())
        {
            break;
        }
        // BGR转换到HSV色彩空间
        cvtColor(frame, frame_HSV, COLOR_BGR2HSV);
        // 根据HSV设置的范围,检测目标
        inRange(frame_HSV, Scalar(low_H, low_S, low_V), Scalar(high_H, high_S, high_V), frame_threshold);

        // 显示分割结果
        imshow(window_capture_name, frame);
        imshow(window_detection_name, frame_threshold);

        //按q或esc退出
        char key = (char) waitKey(30);
        if (key == 'q' || key == 27)
        {
            break;
        }
    }
    return 0;
}

结果

程序运行后,通过trackbar分别设置HSV像素范围,截取部分处理结果如下图。可以看到设置不同的值,可以得到不同的分割效果。

cb41dfd57ee77f5a2292a7ee1b789947.png

3ce61bb490bd5f3775d89b04b9fe6b53.png
分割得到手和手臂

e1ef91e5edfd1152474f18e00ad0f78b.png

6d5bdfb0c9cd77223fb51ebfe300e879.png
分割得到杯子和手臂
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值