2/23/2013

The Thing to be careful, when you use cvSetImageROI


cvSetImage is to set region of interest by a rect size.
If you program as follows:

cvSetImageROI(image, cvRect(10,10,300,300) ); //cvRect(Left, Top, Width, Height)

Then, The region set by (10,10,300,300) in the image will be prcessed only by functions.
so..

cvSetImageROI(image, cvRect(10,10,300,300) ); //cvRect(Left, Top, Width, Height)
cvSetZero(image);
cvResetImageROI(image);

The region (10,10,300,300) in the image is only set by zero.
and ROI is released by cvResetImageROI function.

But there is one thing to be careful.

//Origin image size is 1024, 768
cvSetIamgeROI(image, cvRect(10, 10, 300, 300) );
image->width; -> ?
image->height; -> ?

What do you think about the value?
the answer is 1024, 768
so if you program as follows:(This is not correct source!!)
cvSetImageROI(image, cvRect(10,10,300,300));
for(int h=0; h< image->height; ++h)
{
     for(int w=0; w< image->width; ++w)
     {
          unsigned char R,G,B;
          B = (unsigned char)image->imageData[h*image->widthStep+w*3+0];
          G = (unsigned char)image->imageData[h*image->widthStep+w*3+1];
          R = (unsigned char)image->imageData[h*image->widthStep+w*3+2];

          image->imageData[h*image->widthStep+w*3+0] =  (unsigned char)(255-B);
          image->imageData[h*image->widthStep+w*3+1] =  (unsigned char)(255-G);
          image->imageData[h*image->widthStep+w*3+2] =  (unsigned char)(255-R);
     }
}
cvResetImageROI(image);

The color of whole area of image is inverted.
So If you apply invert processing to the ROI, you have to program as follows:(This is correct source)
for(int h=image2->roi->yOffset; h< image2->roi->yOffset+image2->roi->height; ++h)
{
     for(int w=image2->roi->xOffset; w< image2->roi->xOffset+ image2->roi->width; ++w)
     {
          unsigned char R,G,B;
          B = (unsigned char)image2->imageData[h*image2->widthStep+w*3+0];
          G = (unsigned char)image2->imageData[h*image2->widthStep+w*3+1];
          R = (unsigned char)image2->imageData[h*image2->widthStep+w*3+2];

          image->imageData[h*image->widthStep+w*3+0] =  (unsigned char)(255-B);
          image->imageData[h*image->widthStep+w*3+1] =  (unsigned char)(255-G);
          image->imageData[h*image->widthStep+w*3+2] =  (unsigned char)(255-R);
     }
}

Thank you.
Be careful when you use cvSetImageROI~

2/19/2013

Mahalanobis distance source code between 2D normal distributions

Mahalanobis distance source code between 2D normal distributions

The formula to calculate malanobis distance from 2 distributions is follows:




This is source code

struct mean_cov{
    float mean11;
    float mean21;

    float cov11;
    float cov12;
    float cov21;
    float cov22;
};


float Dist_2Distribution( mean_cov mc1, mean_cov mc2 )
{

    float a,b,c,d;

    float A = (mc1.mean11 - mc2.mean11);
    float B = (mc1.mean21 - mc2.mean21);

    float e = 1/((mc1.cov11 + mc2.cov11)*(mc1.cov22 + mc2.cov22) - (mc1.cov12 + mc2.cov12)*(mc1.cov21 + mc2.cov21));

    a = e * (mc1.cov22 + mc2.cov22);
    b = e * -(mc1.cov12 + mc2.cov12);
    c = e * -(mc1.cov21 + mc2.cov21);
    d = e * (mc1.cov11 + mc2.cov11);

    

    return ((a*A + c*B)*A + (b*A + d*B)*B);
}

Mean, Covariance calculate source code from 2D data

The function "Get_M_C" calculates mean, covriance value of 2D data.
Input value of the function is 2D vector.
Ouput is struct that include 6 elements is consisted by 2x1 means and 2x2 covariance.


struct mean_cov{
 float mean11;
 float mean21;

 float cov11;
 float cov12;
 float cov21;
 float cov22;
};



mean_cov Get_M_C(vector< pair > &vecMC ){

 mean_cov smc;
 memset(&smc, 0, sizeof(float) * 6 );
 
 //mean first, second
 float sum_1=0;
 float sum_2=0;
 float sum_3=0;

 //mean
 int i;
 for(i=0; i < vecMC.size(); ++i)
 {
  sum_1 = sum_1 + vecMC[i].first;
  sum_2 = sum_2 + vecMC[i].second;  
 }
 smc.mean11 = sum_1 / vecMC.size();
 smc.mean21 = sum_2 / vecMC.size();

 sum_1 = 0;
 sum_2 = 0;
 sum_3 = 0;
 for(i=0; i < vecMC.size(); ++i)
 {
  sum_1 = sum_1 + ( (vecMC[i].first - smc.mean11) * (vecMC[i].first - smc.mean11) );
  sum_3 = sum_3 + ( (vecMC[i].second - smc.mean21) * (vecMC[i].second - smc.mean21) );
  sum_2 = sum_2 + ( (vecMC[i].first - smc.mean11) * (vecMC[i].second - smc.mean21) );
 }
 smc.cov11 = sum_1 / (vecMC.size()-1);
 smc.cov22 = sum_3 / (vecMC.size()-1);
 smc.cov21 = sum_2 / (vecMC.size()-1);
 smc.cov12 = sum_2 / (vecMC.size()-1);

 //cov 11
 //cov 12
 //cov 22
 //cov 21 is same with cov 12
 printf("mean11 = %lf \n", smc.mean11 );
 printf("mean21 = %lf \n", smc.mean21 );
 printf("cov11 = %lf \n", smc.cov11 );
 printf("cov12 = %lf \n", smc.cov12 );
 printf("cov21 = %lf \n", smc.cov21 );
 printf("cov22 = %lf \n", smc.cov22 );

 return smc;
}





This source code is example for using the function Get_M_C
vector< pair < float, float > > m;
mean_cov SampleMC;

for(int h=0; h< img1->height; ++h)
{
     for(int w=0; w< img1->width; ++w)
    {
        unsigned char R,G,B;
        B = (unsigned char)img1->imageData[h*img1->widthStep+w*3+0];
        G = (unsigned char)img1->imageData[h*img1->widthStep+w*3+1];
        R = (unsigned char)img1->imageData[h*img1->widthStep+w*3+2];
        float Cb,Cr;
        GetCbCrFromRGB(R, G, B, &Cb, &Cr);

        m.push_back( make_pair(Cb, Cr) );
    }
}


SampleMC = Get_M_C( m );