判断颜色信息-RGB2HSV(opencv)

  • Post author:
  • Post category:其他



前言

项目车号识别过程中,车体有三种颜色黑车黑底白字、红车红底白字、绿车黄底绿字,可以通过判断车体的颜色信息,从而判断二值化是否需要反转,主要是基于rgb2hsv函数进行不同颜色的阈值判断。

matlab代码可参考:

http://www.cnblogs.com/happyamyhope/p/6650920.html

与matlab中的rgb2hsv函数功能相同的opencv代码:


vector<Mat> rgb2hsv(Mat image){
    vector<Mat> image_rgb;
    vector<Mat> hsv(3);
    split(image, image_rgb);
    Mat B = (Mat_<double>)image_rgb.at(0) / 255;
    Mat G = (Mat_<double>)image_rgb.at(1) / 255;
    Mat R = (Mat_<double>)image_rgb.at(2) / 255;
    Mat_<double> H(image.rows, image.cols, 1);
    Mat_<double> S(image.rows, image.cols, 1);
    Mat_<double> V(image.rows, image.cols, 1);

    for (int m = 0; m <image.rows; m++)
    {
        for (int n = 0; n < image.cols; n++)
        {
            double var_B = B.at<double>(m, n);//image.at<cv::Vec3b>(j,i)[0];;B.data[m, n]
            double var_G = G.at<double>(m, n);
            double var_R = R.at<double>(m, n);
            //double var_Min=0;
            //double var_Max=100;
            double var_Min = min(var_R, min(var_G, var_B));    //Min. value of RGB
            double var_Max = max(var_R, max(var_G, var_B));    //Max. value of RGB
            double del_Max = var_Max - var_Min;             //Delta RGB value 
            V.at<double>(m, n) = var_Max;

            if (del_Max == 0.0)                     //This is a gray, no chroma...
            {
                H.at<double>(m, n) = 0.0;                                //HSV results from 0 to 1
                S.at<double>(m, n) = 0.0;
            }
            else                                    //Chromatic data...
            {
                if (var_Max == 0.0)
                {
                    S.at<double>(m, n) = 0.0;
                }
                else{
                    S.at<double>(m, n) = del_Max / var_Max;
                }

                if (var_R == var_Max) H.at<double>(m, n) = (var_G - var_B) / del_Max;
                else if (var_G == var_Max) H.at<double>(m, n) = 2 + (var_B - var_R) / del_Max;
                else if (var_B == var_Max) H.at<double>(m, n) = 4 + (var_R - var_G) / del_Max;

                H.at<double>(m, n) /= 6;
                if (H.at<double>(m, n) < 0) H.at<double>(m, n) += 1.0;
                
            }

        }

    } // end for
    hsv.at(0) = H;
    hsv.at(1) = S;
    hsv.at(2) = V;
    return hsv;

}


View Code

子函数程序代码:


bool isGreen(Mat image){

    vector< Mat > hsv_vec;//Mat M(7,7,CV_32FC2,Scalar(1,3));  

    //判断图像非空
    if (image.channels() < 3)
    {
        std::cout << "ROI Image Error! " << std::endl;
        return false;
    }
    
    ofstream outfile("E:\\carriage_recognition\\train_identification\\ROI1095\\HSV.xls");
    Mat h = hsv_vec.at(0)*180;
    Mat s = hsv_vec.at(1)*255;
    Mat v = hsv_vec.at(2)*255;

    unsigned int green = 0;
    unsigned int yellow = 0;
    double hout = 0;
    double sout = 0;
    double vout = 0;
    double ratio_g = 0;
    double ratio = 0;
    for (int m = 0; m < image.rows; m++)
    {
        for (int n = 0; n < image.cols; n++)
        {
            
            hout = h.at<double>(m, n);
            sout = s.at<double>(m, n);
            vout = v.at<double>(m, n);
            if ((hout >= 40 && hout <= 75) && (sout >= 60) && (vout >= 55))
                green++;
            else if ((hout >= 27 && hout <= 33) && (sout >= 60) && (vout >= 80))
                yellow++;
            //cout << m << "\t" << n << "\t" << hout << "\t" << sout << "\t" << vout << endl;
            outfile << m << "\t" << n << "\t" << hout << "\t" << sout << "\t" << vout << "\t";
            outfile << endl;
        }
        //outfile << endl;
    }
    ratio_g = (double)green * 100 / (image.rows*image.cols);
    ratio = (double)(green + yellow) * 100 / (image.rows*image.cols);

    if ( ratio > 0.04 && ratio_g > 0.0004 )
        return true;
    else
        return false;

}


View Code

主程序代码:


/************************************************************************
* Copyright(c) 2016  ZRJ
* All rights reserved.
*
* File:    isGreen.cpp
* Brief: 
* Version: 1.0
* Author: ZRJ
* Email: happyamyhope@163.com
* Date:    2017/03/29
* History:
* 20170329: 颜色识别;


************************************************************************/
//-------------------------------------------------------------------------
//头文件
#include <iostream>
#include <vector>
#include<time.h>
#include <fstream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"


using namespace cv;
using namespace std;

//-----------------------------------------------------------------------
//调参

//---------------------------------------------------------------------------------
//函数声明
bool isGreen(Mat image);
vector<Mat> rgb2hsv(Mat image);
//-----------------------------------------------------------------------------------------
//函数定义
int main(int argc, char** argv)
{
    char image_path[500];
    char green_path[500];
    ///处理图像

    for (int i = 1; i <= 1095; i++)
    {
        //获取图像帧
        cout << i << endl;
        sprintf(image_path, "E:\\carriage_recognition\\train_identification\\ROI1095\\ROI原图\\%d_number_ROI.png", i);
        sprintf(green_path, "E:\\carriage_recognition\\train_identification\\ROI1095\\green原图\\%d_number_ROI.png", i);
        Mat image = imread(image_path, 1);
        bool flag = isGreen( image );
        if ( flag )
            imwrite(green_path, image);

    }//end for
    //clock_t end = clock();
    //double interval = (double)(end - begin) / CLOCKS_PER_SEC;
    //cout << "处理图像耗时: " << interval << endl;
    return 0;

}


View Code

问题总结:

1.opencv中的cvtColor(image, hsv, CV_BGR2HSV, 0);语句与matlab函数的输出数据类型有些微差别;

2.自己编写的rgb2hsv函数的运行速度很慢,难以保证实际场景的实时性,后续需要优化;

3.rgb2hsv的公式转换问题,需要仔细研读matlab函数代码;

也可参考:http://www.easyrgb.com/index.php?X=MATH&H=20#text20

4.将数据保存在.xls中,方便与matlab的输出结果进行比较;



转载于:https://www.cnblogs.com/happyamyhope/p/6651004.html