颜色识别代码--初版

1、本程序是用于汽车颜色识别的出版,还有很多问题。

2、目前采用的是色差法,在RGB空间计算直方图后统计出现次数较多的点,与颜色模板进行匹配;

3、颜色模板设置有些问题,造成识别效果低,有待改善。。

 

// 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标志

// 颜色模板
国家标准规定:一般有10种颜色:
//  黑、白、红、绿、蓝、黄、 灰 , 棕、紫 粉
#define  BLACK   0
#define  WHITE   1
#define  RED     2
#define  GREEN   3
#define  BLUE    4
#define  YELLOW  5
#define  GRAY    6
#define  BROWN   7
#define  PURPLE  8
#define  PINK    9

int colorVelue[10][3] = {{0,0,0},  //黑
      {255,255,255},  //白
      {255,0,0},     //红
      {0,128,0},  //绿
      {0,0,255},     //蓝
      {255,255,0}, //黄
     // {128,128,128},  //灰
      {165,42,42},    //棕像素值的范围
      {128,0,128}, //紫,像素值的范围
{0,0,0}};//{255,192,203}}; //粉

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 = RED;
 }
 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)
{
 //复制ROI区域图像
 cv::Mat roiImage = cvCreateImage(cvSize(r.width, r.height), 8, 3 );
 car(r).copyTo(roiImage); 
 //
 /*cv::imshow("roi", roiImage); 
 cv::waitKey(0); */

 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("G",G);
 cvShowImage("B",B);
 //为这四幅图创建对应的直方图结构。
 int hist_size = 100;
 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);
  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 < 10; 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;
  *type = colorIdx;
 cvNamedWindow( "hsv", 1 );
 cvShowImage("hsv",roi); 
 cvWaitKey(0);
 //cvReleaseImage(&hsv);
 cvDestroyWindow("hsv");
 cvReleaseImage(&R);  
 cvReleaseImage(&G);  
 cvReleaseImage(&B);  
 //cvReleaseImage(&src_tmp1);
 cout<<"the colorof thiscar is:"<<colorIdx <<endl; 
   return *type;
}

int main(int argc, _TCHAR* argv[])
{
 cvNamedWindow( "color recognition", 1 );//建立视频窗口
 IplImage* src = cvLoadImage("Img267346543.jpg");
 //读图像//
 image = cvCreateImage( cvGetSize(src), 8, 3 );
 cvCopy(src,image);
 cvSetMouseCallback( "color recognition", on_mouse); // 设置鼠标回调函数
 cvShowImage( "color recognition", image );//显示视频和直方图
 
 车牌区域选择函数// 
 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);
 
车牌区域选择函数//
 
 if (1)
 {
  int i;
  int j;

  j = Color_difference_RGB(src,r,&i);
  cout<<"the colorof thiscar is:"<< j<<endl; 
 }

 cvReleaseImage(&image);
 cvDestroyWindow("CamShiftDemo");
 return 0;
}

 


//int main( int argc, char** argv )
//{
// IplImage * src;
// if (!(src = cvLoadImage("D:\\program Files\\matlab projects\\Lib行人数据库\\样本提取图像\\跑步姿势\\无标题.png")))
// {
//  cout << "没有找到源文件" << endl;
//  return -1;
// }
//
// IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 );
// IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 );
// IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 );
// IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 );
// IplImage* planes[] = { h_plane, s_plane };
//
// /** H 分量划分为16个等级,S分量划分为8个等级 */
// int h_bins = 16, s_bins = 8;
// int hist_size[] = {h_bins, s_bins};
//
// /** H 分量的变化范围 */
// float h_ranges[] = { 0, 180 };
//
// /** S 分量的变化范围*/
// float s_ranges[] = { 0, 255 };
// float* ranges[] = { h_ranges, s_ranges };
//
// /** 输入图像转换到HSV颜色空间 */
// cvCvtColor( src, hsv, CV_BGR2HSV );
// cvNamedWindow( "hsv", 1 );
// cvShowImage( "hsv", hsv );
//
// cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );
// cvNamedWindow( "h_plane", 1 );
// cvShowImage( "h_plane", h_plane );
// cvNamedWindow( "s_plane", 1 );
// cvShowImage( "s_plane", s_plane );
// cvNamedWindow( "v_plane", 1 );
// cvShowImage( "v_plane", v_plane );
//
// /** 创建直方图,二维, 每个维度上均分 */
// CvHistogram * hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );
// /** 根据H,S两个平面数据统计直方图 */
// cvCalcHist( planes, hist, 0, 0 );
//
// /** 获取直方图统计的最大值,用于动态显示直方图 */
// float max_value;
// cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );
//
//
// /** 设置直方图显示图像 */
// int height = 240;
// int width = (h_bins*s_bins*6);
// IplImage* hist_img = cvCreateImage( cvSize(width,height), 8, 3 );
// cvZero( hist_img );
//
// /** 用来进行HSV到RGB颜色转换的临时单位图像 */
// IplImage * hsv_color = cvCreateImage(cvSize(1,1),8,3);
// IplImage * rgb_color = cvCreateImage(cvSize(1,1),8,3);
// int bin_w = width / (h_bins * s_bins);
// for(int h = 0; h < h_bins; h++)
// {
//  for(int s = 0; s < s_bins; s++)
//  {
//   int i = h*s_bins + s;
//   /** 获得直方图中的统计次数,计算显示在图像中的高度 */
//   float bin_val = cvQueryHistValue_2D( hist, h, s );
//   int intensity = cvRound(bin_val*height/max_value);
//
//   /** 获得当前直方图代表的颜色,转换成RGB用于绘制 */
//   cvSet2D(hsv_color,0,0,cvScalar(h*180.f / h_bins,s*255.f/s_bins,255,0));
//   cvCvtColor(hsv_color,rgb_color,CV_HSV2BGR);
//   CvScalar color = cvGet2D(rgb_color,0,0);
//
//   cvRectangle( hist_img, cvPoint(i*bin_w,height),
//    cvPoint((i+1)*bin_w,height - intensity),
//    color, -1, 8, 0 );
//  }
// }
//
// cvNamedWindow( "Source", 1 );
// cvShowImage( "Source", src );
//
// cvNamedWindow("H-S Histogram", 1 );
// cvShowImage( "H-S Histogram", hist_img );
//
// cvWaitKey(0);
//}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值