• 关于汽车颜色识别


    #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;
    }
    

    如果您有更好的想法,请多多指教!

  • 相关阅读:
    Navicat 连接MySQL 8.0.11 出现2059错误
    安全技术运营的心得
    浅谈命令混淆
    2021年度总结与2022新的展望
    域环境搭建之安装exchange
    内网ADCS攻防
    CVE202142287复现
    企业安全建设——安全防线框架建设(一)
    frp_v0.37.1内网穿透,内网服务公网用不求人
    WP7XNA 多点触摸
  • 原文地址:https://www.cnblogs.com/sophia-hxw/p/6138489.html
Copyright © 2020-2023  润新知