前言
項目車号識别過程中,車體有三種顔色黑車黑底白字、紅車紅底白字、綠車黃底綠字,可以通過判斷車體的顔色資訊,進而判斷二值化是否需要反轉,主要是基于rgb2hsv函數進行不同顔色的門檻值判斷。
matlab代碼可參考
與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: [email protected]
* 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函數代碼;