• 判断颜色信息-RGB2HSV(opencv)


    前言

    项目车号识别过程中,车体有三种颜色黑车黑底白字、红车红底白字、绿车黄底绿字,可以通过判断车体的颜色信息,从而判断二值化是否需要反转,主要是基于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 << "	" << n << "	" << hout << "	" << sout << "	" << vout << endl;
                outfile << m << "	" << n << "	" << hout << "	" << sout << "	" << vout << "	";
                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的输出结果进行比较;

  • 相关阅读:
    protobuf 文档
    nodesass安装出错问题
    idea 部署docker
    cnpm报错 : 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本
    开源镜像下载
    工具—idea
    Java 17 java.util.HashSet 类源码分析
    IDEA 使用@Autowired提示Field injection is not recommended
    6 MyBatis动态SQL之choose(when、otherwise)语句
    Java Set的五种遍历方式
  • 原文地址:https://www.cnblogs.com/happyamyhope/p/6651004.html
Copyright © 2020-2023  润新知