天天看點

opencv圖像分割合成_【3】OpenCV圖像處理子產品(10)inRange函數實作門檻值化,HSV圖像分割...

opencv圖像分割合成_【3】OpenCV圖像處理子產品(10)inRange函數實作門檻值化,HSV圖像分割...

本節使用inRange函數來實作門檻值化。跟前面的門檻值化方法一樣,隻不過在實作時用門檻值範圍來替代固定門檻值。

本節還提供了一種物體檢測的手段,用基于像素值範圍的方法,在HSV色彩空間檢測物體。

HSV色彩空間

HSV(hue,saturation,value的首字母,分别表示顔色的色相、飽和度、強度)色彩空間是一種類似于RGB的顔色表示方式。hue通道是顔色類型,在需要根據顔色來分割物體的應用中,非常有效。saturation 的變化從不飽和到完全飽和,對應下圖中灰色過度到陰影(沒有白色成分)。Value描述了顔色的強度或者說亮度。下面是HSV圓柱體,表示HSV的顔色空間。

opencv圖像分割合成_【3】OpenCV圖像處理子產品(10)inRange函數實作門檻值化,HSV圖像分割...

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

由于RGB色彩空間是由三個來編碼顔色,是以難以根據顔色來分割物體。

opencv圖像分割合成_【3】OpenCV圖像處理子產品(10)inRange函數實作門檻值化,HSV圖像分割...

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像素範圍,截取部分處理結果如下圖。可以看到設定不同的值,可以得到不同的分割效果。

opencv圖像分割合成_【3】OpenCV圖像處理子產品(10)inRange函數實作門檻值化,HSV圖像分割...
opencv圖像分割合成_【3】OpenCV圖像處理子產品(10)inRange函數實作門檻值化,HSV圖像分割...

分割得到手和手臂

opencv圖像分割合成_【3】OpenCV圖像處理子產品(10)inRange函數實作門檻值化,HSV圖像分割...
opencv圖像分割合成_【3】OpenCV圖像處理子產品(10)inRange函數實作門檻值化,HSV圖像分割...

分割得到杯子和手臂