VIVO X7玫瑰金与银色边框颜色区分 方案(C++实现)

之前在一位硕士研究生的论文上苦下很多功夫研究颜色识别,色差计算等等,其中不少要用到许多数学计算公式,我几乎看到茫然。后来才明白,许多有权威性的东西错误满满。绕了好多弯路。现在贴上代码,以警示。


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; iheight; i++)
    for (j = 0; jwidth; 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

你可能感兴趣的:(opencv)