首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

汽车色彩识别-更新版

2013-03-28 
汽车颜色识别--更新版1、改程序是基于同事车牌定位接口上进行的;2、为调试程序,程序中设定了鼠标选择图片中

汽车颜色识别--更新版

1、改程序是基于同事车牌定位接口上进行的;

2、为调试程序,程序中设定了鼠标选择图片中特定区域来进行识别;

3、程序针对汽车颜色,一共8种颜色

PS:相比刚接触opencv就接手的半死不活的行人检测,这个算是稍稍给了些安慰O(∩_∩)O,继续努力撒

 

// color recognition.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>
#include "cv.h"
#include <math.h>

using namespace cv;    
using namespace std;


Rect r;   //存储车牌位置
CvPoint origin;
IplImage* image=NULL;
int mark = 0;  //选择ROI标志
#define  N  12 //颜色模板的个数

// 颜色模板
//国家标准规定:一般有10种颜色:
//  黑、白、红、绿、蓝、黄/ 棕、紫 、灰
#define  BLACK   0
#define  WHITE   1
#define  RED1     2
#define  RED2     3
#define  GREEN1   4
#define  GREEN2   5
#define  BLUE1    6
#define  BLUE2    7
#define  YELLOW1  8
#define  YELLOW2  9
#define  BROWN    10
#define  GRAY     11

int colorVelue[N][3]  = {{50,50,50},    //黑
      {255,255,255},  //白
      {240,80,80}, //红小
      {240,160,160},  //红大
      {60,180,60}, //绿小
      {160,240,160},  //绿大
      {80,80,240}, //蓝小
         {160,160,240},  //蓝大
      {240,190,80}, //黄小
      {240,240,160},  //黄大
      {205,133,63}};   //棕/褐
      //{162,162,162},//灰,特殊
  

void on_mouse( int event, int x, int y, int flags, void* zhang )
{
 if( !image )
  return;
 CvPoint pt;
 if( event == CV_EVENT_LBUTTONDOWN ) //开始点击选择跟踪物体
 {
  origin = cvPoint( x,y );
     r = cvRect( x,y,0,0 );//坐标
  r.x = MIN( x,origin.x );
  r.y = MIN( y,origin.y );
  r.width = r.x + CV_IABS( x - origin.x );
  r.height = r.y + CV_IABS( y - origin.y );

  r.x = MAX( r.x, 0 );
  r.y = MAX( r.y, 0 );
  r.width = MIN( r.width, image->width );
  r.height = MIN( r.height, image->height );
  r.width -= r.x;
  r.height -= r.y;
  
 }

  if( event == CV_EVENT_LBUTTONUP )
  {
    pt = cvPoint( x,y );
    mark = -1;
       r.width = pt.x - r.x;
       r.height = pt.y - r.y;
  }

}
/*************************************************************************
 * 函数名称:
 *   Color_difference()
 * 参数:
 *   IplImage* car       - 输入原图像
 *   Rect r              - 源图像中划出的颜色识别区域
 * 返回值:
 *   int* type           - 指向颜色类型值,返回类型参数
 * 说明:
 *   该函数用来对图像进行颜色匹配识别。
 ************************************************************************/
//int Color_difference_HSV( cv::Mat car, Rect r,int* type)
//{
// //复制ROI区域图像
// cv::Mat roiImage = cvCreateImage(cvSize(r.width, r.height), 8, 3 );
// car(r).copyTo(roiImage); 
// //
// /*cv::imshow("roi", roiImage); 
// cv::waitKey(0); */
// //
// int hdims = 5; // 划分直方图bins的个数,越多越精确
// float hranges_arr[] = {0,180};//像素值的范围
// float* hranges = hranges_arr;//用于初始化CvHistogram类
//
// IplImage* roi = &roiImage.operator IplImage();  
// IplImage* hsv = cvCreateImage(cvGetSize(roi), IPL_DEPTH_8U, 3);//用于存图像的一个中间变量,是用来分通道用的,分成hsv通道  
// IplImage* tmpH1 = cvCreateImage( cvGetSize(roi), IPL_DEPTH_8U, 1);//通道的中间变量,用于肤色检测的中间变量  
// IplImage* tmpS1 = cvCreateImage(cvGetSize(roi), IPL_DEPTH_8U, 1);  
// IplImage* tmpH2 = cvCreateImage(cvGetSize(roi), IPL_DEPTH_8U, 1);  
// IplImage* tmpS2 = cvCreateImage(cvGetSize(roi), IPL_DEPTH_8U, 1);  
// IplImage* tmpH3 = cvCreateImage(cvGetSize(roi), IPL_DEPTH_8U, 1);  
// IplImage* tmpS3 = cvCreateImage(cvGetSize(roi), IPL_DEPTH_8U, 1);  
// IplImage* H = cvCreateImage( cvGetSize(roi), IPL_DEPTH_8U, 1);  
// IplImage* S = cvCreateImage( cvGetSize(roi), IPL_DEPTH_8U, 1);  
// IplImage* V = cvCreateImage( cvGetSize(roi), IPL_DEPTH_8U, 1);    
// IplImage* src_tmp1=cvCreateImage(cvGetSize(roi),8,3);  
// 
// 
// //CvHistogram *hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 ); //分配建立直方图空间
// //IplImage* mask = cvCreateImage( cvGetSize(hsv), 8, 1 );//分配掩膜图像空间
// //IplImage* hue = cvCreateImage( cvGetSize(hsv), 8, 1 );
// 
// // 高斯模糊  
// //cvSmooth(roi,src_tmp1,CV_GAUSSIAN,3,3); //高斯模糊  
//
// //// hue色度,saturation饱和度,value纯度  
// //cvCvtColor(src_tmp1, hsv, CV_BGR2HSV );//颜色转换  
// //cvCvtPixToPlane(hsv,H,S,V,0);//分为3个通道  
//
// //cvInRangeS(H,cvScalar(0.0,0.0,0,0),cvScalar(20.0,0.0,0,0),tmpH1);  
// //cvInRangeS(S,cvScalar(75.0,0.0,0,0),cvScalar(200.0,0.0,0,0),tmpS1);  
// //cvAnd(tmpH1,tmpS1,tmpH1,0);  
//
//// cvCalcHist( &hue, hist, 0, mask ); // 计算直方图
// 
// if (1)
// {
//  float velue[] = {0,0,0};
//  float d = sqrt(pow(colorVelue[0][0]-velue[0],2)+pow(colorVelue[0][1]-velue[1],2)+pow(colorVelue[0][2]-velue[2],2));
//  
//  cout<<d<<endl;
//  *type = RED1;
// }
// cvNamedWindow( "hsv", 1 );
// cvShowImage("hsv",roi); 
// //cvWaitKey(0);
//
// cvReleaseImage(&hsv);
// cvDestroyWindow("hsv");
// cvReleaseImage(&tmpH1);  
// cvReleaseImage(&tmpS1);  
// cvReleaseImage(&tmpH2);  
// cvReleaseImage(&tmpS2);  
// cvReleaseImage(&tmpH3);  
// cvReleaseImage(&tmpS3);  
// cvReleaseImage(&H);  
// cvReleaseImage(&S);  
// cvReleaseImage(&V);  
// cvReleaseImage(&src_tmp1);
//   return *type;
//}

int Color_difference_RGB( cv::Mat car, Rect r )
{
 int type = 0;
 //复制ROI区域图像
 if ( r.width==0 || r.height==0 )
 {
  return -1;
 }
 cv::Mat roiImage = cvCreateImage( cvSize(r.width, r.height), 8, 3 );
 car(r).copyTo(roiImage); 

 IplImage* roi = &roiImage.operator IplImage();  
   IplImage* R = cvCreateImage( cvGetSize(roi), IPL_DEPTH_8U, 1);  
 IplImage* G = cvCreateImage( cvGetSize(roi), IPL_DEPTH_8U, 1);  
 IplImage* B = cvCreateImage( cvGetSize(roi), IPL_DEPTH_8U, 1);      
  
 // 高斯模糊  
 //cvSmooth(roi,roi,CV_GAUSSIAN,3,3); //高斯模糊 ,作用   
 cvCvtPixToPlane(roi,B,G,R,0);//分为3个通道,OpenCV中不管是Windows中Load的还是摄像头取得的都是BGR顺序排列的
 
 cvShowImage("R",R);
 cvShowImage("hsv",roi); 
 cvShowImage("G",G);
 cvShowImage("B",B);
 
 //为这四幅图创建对应的直方图结构。
 int hist_size = 28; //划分bin的个数
 int hist_height = 100;
 float range[] = {0,255};
 float* ranges[]={range};
 CvHistogram* r_hist = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);
 CvHistogram* g_hist = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);
 CvHistogram* b_hist = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);
 
 //计算直方图,创建用于显示直方图的图像
 cvCalcHist( &R, r_hist, 0, 0 );
 cvCalcHist( &G, g_hist, 0, 0 );
 cvCalcHist( &B, b_hist, 0, 0 );
 cvNormalizeHist(r_hist,1.0);
 cvNormalizeHist(g_hist,1.0);
 cvNormalizeHist(b_hist,1.0);
 
 //开始显示,这里对直方图进行了标准化处理,不然的话无法观察到明显的变化
 int scale = 256/hist_size;
 IplImage* hist_image = cvCreateImage(cvSize(hist_size*scale,hist_height*3),8,3);
 cvZero(hist_image);
 float bmax_value = 0,rmax_value=0,gmax_value=0;
 float min_value; 
 int rmin_idx, rmax_idx,gmin_idx, gmax_idx,bmin_idx,bmax_idx; 
 float rmax=0,gmax=0,bmax=0; //保存最高峰值
 float ridx=0,gidx=0,bidx=0; //保存最高峰值的元素值

 cvGetMinMaxHistValue(r_hist, 0,&rmax_value,0,&rmax_idx);
 cvGetMinMaxHistValue(g_hist, 0,&gmax_value,0,0);
 cvGetMinMaxHistValue(b_hist, 0,&bmax_value,0,0);
 //cout<<"R最大值"<<(1-rmax_value)*255<<" "<<rmax_idx<<",G最大值"<<(1-gmax_value)*255<<",B最大值"<<(1-bmax_value)*255<<endl; 
 
  for(int i=0;i<hist_size;i++)
 {
  float bin_val = cvQueryHistValue_1D(r_hist,i);//返回相应bin中的值
  int intensity = cvRound(bin_val*hist_height/rmax_value);
  cvRectangle(hist_image,cvPoint(i*scale,hist_height),cvPoint((i+1)*scale - 1, hist_height - intensity),CV_RGB(255,0,0));  
  float k = (i+1)*255.f/hist_size;
  if (rmax<bin_val)
  {
   rmax = bin_val;
   ridx = k;
  }
 }
  cout<<rmax<<" "<<ridx<<endl;
 for(int i=0;i<hist_size;i++)
 {
  float bin_val = cvQueryHistValue_1D(g_hist,i);
  int intensity = cvRound(bin_val*hist_height/gmax_value); 
  cvRectangle(hist_image,cvPoint(i*scale,2*hist_height),cvPoint((i+1)*scale - 1, 2*hist_height - intensity),CV_RGB(0,255,0));
  float k = i*255.f/hist_size;
  if (gmax<bin_val)
  {
   gmax = bin_val;
   gidx = k;
  }  
 }
 cout<<gmax<<" "<<gidx<<endl;
 for(int i=0;i<hist_size;i++)
 {
  float bin_val = cvQueryHistValue_1D(b_hist,i);
  int intensity = cvRound(bin_val*hist_height/bmax_value);
        cvRectangle(hist_image,cvPoint(i*scale,3*hist_height),cvPoint((i+1)*scale - 1, 3*hist_height - intensity),CV_RGB(0,0,255));
  float k = i*255.f/hist_size;
  if (bmax<bin_val)
  {
   bmax = bin_val;
   bidx = k;
  }
 }
 cout<<bmax<<" "<<bidx<<endl;
 cvShowImage("ZHIFANGTUr",hist_image);

 //颜色判断及匹配
 float velue[] = {ridx,gidx,bidx};
 float dmin = 100000; //保存最小的距离
 int colorIdx = 0;
 for(int i=0 ; i <N ; i++)
 {
       float d = sqrt(pow(colorVelue[i][0]-velue[0],2)+pow(colorVelue[i][1]-velue[1],2)+pow(colorVelue[i][2]-velue[2],2));
   if (dmin > d)
   {
            dmin = d;
         colorIdx = i;
   }
 }
  cout<<"colorIdx:"<<colorIdx<<endl;
 if (( ridx>100 )&&( ridx<220 )&&( gidx>100 )&&( gidx < 220 )&&(bidx>100)&&(bidx<220)&&
  abs(ridx-gidx)<30&&abs(ridx-bidx)<30&&(gidx-bidx)<30)
 {
    type =  12;
 }
 else
  type = colorIdx;

 //cvDestroyWindow("hsv");
 cvReleaseImage(&R);  
 cvReleaseImage(&G);  
 cvReleaseImage(&B);
 cvReleaseImage(&hist_image);
 cvReleaseHist(&r_hist);
 cvReleaseHist(&g_hist);
 cvReleaseHist(&b_hist);
   return type;
}

int main(int argc, _TCHAR* argv[])
{
 cvNamedWindow( "color recognition", 1 );//建立视频窗口
 IplImage* src = cvLoadImage("D:\\tu\\U17328_20091230235830314-2.jpg");
 
 //读图像//
 image = cvCreateImage( cvGetSize(src), 8, 3 );
 //cvCopy(src,image);

 cvResize(src,image);
 cvShowImage( "color recognition", image );//显示视频和直方图
 cvWaitKey(1000);
 cvSetMouseCallback( "color recognition", on_mouse ); // 设置鼠标回调函数 
 
 ////车牌区域选择函数// 
 for ( int i=0;i<4;i++ )
 {
  if ( mark )
    {
     cout<<"区域坐标:"<<"x:"<<r.x<<", y:"<<r.y<<", width:"<<r.width<<", height:"<<r.height<<endl;
     cout<<"ok"<<endl;
    } 
 cvWaitKey(1000);
 cvRectangle( image,cvPoint(r.x,r.y ),cvPoint( r.x+r.width,r.y+r.height ),cvScalar(255,0,255) ,2, 8, 0);
 cvShowImage( "color recognition", image );
  
 }
 cvShowImage( "color recognition", image );
 cout<<"selection is ok"<<endl;
// cvWaitKey(0);
 
    //颜色匹配识别// 
 int j;
 j = Color_difference_RGB(src,r);  //返回颜色类型
 cout<<"j:"<<j<<endl;
 switch (j)
 {
     case -1:
  cout<<"please select ROI first!"<<endl;
  break;
     case 0:
         cout<<"the colorof thiscar is:黑"<<endl;
      break;
  case 1:
   cout<<"the colorof thiscar is:白"<<endl;
   break;
  case 2:
   cout<<"the colorof thiscar is:红"<<endl;
   break;
  case 3:
   cout<<"the colorof thiscar is:红"<<endl;
   break;
  case 4:
   cout<<"the colorof thiscar is:绿"<<endl;
   break;
  case 5:
   cout<<"the colorof thiscar is:绿"<<endl;
   break;
  case 6:
   cout<<"the colorof thiscar is:蓝"<<endl;
   break;
  case 7:
   cout<<"the colorof thiscar is:蓝"<<endl;
   break;
  case 8:
   cout<<"the colorof thiscar is:黄"<<endl;
   break;
  case 9:
   cout<<"the colorof thiscar is:黄"<<endl;
   break;
  case 10:
   cout<<"the colorof thiscar is:棕"<<endl;
   break;
     case 11 :
     cout<<"the colorof thiscar is:灰"<<endl;
     break;
  default:
     cout<<"the colorof thiscar is:其他"<<endl;
 }
     cvWaitKey(0); 
 cvReleaseImage(&image);
 cvReleaseImage(&src);
 cvDestroyWindow("color recognition");
 return 0;
}

 

热点排行