之前在一位硕士研究生的论文上苦下很多功夫研究颜色识别,色差计算等等,其中不少要用到许多数学计算公式,我几乎看到茫然。后来才明白,许多有权威性的东西错误满满。绕了好多弯路。现在贴上代码,以警示。
int main()
{
IplImage *Asrc;//图A 的 原图
IplImage *Bsrc;//图B 的 原图
IplImage *Adst1, *Adst2,*Adst3,*Adst4;
IplImage *Bdst1, *Bdst2, *Bdst3,*Bdst4;
IplImage *Ahsi1;//图A 的 一个区域转化为hsi
IplImage *Ahsi2;
IplImage *Ahsi3;
IplImage *Ahsi4;
IplImage *Bhsi1;//图B 的 一个区域
IplImage *Bhsi2;
IplImage *Bhsi3;
IplImage *Bhsi4;
double aH1, aS1, aI1;
double bH1, bS1, bI1;
double aH2, aS2, aI2;
double bH2, bS2, bI2;
double aH3, aS3, aI3;
double bH3, bS3, bI3;
double aH4, aS4, aI4;
double bH4, bS4, bI4;
CvRect Arect1, Arect2, Arect3, Arect4;// 图A 的 四个 区域
CvRect Brect1, Brect2, Brect3, Brect4;//图B 的 四个区域
Arect1.x = APoint, Arect1.y = APointY1, Arect1.width = REC_W_H, Arect1.height = REC_W_H;//图1 的ROI 1 确定区域
Arect2.x = APoint, Arect2.y = APointY2, Arect2.width = REC_W_H, Arect2.height = REC_W_H;//图1 的ROI 2 确定区域
Arect3.x = APoint, Arect3.y = APointY3, Arect3.width = REC_W_H, Arect3.height = REC_W_H;//图1 的ROI 3 确定区域
Arect4.x = APoint, Arect4.y = APointY4, Arect4.width = REC_W_H, Arect4.height = REC_W_H;//图1 的ROI 4 确定区域
Brect1.x = BPoint, Brect1.y = BPointY1, Brect1.width = REC_W_H, Brect1.height = REC_W_H;// 图2 的ROI 1 确定区域 大小一样
Brect2.x = BPoint, Brect2.y = BPointY2, Brect2.width = REC_W_H, Brect2.height = REC_W_H;// 图2 的ROI 1 确定区域 大小一样
Brect3.x = BPoint, Brect3.y = BPointY3, Brect3.width = REC_W_H, Brect3.height = REC_W_H;// 图2 的ROI 1 确定区域 大小一样
Brect4.x = BPoint, Brect4.y = BPointY4, Brect4.width = REC_W_H, Brect4.height = REC_W_H;// 图2 的ROI 1 确定区域 大小一样
Asrc = cvLoadImage("d:/project/tt/7.bmp");//载入一张图片
Bsrc = cvLoadImage("d:/project/tt/7a.bmp");//载入 2 张图片//add
cvRectangle(Asrc, cvPoint(APoint, APointY1), cvPoint(APoint + REC_W_H, APointY1 + REC_W_H), cvScalar(255, 0, 0), 1); //画矩形 1
cvRectangle(Asrc, cvPoint(APoint, APointY2), cvPoint(APoint + REC_W_H, APointY2 + REC_W_H), cvScalar(255, 0, 0), 1); //画矩形 2
cvRectangle(Asrc, cvPoint(APoint, APointY3), cvPoint(APoint + REC_W_H, APointY3 + REC_W_H), cvScalar(255, 0, 0), 1); //画矩形 3
cvRectangle(Asrc, cvPoint(APoint, APointY4), cvPoint(APoint + REC_W_H, APointY4 + REC_W_H), cvScalar(255, 0, 0), 1); //画矩形 4
cvRectangle(Bsrc, cvPoint(BPoint, BPointY1), cvPoint(BPoint + REC_W_H, BPointY1 + REC_W_H), cvScalar(255, 0, 0), 1);
cvRectangle(Bsrc, cvPoint(BPoint, BPointY2), cvPoint(BPoint + REC_W_H, BPointY2 + REC_W_H), cvScalar(255, 0, 0), 1);
cvRectangle(Bsrc, cvPoint(BPoint, BPointY3), cvPoint(BPoint + REC_W_H, BPointY3 + REC_W_H), cvScalar(255, 0, 0), 1);
cvRectangle(Bsrc, cvPoint(BPoint, BPointY4), cvPoint(BPoint + REC_W_H, BPointY4 + REC_W_H), cvScalar(255, 0, 0), 1);
Adst1 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间
Bdst1 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间1 用来保存ROI 大小
Adst2 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间
Bdst2 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间1 用来保存ROI 大小
Adst3 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间
Bdst3 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间1 用来保存ROI 大小
Adst4 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间
Bdst4 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间1 用来保存ROI 大小
Ahsi1 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间
Bhsi1 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间2 用来保存ROI 大小
Ahsi2 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间
Bhsi2 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间2 用来保存ROI 大小
Ahsi3 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间
Bhsi3 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间2 用来保存ROI 大小
Ahsi4 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间
Bhsi4 = cvCreateImage(cvSize(REC_W_H, REC_W_H), 8, 3);//创建图像空间2 用来保存ROI 大小
//创建窗口
cvNamedWindow("res", CV_WINDOW_AUTOSIZE);
cvNamedWindow("res2", CV_WINDOW_AUTOSIZE);
//设置ROI区域
cvSetImageROI(Asrc, Arect1); //图1 设置 ROI 1
cvCopy(Asrc, Adst1);//图1 提取ROI
//取消设置
cvResetImageROI(Asrc);
cvSetImageROI(Asrc, Arect2); //图1 设置 ROI 2
cvCopy(Asrc, Adst2);//图1 提取ROI
//取消设置
cvResetImageROI(Asrc);
cvSetImageROI(Asrc, Arect3); //图1 设置 ROI 3
cvCopy(Asrc, Adst3);//图1 提取ROI
//取消设置
cvResetImageROI(Asrc);
cvSetImageROI(Asrc, Arect4); //图1 设置 ROI 4
cvCopy(Asrc, Adst4);//图1 提取ROI
//取消设置
cvResetImageROI(Asrc);
cvSetImageROI(Bsrc, Brect1); //图2 设置 ROI 1
//提取ROI
cvCopy(Bsrc, Bdst1);
cvResetImageROI(Bsrc);
cvSetImageROI(Bsrc, Brect2); //图2 设置 ROI 2
//提取ROI
cvCopy(Bsrc, Bdst2);
cvResetImageROI(Bsrc);
cvSetImageROI(Bsrc, Brect3); //图2 设置 ROI 3
//提取ROI
cvCopy(Bsrc, Bdst3);
cvResetImageROI(Bsrc);
cvSetImageROI(Bsrc, Brect4); //图2 设置 ROI 4
//提取ROI
cvCopy(Bsrc, Bdst4);
cvResetImageROI(Bsrc);
//显示图像
cvShowImage("res", Asrc);
cvShowImage("res2", Bsrc);
//需要提取图像ROI区域RGB的平均值,发现有一个cvAvg函数:
//CvScalar cvAvg( const CvArr* arr, const CvArr* mask=NULL );
CvScalar avgChannelsA1 = cvAvg(Adst1);
double AavgB1 = avgChannelsA1.val[0];
double AavgG1 = avgChannelsA1.val[1];
double AavgR1 = avgChannelsA1.val[2];//图 A ROI1 RGB 的均值
CvScalar avgChannelsA2 = cvAvg(Adst2);
double AavgB2 = avgChannelsA2.val[0];
double AavgG2 = avgChannelsA2.val[1];
double AavgR2 = avgChannelsA2.val[2];//图 A ROI2 RGB 的均值
CvScalar avgChannelsA3 = cvAvg(Adst3);
double AavgB3 = avgChannelsA3.val[0];
double AavgG3 = avgChannelsA3.val[1];
double AavgR3 = avgChannelsA3.val[2];//图 A ROI3 RGB 的均值
CvScalar avgChannelsA4 = cvAvg(Adst4);
double AavgB4 = avgChannelsA4.val[0];
double AavgG4 = avgChannelsA4.val[1];
double AavgR4 = avgChannelsA4.val[2];//图 A ROI4 RGB 的均值
double RGB1_2 = sqrt(2 * (pow((AavgB1 - AavgB2), 2)) + 4 * pow((AavgG1 - AavgG2), 2) + 3 * pow((AavgR1 - AavgR2), 2));
cout << "A 1--2 RGB ava : " << RGB1_2 << endl;
double RGB3_4 = sqrt(2 * (pow((AavgB3 - AavgB4), 2)) + 4 * pow((AavgG3 - AavgG4), 2) + 3 * pow((AavgR3 - AavgR4), 2));
cout << "A 3--4 RGB ava : " << RGB3_4 << endl;
double RGB1_3 = sqrt(2 * (pow((AavgB1 - AavgB3), 2)) + 4 * pow((AavgG1 - AavgG3), 2) + 3 * pow((AavgR1 - AavgR3), 2));
cout << "A 1--3 RGB ava : " << RGB3_4 << endl;
double RGB2_4 = sqrt(2 * (pow((AavgB2 - AavgB4), 2)) + 4 * pow((AavgG2 - AavgG4), 2) + 3 * pow((AavgR2 - AavgR4), 2));
cout << "A 2--4 RGB ava : " << RGB2_4 << endl;
cout << "-----------------------------------------" << endl;
CvScalar avgChannelsB1 = cvAvg(Bdst1);
double BavgB1 = avgChannelsB1.val[0];
double BavgG1 = avgChannelsB1.val[1];
double BavgR1 = avgChannelsB1.val[2];//图B ROI1 RGB 的均值
CvScalar avgChannelsB2 = cvAvg(Bdst2);
double BavgB2 = avgChannelsB2.val[0];
double BavgG2 = avgChannelsB2.val[1];
double BavgR2 = avgChannelsB2.val[2];//图B ROI1 RGB 的均值
CvScalar avgChannelsB3 = cvAvg(Bdst3);
double BavgB3 = avgChannelsB3.val[0];
double BavgG3 = avgChannelsB3.val[1];
double BavgR3 = avgChannelsB3.val[2];//图B ROI1 RGB 的均值
CvScalar avgChannelsB4 = cvAvg(Bdst4);
double BavgB4 = avgChannelsB4.val[0];
double BavgG4 = avgChannelsB4.val[1];
double BavgR4 = avgChannelsB4.val[2];//图B ROI1 RGB 的均值
double B_RGB1_2 = sqrt(2 * (pow((BavgB1 - BavgB2), 2)) + 4 * pow((BavgG1 - BavgG2), 2) + 3 * pow((BavgR1 - BavgR2), 2));
cout << "B 1--2 RGB ava : " << B_RGB1_2 << endl;
double B_RGB3_4 = sqrt(2 * (pow((BavgB3 - BavgB4), 2)) + 4 * pow((BavgG3 - BavgG4), 2) + 3 * pow((BavgR3 - BavgR4), 2));
cout << "B 3--4 RGB ava : " << B_RGB3_4 << endl;
double B_RGB1_3 = sqrt(2 * (pow((BavgB1 - BavgB3), 2)) + 4 * pow((BavgG1 - BavgG3), 2) + 3 * pow((BavgR1 - BavgR3), 2));
cout << "B 1--3 RGB ava : " << B_RGB1_3 << endl;
double B_RGB2_4 = sqrt(2 * (pow((BavgB2 - BavgB4), 2)) + 4 * pow((BavgG2 - BavgG4), 2) + 3 * pow((BavgR2 - BavgR4), 2));
cout << "B 2--4 RGB ava : " << B_RGB2_4 << endl;
RGBtoHSI(Adst1, Ahsi1, aH1, aS1, aI1);
RGBtoHSI(Bdst1, Bhsi1, bH1, bS1, bI1);
RGBtoHSI(Adst2, Ahsi2, aH2, aS2, aI2);
RGBtoHSI(Bdst2, Bhsi2, bH2, bS2, bI2);
RGBtoHSI(Adst3, Ahsi3, aH3, aS3, aI3);
RGBtoHSI(Bdst3, Bhsi3, bH3, bS3, bI3);
RGBtoHSI(Adst4, Ahsi4, aH4, aS4, aI4);
RGBtoHSI(Bdst4, Bhsi4, bH4, bS4, bI4);
cout << "aH1 ----- " << aH1 << endl;
cout << "aH2 ----- " << aH2 << endl;
cout << "aH3 ----- " << aH3 << endl;
cout << "aH4 ----- " << aH4 << endl;
cout << "aS1 ----- " << aS1 << endl;
cout << "aS2 ----- " << aS2 << endl;
cout << "aS3 ----- " << aS3 << endl;
cout << "aS4 ----- " << aS4 << endl;
cout << "aI1 ----- " << aI1 << endl;
cout << "aI2 ----- " << aI2 << endl;
cout << "aI3 ----- " << aI3 << endl;
cout << "aI4 ----- " << aI4 << endl;
cout << "A ----- --------------------- " << endl;
cout << "bH1 ----- " << bH1 << endl;
cout << "bH2 ----- " << bH2 << endl;
cout << "bH3 ----- " << bH3 << endl;
cout << "bH4 ----- " << bH4 << endl;
cout << "bS1 ----- " << bS1 << endl;
cout << "bS2 ----- " << bS2 << endl;
cout << "bS3 ----- " << bS3 << endl;
cout << "bS4 ----- " << bS4 << endl;
cout << "bI1 ----- " << bI1 << endl;
cout << "bI2 ----- " << bI2 << endl;
cout << "bI3 ----- " << bI3 << endl;
cout << "bI4 ----- " << bI4 << endl;
cout << "B ----- --------------------- " << endl;
//double RGB2HSV = sqrt(pow((bI - aI), 2) + pow((bS*bI*cos(bH*CV_PI / 180) - aS*aI*cos(aS*CV_PI / 180)), 2) + pow((bS*bI*sin(bH*CV_PI / 180) - aS*aI*sin(aS*CV_PI / 180)), 2));
//double RGB2HSV1_2// = sqrt(pow((aI2 - aI1), 2) + pow((aS2*aI2*cos(aH2*CV_PI / 180) - aS1*aI1*cos(aH1*CV_PI / 180)), 2) + pow((aS2*aI2*sin(aH2*CV_PI / 180) - aS1*aI1*sin(aH1*CV_PI / 180)),
2));
//double RGB2HSV3_4 = sqrt(pow((aI4 - aI3), 2) + pow((aS4*aI4*cos(aH4*CV_PI / 180) - aS3*aI3*cos(aH3*CV_PI / 180)), 2) + pow((aS4*aI4*sin(aH4*CV_PI / 180) - aS3*aI3*sin(aH3*CV_PI / 180)),
2));
//double RGB2HSV1_3 = sqrt(pow((aI3 - aI1), 2) + pow((aS3*aI3*cos(aH3*CV_PI / 180) - aS1*aI1*cos(aH1*CV_PI / 180)), 2) + pow((aS3*aI3*sin(aH3*CV_PI / 180) - aS1*aI1*sin(aH1*CV_PI / 180)),
2));
//double RGB2HSV1_4 = sqrt(pow((aI4 - aI1), 2) + pow((aS4*aI4*cos(aH4*CV_PI / 180) - aS1*aI1*cos(aH1*CV_PI / 180)), 2) + pow((aS4*aI4*sin(aH4*CV_PI / 180) - aS1*aI1*sin(aH1*CV_PI / 180)),
2));
//double RGB2HSV2_3 = sqrt(pow((aI2 - aI3), 2) + pow((aS2*aI2*cos(aH2*CV_PI / 180) - aS3*aI3*cos(aH3*CV_PI / 180)), 2) + pow((aS2*aI2*sin(aH2*CV_PI / 180) - aS3*aI3*sin(aH3*CV_PI / 180)),
2));
double RGB2HSV1_2 = sqrt(2*pow((aH2 - aH1), 2) + pow((aS2 - aS1), 2)/* + pow((aI2 - aI1), 2)*/);//权重改变 H分量 在这里忽略I分量
double RGB2HSV3_4 = sqrt(2*pow((aH3 - aH4), 2) + pow((aS3 - aS4), 2)/* + pow((aI3 - aI4), 2)*/);
double RGB2HSV1_3 = sqrt(2*pow((aH3 - aH1), 2) + pow((aS3 - aS1), 2)/* + pow((aI3 - aI1), 2)*/);
double RGB2HSV1_4 = sqrt(2*pow((aH1 - aH4), 2) + pow((aS1 - aS4), 2)/* + pow((aI1 - aI4), 2)*/);
double RGB2HSV2_3 = sqrt(2*pow((aH3 - aH2), 2) + pow((aS3 - aS2), 2)/* + pow((aI3 - aI2), 2)*/);
cout << "A 1--2 hSV : " << RGB2HSV1_2 << endl;
cout << "A 3--4 hSV : " << RGB2HSV3_4 << endl;
cout << "A 1--3 hSV : " << RGB2HSV1_3 << endl;
cout << "A 1--4 hSV : " << RGB2HSV1_4 << endl;
cout << "A 2--3 hSV : " << RGB2HSV2_3 << endl;
double bRGB2HSV1_2 = sqrt(2*pow((bH2 - bH1), 2) + pow((bS2 - bS1), 2)/* + pow((bI2 - bI1), 2)*/ );
double bRGB2HSV3_4 = sqrt(2*pow((bH3 - bH4), 2) + pow((bS3 - bS4), 2)/* + pow((bI3 - bI4), 2)*/ );
double bRGB2HSV1_3 = sqrt(2*pow((bH3 - bH1), 2) + pow((bS3 - bS1), 2)/* + pow((bI3 - bI1), 2)*/ );
double bRGB2HSV1_4 = sqrt(2*pow((bH1 - bH4), 2) + pow((bS1 - bS4), 2)/* + pow((bI1 - bI4), 2)*/ );
double bRGB2HSV2_3 = sqrt(2*pow((bH3 - bH2), 2) + pow((bS3 - bS2), 2)/* + pow((bI3 - bI2), 2)*/ );
cout << "B 1--2 hSV : " << bRGB2HSV1_2 << endl;
cout << "B 3--4 hSV : " << bRGB2HSV3_4 << endl;
cout << "B 1--3 hSV : " << bRGB2HSV1_3 << endl;
cout << "B 1--4 hSV : " << bRGB2HSV1_4 << endl;
cout << "B 2--3 hSV : " << bRGB2HSV2_3 << endl;
cvWaitKey(0);
cvDestroyWindow("res");//释放资源
cvDestroyWindow("res2");
cvReleaseImage(&Asrc);
cvReleaseImage(&Bsrc);
cvReleaseImage(&Adst1);
cvReleaseImage(&Bdst1);
cvReleaseImage(&Ahsi1);
cvReleaseImage(&Bhsi1);
return 0;
}
void RGBtoHSI(IplImage *src, IplImage *dst,double &H1,double &S1,double &I1)//src 为要处理的区域 ,dst是要存放转换后的HSI ,H1,S1,I1三分量值(dst的均值)
{
int i, j;
double b, g, r, numm, den, min, theta, H, S, I;
//add
double tmp_H, tmp_S, tmp_I;//用来存放H,S,I 的分量总和
tmp_H = 0;
tmp_S = 0;
tmp_I = 0;
//
CvScalar s0;
for (i = 0; i
for (j = 0; j
{
s0 = cvGet2D(src, i, j);
b = s0.val[0] / 255;
g = s0.val[1] / 255;
r = s0.val[2] / 255;
//几何推导法转换
numm = 0.5*((r - g) + (r - b));
den = sqrt((r - g)*(r - g) + (r - b)*(g - b));
if (den == 0)
H = 0;
else
{
theta = acos(numm / den);
if (b>g)
H = (2 * CV_PI - theta) / (2 * CV_PI);// M_PI --> CV_PI 20160729
else
H = theta / (2 * CV_PI);
}
min = (b>g) ? g : b;
min = (min>r) ? r : min;
den = r + g + b;
if (den == 0)
S = 0;
else
S = 1 - 3 * min / den;
I = (r + g + b) / 3;
//add 在这里转换了
tmp_H += H*360;
tmp_S += S*255;
tmp_I += I*255;
//end
cvSet2D(dst, i, j, cvScalar(H * 180, S * 255, I * 255));
}
//add
H1 = tmp_H/(src->height * src->width);//H1的 均值
S1 = tmp_S/(src->height * src->width);
I1 = tmp_I/(src->height * src->width);
//end
}
RGBtoHSI函数来源 ,注明出处!在此基础上增加均值输出。
http://blog.sina.com.cn/s/blog_a5b3ed560100yo26.html