HSV颜色检测

Home / C++ MrLee 2018-10-25 5659

HSV(Hue, Saturation, Value)是根据颜色的直观特性由A. R. Smith在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)。这个模型中颜色的参数分别是:色调(H),饱和度(S),亮度(V)。

RGB和CMY颜色模型都是面向硬件的,而HSV(Hue Saturation Value)颜色模型是面向用户的。
HSV模型的三维表示从RGB立方体演化而来。设想从RGB沿立方体对角线的白色顶点向黑色顶点观察,就可以看到立方体的六边形外形。六边形边界表示色彩,水平轴表示纯度,明度沿垂直轴测量。

OpenCV中HSV各个分量的取值范围
色调 H  : 0 ~ 180
用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°, 蓝色为240°。它们的补色是:黄色为60°,青色为180°, 品红为300°;

饱和度 S  :0 ~ 255
饱和度S表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。

亮度 V  : 0 ~ 255
亮度表示颜色明亮的程度,对于光源色,亮度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)。

若要识别某种颜色,HSV的3个分量的范围得自己调了,官方的颜色区域不是特别靠谱。
一点经验:亮度V 几乎对颜色的识别没有影响,亮度与颜色大概关系不大,只与环境中的光照有关,为了算法的适应性更强,可以把亮度V的范围调成0~255。
对颜色识别影响最大的是色调,这个得仔细调,当然,为了适应性强,范围最好调宽点。

以下的程序,能将一幅图像中的 红色、蓝色、黄色找出来:

(原图)

(HSV处理结果图)

代码

int main(){

    Mat srcImg = imread("3.jpg");  

    Mat hsvImg;    //将RGB颜色空间转换为HSV颜色空间
    cvtColor(srcImg, hsvImg, COLOR_BGR2HSV); //CV_BGR2YCrCb

    imshow("hsv", hsvImg);    int minH = 0; //26
    int maxH = 0; //34

    int minS = 0; //
    int maxS = 0;    int minV = 0; //200
    int maxV = 0;

    Mat yellowImg, blueImg, redImg;    for (int i = 0; i < 3; i++)
    {        switch (i)
        {            case 0: //黄色
                minH = 16; //26
                maxH = 35; //34

                minS = 160; //
                maxS = 255;

                minV = 50; //200
                maxV = 255;                // inRange(原图像, 最小值的范围, 最大值的范围, 输出图像); //输出图像是黑白二值图像,其中 最小值<=像素点<=最大值 的像素点是白色
                inRange(hsvImg, Scalar(minH, minS, minV), Scalar(maxH, maxS, maxV), yellowImg); //Threshold the image
                break;            case 1: //蓝色
                minH = 70; //26
                maxH = 120; //34

                minS = 150; //
                maxS = 255;

                minV = 50; //200
                maxV = 255;

                inRange(hsvImg, Scalar(minH, minS, minV), Scalar(maxH, maxS, maxV), blueImg); //Threshold the image
                break;            case 2: //红色
                minH = 0; //26
                maxH = 15; //34

                minS = 160; //
                maxS = 255;

                minV = 50; //200
                maxV = 255;

                inRange(hsvImg, Scalar(minH, minS, minV), Scalar(maxH, maxS, maxV), redImg); 
                break;            default:                cout << "颜色标志输入错误" << endl;
        }
    }

    Mat resultImg;
    Mat yeBluImg;    //bitwise_or(a, b, ab);
    //图像或 ,ab = a||b

    bitwise_or(yellowImg, blueImg, yeBluImg); //图像或 
    bitwise_or(yeBluImg, redImg, resultImg); //图像或

    imshow("result", resultImg);    //开操作 (去除一些噪点)  如果二值化后图片干扰部分依然很多,增大下面的size
    Mat eleOpen = getStructuringElement(MORPH_RECT, Size(6, 6));
    morphologyEx(resultImg, resultImg, MORPH_OPEN, eleOpen);
    imshow("open", resultImg);


    waitKey(0);    
    return 0;
}


本文链接:https://www.it72.com/12414.htm

推荐阅读
最新回复 (0)
返回