赞
踩
找到目标颜色所在区域
色度空间转换
1.1 读取图像并滤波
1.2 根据公式将图像从rgb转换到hsv色度空间
颜色分割
2.1 利用 createTrackbar()函数建立滑动条,对颜色空间转换后的各通道进行阈值分割
2.2 根据阈值分割的结果,判断各种颜色的对应阈值
2.3 针对不同颜色,分别对图像进行阈值分割
2.4 对阈值分割结果进行数学统计,判断图像的颜色并输出分类结果
目标颜色检测
3.1 对图像进行预处理,消除噪声并获取二值化图
3.2 对二值图进行轮廓检测;
3.3 根据任务目标选择合适的多边形描述轮廓;
3.4 获取多边形区域后,从原图中截取该区域图像;
3.5 对多边形区域的图像进行颜色分割,对分割结果进行统计,判断图像的颜色并输出分类结果
#include <stdlib.h> #include <opencv2/opencv.hpp> #include <opencv2/core/core.hpp> #define LINEAR_X 0 #define SIZE 3 #define PI 3.1415926 #define HMaxValue 255 #define SMaxValue 255 #define VMaxValue 255 #define oo 1e9+7 using namespace std; using namespace cv; int H_min=100, H_max=124, S_min=43, S_max=255, V_min=46, V_max=255; Mat img_in; void Gaussian(Mat input, Mat output, double sigma){ double weight;//权重 double sum = 0; double Gaussian_Temp[SIZE][SIZE] = {0};//模板 weight = (2*PI*sigma*sigma); for(int i =0;i <SIZE;i++) { for(int j = 0;j < SIZE;j++) { int x = i - SIZE/2; int y = j - SIZE/2; Gaussian_Temp[i][j] =exp(-(x*x+y*y)/(2.0*sigma*sigma))/weight; sum += Gaussian_Temp[i][j]; } } for(int i = 0; i < SIZE;i++) { for(int j = 0;j < SIZE;j++) { Gaussian_Temp[i][j] = Gaussian_Temp[i][j]/sum;//归一化处理 //printf("%f ",Gaussian_Temp[i][j]); } //printf("\n"); } int rows = output.rows; int cols = output.cols; int channels = input.channels(); for(int i=0;i<rows;i++) { for(int j=0;j<cols;j++) { int sum3[3]={0}; int sum1 = 0; for(int k=0;k<SIZE;k++) for(int t=0;t<SIZE;t++) { int x=i+k-SIZE/2; int y=j+t-SIZE/2; if(x<0||y<0||x>=rows||y>=cols)continue; double m=Gaussian_Temp[k][t]; if(channels == 1)sum1+=m*input.at<uchar>(x,y); else if(channels == 3) { Vec3b rgb = input.at<Vec3b>(x,y); sum3[0]+=m*rgb[0]; sum3[1]+=m*rgb[1]; sum3[2]+=m*rgb[2]; } } if(channels == 3){ for(int k=0;k<3;k++){ if(sum3[k]>255)sum3[k]=255; if(sum3[k]<0)sum3[k]=0; output.at<Vec3b>(i,j)[k]=sum3[k]; } } else { if(sum1>255)sum1=255; if(sum1<0)sum1=0; output.at<uchar>(i,j)=sum1; } } } } void RBG2HSV(Mat input,Mat output){ int rows=input.rows; int cols=input.cols; //cout<<rows<<" "<<cols<<endl; for(int i=0;i<rows;i++){ for(int j=0;j<cols;j++){ Vec3b pix=input.at<Vec3b>(i,j);//012:BGR float b=1.0*pix[0]/255; float g=1.0*pix[1]/255; float r=1.0*pix[2]/255; float maxrgb=max(r,max(g,b)); float minrgb=min(r,min(g,b)); float diff=maxrgb-minrgb; float v=maxrgb; float s=(diff/v); float h; if(maxrgb-minrgb<1e-5)h=0; else if(maxrgb==r)h=60*(g-b)/diff; else if(maxrgb==g)h=60*(b-r)/diff+120; else if(maxrgb==b)h=60*(r-g)/diff+240; if(h<0)h+=360; else if(h>359)h-=360; output.at<Vec3b>(i,j)[0]=(int)(h*180/360); output.at<Vec3b>(i,j)[1]=(int)(s*255); output.at<Vec3b>(i,j)[2]=(int)(v*255); } } } /* 画颜色统计图 */ void Statistical(Mat input){ int weigth=210,height=300; Mat output=Mat::zeros(height,weigth,CV_8UC3); int rows=input.rows; int cols=input.cols; int colorNum[7]={0}; int sum=rows*cols; for(int i=0;i<rows;i++){ for(int j=0;j<cols;j++){ Vec3b pix=input.at<Vec3b>(i,j);//012:HSV if(pix[1]<43||pix[2]<46)continue; //pix[0]=pix[0]*180/255; int color=0; if((pix[0]>=0&&pix[0]<=10)||(pix[0]>=156&&pix[0]<=180))color=0; else if(pix[0]>=11&&pix[0]<=25)color=1; else if(pix[0]>=26&&pix[0]<=34)color=2; else if(pix[0]>=35&&pix[0]<=77)color=3; else if(pix[0]>=78&&pix[0]<=99)color=4; else if(pix[0]>=100&&pix[0]<=124)color=5; else if(pix[0]>=125&&pix[0]<=155)color=6; colorNum[color]++; } } Scalar Color[7]={Scalar(0,0,255),Scalar(0,125,255),Scalar(0,255,255),Scalar(0,255,0),Scalar(255,255,0),Scalar(255,0,0),Scalar(255,0,255)}; for(int i=0;i<7;i++){ int h=colorNum[i]*height/sum; rectangle(output,Point(i*30,height),Point((i+1)*30-1, height-h),Color[i],-1); } imshow("color",output); } void colorDetection(Mat input){ vector<vector<Point> > contours; vector<Vec4i> hierarchy; findContours( input, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0) ); if(contours.size()==0)return; int area=0,x=0,y=0,a=0,b=0,c=0,d=0; for(int k=0;k<contours.size();k++){ RotatedRect rectPoint = minAreaRect(contours[k]); Point2f point[4]; //将rectPoint变量中存储的坐标值放到 point的数组中 rectPoint.points(point); //寻找轮廓的左上角和右下角,算出长宽 int max_x=0,max_y=0,min_x=oo,min_y=oo; for (int i = 0; i < 4; i++) { if (max_x < point[i].x)max_x=int(point[i].x+0.5); if (max_y < point[i].y)max_y=int(point[i].y+0.5); if (min_x > point[i].x)min_x=(int)point[i].x; if (min_y > point[i].y)min_y=(int)point[i].y; } if(min_x<0)min_x=0; if(min_y<0)min_y=0; if(max_x>=input.cols)max_x=input.cols-1; if(max_y>=input.rows)max_y=input.rows-1; if((max_x-min_x)*(max_y-min_y)>area){ area=(max_x-min_x)*(max_y-min_y); x=min_x; y=min_y; a=max_x; b=max_y; c=max_x-min_x; d=max_y-min_y; } } if(c==0||d==0)return; //截取ROI区域 Mat output=img_in(Rect(x,y,c,d)); imshow("ROI",output); Mat hsv=Mat::zeros(output.size(),CV_8UC3); RBG2HSV(output,hsv); //统计截取之后的图像各种颜色的含量 Statistical(hsv); } /* 颜色分割 */ void thresholdSeq(int var,void* usrdata){ Mat input = *(static_cast<Mat*> (usrdata)); Mat output=Mat::zeros(input.size(),CV_8UC1); int rows=input.rows; int cols=input.cols; for(int i=0;i<rows;i++){ for(int j=0;j<cols;j++){ Vec3b pix=input.at<Vec3b>(i,j);//012:HSV if(pix[0]<H_min||pix[0]>H_max)continue; if(pix[1]<S_min||pix[1]>S_max)continue; if(pix[2]<V_min||pix[2]>V_max)continue; output.at<uchar>(i,j)=255; } } imshow("thresholdSeq",output); //目标颜色检测 colorDetection(output); } int main(int argc, char **argv) { //读取原始图像 img_in=imread(argv[1],IMREAD_UNCHANGED); //检查是否读取图像 if(img_in.empty()){ cout<<"Error! Input image cannot be read...\n"; return -1; } imshow("src",img_in); Mat frOut1=Mat::zeros(img_in.size(),CV_8UC3); Mat frOut2=Mat::zeros(img_in.size(),CV_8UC1); // 空域滤波函数 Gaussian(img_in,frOut1,1); // 色度空间转换 RBG2HSV(frOut1,frOut1); //阈值分割 namedWindow("thresholdSeq"); createTrackbar("H_min", "thresholdSeq", &H_min, HMaxValue, thresholdSeq,&frOut1); createTrackbar("H_max", "thresholdSeq", &H_max, HMaxValue, thresholdSeq,&frOut1); createTrackbar("S_min", "thresholdSeq", &S_min, SMaxValue, thresholdSeq,&frOut1); createTrackbar("S_max", "thresholdSeq", &S_max, SMaxValue, thresholdSeq,&frOut1); createTrackbar("V_min", "thresholdSeq", &V_min, VMaxValue, thresholdSeq,&frOut1); createTrackbar("V_max", "thresholdSeq", &V_max, VMaxValue, thresholdSeq,&frOut1); waitKey(); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。