mardi 14 juin 2016

Implement RGBtoHSV C++ , wrong H output

I am trying to do Sobel operator in the HSV dimension (told to do this in the HSV by my guide but I dont understand why it will work better on HSV than on RGB) . I have built a function that converts from RGB to HSV . while I have some mediocre knowledge in C++ I am getting confused by the Image Processing thus I tried to keep the code as simple as possible , meaning I dont care (at this stage) about time nor space . From looking on the results I got in gray levels bmp photos , my V and S seems to be fine but my H looks very gibbrish . I got 2 questions here : 1. How a normal H photo in gray level should look a like comparing to the source photo ? 2. Where was I wrong in the code :

void RGBtoHSV(unsigned char image[][NUMBER_OF_COLUMNS][NUMBER_OF_COLORS],
float Him[][NUMBER_OF_COLUMNS],
float Vim[][NUMBER_OF_COLUMNS], 
float Sim[][NUMBER_OF_COLUMNS])
{

float Rn, Gn, Bn;

float   C;
float H, S, V;

for (int row = 0; row < NUMBER_OF_ROWS; row++)
{
    for (int column = 0; column < NUMBER_OF_COLUMNS; column++)
    {
        Rn = (1.0f*image[row][column][R]) / 255;
        Gn = (1.0f*image[row][column][G] )/ 255;
        Bn = (1.0f*image[row][column][B] )/ 255;

        float RGBn[3] = { Rn, Gn, Bn };

        float max = Rn;
        if (max < Gn) max = Gn;
        if (max < Bn) max = Bn;
        float min = Rn;
        if (min > Gn) min = Gn;
        if (min > Bn) min = Bn;

        C = max - min;
        /*
        H = 0;
        if (max == min) H = 0; //aka C=0
        else if (max == Rn)
        H = (float)(60.0* ((int)((Gn - Bn) / C) % 6));
        else if (max == Gn)
        H = 60.0f*((Bn - Rn) / C + 2);
        else
        H = 60.0f*((Rn - Gn) / C + 4);*/


        if (C == 0) H = 0;
        else
        {

            if (Rn > Gn)
            {
                if (Gn > Bn)
                {
                    H = (Gn - Bn) / (Rn - Bn);
                }
                else if (Bn > Rn)
                {
                    H = 4 + (Rn - Gn) / (Bn - Gn);
                }
            }
            else if (Rn > Bn)
            {
                if (Bn > Gn)
                {
                    H = 6 + (Gn - Bn) / (Rn - Gn);
                }
                else if (Gn > Rn)
                {
                    H = 2 + (Bn - Rn) / (Gn - Bn);
                }
            }
            else if (Gn > Bn)
            {
                if (Bn > Rn)
                {
                    H = 2 + (Bn - Rn) / (Gn - Rn);
                }
            }

            else if (Bn > Gn)
            {
                if (Gn > Rn)
                {
                    H = 4 + (Rn - Gn) / (Bn - Rn);
                }
            }
        }
        H = H * 60;
        while (H < 0) H += 360;

        V = max; //AKA lightness
        S = C / V; //saturation 
        Him[row][column] = H;
        Vim[row][column] = S;
        Sim[row][column] = V;
    }
}
}    

also my hsvtorgb :

void HSVtoRGB(unsigned char image[][NUMBER_OF_COLUMNS][NUMBER_OF_COLORS],
float Him[][NUMBER_OF_COLUMNS],
float Vim[][NUMBER_OF_COLUMNS],
float Sim[][NUMBER_OF_COLUMNS])
{

float R1, G1, B1;

float   C;
float   V;
int Htag;
float x;
for (int row = 0; row < NUMBER_OF_ROWS; row++)
{
    for (int column = 0; column < NUMBER_OF_COLUMNS; column++)
    {

        C = Vim[row][column] * Sim[row][column];
        Htag = (int) (Him[row][column] / 60);
        x = C*(1 - abs(Htag % 2 - 1));
        switch (Htag)
        {
        case 0 : 
            R1 = C;
            G1 = x;
            B1 = 0;
            break;
        case 1:
            R1 = x;
            G1 = C;
            B1 = 0;
            break;
        case 2:
            R1 = 0;
            G1 = C;
            B1 = x;
            break;
        case 3:
            R1 = 0;
            G1 = x;
            B1 = C;
            break;
        case 4:
            R1 = x;
            G1 = 0;
            B1 = C;
            break;
        case 5:
            R1 = C;
            G1 = 0;
            B1 = x;
            break;
        default:
            R1 = 0;
            G1 = 0;
            B1 = 0;
            break;

        }
        float m;
        V = Vim[row][column];
        m = V - C;

        image[row][column][R] = unsigned char(R1 + m);
        image[row][column][G] = unsigned char(G1 + m);
        image[row][column][B] = unsigned char( B1 + m);

    }
}
}


void HSVfloattoGrayconvert(unsigned char grayimage[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], float hsvimage[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], char hsv)
{
//grayimage , flaotimage , h/s/v
float factor;
if (hsv == 'h' || hsv == 'H') factor = (float) 1 / 360;
else factor = 1;

for (int row = 0; row < NUMBER_OF_ROWS; row++)
{
    for (int column = 0; column < NUMBER_OF_COLUMNS; column++)
    {
        grayimage[row][column] = (unsigned char) (0.5f + 255.0f * (float)hsvimage[row][column] / factor);
        //grayimage[row][column] = (unsigned char)(0.5 + 255.0*hsvimage[row][column] );
    }
}
}

and my main:

 unsigned char ColorImage1[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]   [NUMBER_OF_COLORS];
float Himage[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
float Vimage[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
float Simage[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];

 unsigned char ColorImage2[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]   [NUMBER_OF_COLORS];

unsigned char HimageGray[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
unsigned char VimageGray[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
unsigned char SimageGray[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];

unsigned char HAfterSobel[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
unsigned char VAfterSobel[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
unsigned char SAfterSobal[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];

   unsigned char HSVcolorAfterSobal[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS][NUMBER_OF_COLORS];

unsigned char RGBAfterSobal[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS][NUMBER_OF_COLORS];


int KernelX[3][3] = { 
{-1,0,+1}, {-2,0,2}, {-1,0,1 }
};

  int KernelY[3][3] = {
   {-1,-2,-1}, {0,0,0}, {1,2,1}
  };

  void main()
{

//work
LoadBgrImageFromTrueColorBmpFile(ColorImage1, "P22A.bmp");

// add noise
AddSaltAndPepperNoiseRGB(ColorImage1, 350, 255);
StoreBgrImageAsTrueColorBmpFile(ColorImage1, "saltandpepper.bmp");
AddGaussNoiseCPPstileRGB(ColorImage1, 0.0, 1.0);
StoreBgrImageAsTrueColorBmpFile(ColorImage1, "Saltandgauss.bmp");

//saves hsv in float array 
RGBtoHSV(ColorImage1, Himage, Vimage, Simage); 

//saves hsv float arrays in unsigned char arrays
HSVfloattoGrayconvert(HimageGray, Himage, 'h');
HSVfloattoGrayconvert(VimageGray, Vimage, 'v');
HSVfloattoGrayconvert(SimageGray, Simage, 's');


StoreGrayImageAsGrayBmpFile(HimageGray, "P22H.bmp");
StoreGrayImageAsGrayBmpFile(VimageGray, "P22V.bmp");
StoreGrayImageAsGrayBmpFile(SimageGray, "P22S.bmp");

    WaitForUserPressKey();

  }

Aucun commentaire:

Enregistrer un commentaire