#1,首先说说我自己做的一个小程序
有参考优快云中的一篇博客,具体文章链接找不到了。
主要思想:将RGB颜色空间中的图像转换到HSV空间,根据常见九种颜色的H、S、V范围来判断给定图像中的汽车最大概率属于哪种色系的车。
常见颜色的HSV范围:(也是参考的网上的为主)
程序接口:【输入】Mat类型,汽车图片的patch;【输出】string类型,上面九种颜色中的一种;
算法流程图:
#2,存在的问题
可能原因:我个人觉得,HSV空间中的值与实际肉眼中的颜色并不是线性的映射关系,所以单纯用一个线性范围来给出一中颜色的HSV值是有问题的,实验结果也验证了我这个猜想。很多车子在进去检测时都会有误,如下给出几种:
尽管代码有问题,但还是在此贴出,以备之后改进:
/***********************************
-----------------------------------
Name: sophia
Date: 20161206
Email: hxinwen1218@sina.com
-----------------------------------
Function: Reco
Identification the color of the cars.
************************************/
#include<iostream>
#include<vector>
#include<string>
#include<conio.h>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
string ImgClass(Mat image);
/*
number color
0 blue;
1 orange;
2 yellow;
3 green;
4 violet
5 red;
6 white;
7 grey;
8 black;
9 red;
*/
int main(){
while (1)
{
string img_name;
cout << "Please enter the name of the image: " << endl;
cin >> img_name;
string imgN = img_name + ".jpg";
Mat img = imread(imgN);
string className;
className=ImgClass(img);
cout << "The class of the car is: " << className << endl;
char ch;
ch = _getch();
if (ch == 27)
break;
else
continue;
}
system("Pause");
return 0;
}
string ImgClass(Mat image){
int classNum = 10;
int lowH, highH, lowS, highS, lowV, highV;
vector<double> ptRate(classNum, 0.0);
string outClass;
for (int ic = 0; ic < classNum; ic++)
{
switch (ic)
{
case 0://blue
lowH = 100;
highH = 124;
lowS = 63;
highS = 255;
lowV = 76;
highV = 220;
break;
case 1://orange
lowH = 11;
highH = 25;
lowS = 43;
highS = 255;
lowV = 46;
highV = 255;
break;
case 2://yellow
lowH = 22;
highH = 37;
lowS = 43;
highS = 255;
lowV = 46;
highV = 255;
break;
case 3:
lowH = 35;
highH = 77;
lowS = 43;
highS = 255;
lowV = 46;
highV = 255;
break;
case 4:
lowH = 125;
highH = 155;
lowS = 43;
highS = 255;
lowV = 46;
highV = 255;
break;
case 5:
lowH = 0;
highH = 10;
lowS = 43;
highS = 255;
lowV = 46;
highV = 255;
break;
case 6://white
lowH = 0;
highH = 180;
lowS = 0;
highS = 25;
lowV = 225;
highV = 255;
break;
case 7://grey
lowH = 0;
highH = 180;
lowS = 28;
highS = 40;
lowV = 30;
highV = 221;
break;
case 8://black
lowH = 0;
highH = 180;
lowS = 0;
highS = 255;
lowV = 0;
highV = 30;
break;
case 9://red
lowH = 156;
highH = 180;
lowS = 43;
highS = 255;
lowV = 46;
highV = 255;
break;
}
Mat imgHSV;
vector<Mat> hsvSplit;
cvtColor(image, imgHSV, COLOR_BGR2HSV);
split(imgHSV, hsvSplit);
equalizeHist(hsvSplit[2], hsvSplit[2]);
merge(hsvSplit, imgHSV);
Mat imgThresholded;
inRange(imgHSV, Scalar(lowH, lowS, lowV), Scalar(highH, highS, highV), imgThresholded);
int nonZeroNum = 0;
vector<Mat> channelsImg;
split(imgThresholded, channelsImg);
Mat_<uchar> imgResult = channelsImg[0];
for (int ia = 0; ia < imgResult.rows; ia++)
for (int ib = 0; ib < imgResult.cols; ib++)
if (imgResult(ia, ib) != 0)
nonZeroNum++;
double rateCac = (double)nonZeroNum / (double)(imgResult.rows*imgResult.cols);
ptRate[ic] = rateCac;
}
double curRate = 0.0;
int classN;
for (int id = 0; id < ptRate.size(); id++)
{
if (ptRate[id] > curRate)
{
curRate = ptRate[id];
classN = id;
}
}
switch (classN){
case 0:
outClass = "blue";
break;
case 1:
outClass = "orange";
break;
case 2:
outClass = "yellow";
break;
case 3:
outClass = "green";
break;
case 4:
outClass = "violet";
break;
case 5:
outClass = "red";
break;
case 6:
outClass = "white";
break;
case 7:
outClass = "grey";
break;
case 8:
outClass = "black";
break;
case 9:
outClass = "red";
}
return outClass;
}
如果您有更好的想法,请多多指教!