#1,首先说说我自己做的一个小程序
有参考CSDN中的一篇博客,具体文章链接找不到了。
主要思想:将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; }
如果您有更好的想法,请多多指教!