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