Skip to content

Commit

Permalink
RGB <=> HSV conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
tom2238 committed Aug 8, 2019
1 parent ab9562a commit 2d49080
Show file tree
Hide file tree
Showing 3 changed files with 275 additions and 22 deletions.
157 changes: 157 additions & 0 deletions image.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,160 @@ TgaImageHead WriteTgaImage(char *filename, TgaImageHead WriteImage) {
fwrite_int(WriteImage.ImageDescriptor,1,fileout);
return WriteImage; //now ready to write image data
}

HsvColor RgbToHsv(RgbColor rgb) {
HsvColor hsv;
uint8_t rgbMin, rgbMax;
// Get min/max
rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);
rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);
// Value
hsv.v = rgbMax;
if (hsv.v == 0) {
hsv.h = 0;
hsv.s = 0;
return hsv;
}
// Saturation
hsv.s = 255 * (long)(rgbMax - rgbMin) / hsv.v;
if (hsv.s == 0) {
hsv.h = 0;
return hsv;
}
// Hue
if (rgbMax == rgb.r) {
hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);
}
else if (rgbMax == rgb.g) {
hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);
}
else {
hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);
}
return hsv;
}

RgbColor HsvToRgb(HsvColor hsv) {
RgbColor rgb;
uint8_t region, remainder, p, q, t;
// Grayscale
if (hsv.s == 0) {
rgb.r = hsv.v;
rgb.g = hsv.v;
rgb.b = hsv.v;
return rgb;
}
// 60 degrees region
region = hsv.h / 43;
remainder = (hsv.h - (region * 43)) * 6;

p = (hsv.v * (255 - hsv.s)) >> 8;
q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8;
t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8;

switch (region) {
case 0:
rgb.r = hsv.v; rgb.g = t; rgb.b = p;
break;
case 1:
rgb.r = q; rgb.g = hsv.v; rgb.b = p;
break;
case 2:
rgb.r = p; rgb.g = hsv.v; rgb.b = t;
break;
case 3:
rgb.r = p; rgb.g = q; rgb.b = hsv.v;
break;
case 4:
rgb.r = t; rgb.g = p; rgb.b = hsv.v;
break;
default:
rgb.r = hsv.v; rgb.g = p; rgb.b = q;
break;
}

return rgb;
}

AptColor HsvToApt(HsvColor hsv, uint8_t bits) {
AptColor apt;
apt.h = hsv.h;
switch (bits) {
case 0:
apt.sv = (hsv.s & 0x00)+(hsv.v >> 0);
break;
case 1:
apt.sv = (hsv.s & 0x80)+(hsv.v >> 1);
break;
case 2:
apt.sv = (hsv.s & 0xC0)+(hsv.v >> 2);
break;
case 4:
apt.sv = (hsv.s & 0xF0)+(hsv.v >> 4);
break;
case 5:
apt.sv = (hsv.s & 0xF8)+(hsv.v >> 5);
break;
case 6:
apt.sv = (hsv.s & 0xFC)+(hsv.v >> 6);
break;
case 7:
apt.sv = (hsv.s & 0xFE)+(hsv.v >> 7);
break;
case 8:
apt.sv = (hsv.s & 0xFF)+(hsv.v >> 8);
break;
case 3:
default:
apt.sv = (hsv.s & 0xE0)+(hsv.v >> 3);
break;
}

return apt;
}

HsvColor AptToHsv(AptColor apt, uint8_t bits) {
HsvColor hsv;
hsv.h = apt.h;
switch (bits) {
case 0:
hsv.s = (apt.sv & 0x00);
hsv.v = (apt.sv & 0xFF) << 0;
break;
case 1:
hsv.s = (apt.sv & 0x80);
hsv.v = (apt.sv & 0x7F) << 1;
break;
case 2:
hsv.s = (apt.sv & 0xC0);
hsv.v = (apt.sv & 0x3F) << 2;
break;
case 4:
hsv.s = (apt.sv & 0xF0);
hsv.v = (apt.sv & 0x0F) << 4;
break;
case 5:
hsv.s = (apt.sv & 0xF8);
hsv.v = (apt.sv & 0x07) << 5;
break;
case 6:
hsv.s = (apt.sv & 0xFC);
hsv.v = (apt.sv & 0x03) << 6;
break;
case 7:
hsv.s = (apt.sv & 0xFE);
hsv.v = (apt.sv & 0x01) << 7;
break;
case 8:
hsv.s = (apt.sv & 0xFF);
hsv.v = (apt.sv & 0x00) << 8;
break;
case 3:
default:
hsv.s = (apt.sv & 0xE0);
hsv.v = (apt.sv & 0x1F) << 3;
break;
}

return hsv;
}
25 changes: 25 additions & 0 deletions image.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ typedef struct {
FILE *File;
}TgaImageHead;

typedef struct {
uint8_t r;
uint8_t g;
uint8_t b;
}RgbColor;

typedef struct {
uint8_t h;
uint8_t s;
uint8_t v;
}HsvColor;

typedef struct {
uint8_t h; // Hue
uint8_t sv; // Reduced saturation and value
}AptColor;

//Write test image
int TestTGAImage(FILE *fp);
//Write one 24 bit pixel
Expand All @@ -37,4 +54,12 @@ unsigned int fread_int(char len, FILE *p);
TgaImageHead OpenTgaImage(char *filename);
//Write transmitted image
TgaImageHead WriteTgaImage(char *filename, TgaImageHead WriteImage);
//Convert RGB to HSV color space
HsvColor RgbToHsv(RgbColor rgb);
//Convert HSV to RGB color space
RgbColor HsvToRgb(HsvColor hsv);
//Convert HSV to APT color space
AptColor HsvToApt(HsvColor hsv, uint8_t bits);
//Convert APT to HSV color space
HsvColor AptToHsv(AptColor apt, uint8_t bits);
#endif
115 changes: 93 additions & 22 deletions img.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
#include "image.h"
#include "aptcode.h"

#define IMG_COL_STEP 4.2666666

void CallColorTable();

int main() {
printf("Start\n");
//FILE *fp;
Expand All @@ -20,17 +24,22 @@ int main() {
unsigned int data=0;
int i,j;

TgaImageHead ReadTga = OpenTgaImage("169049.tga");
TgaImageHead ReadTga = OpenTgaImage("duha.tga");
if(ReadTga.File == NULL) {
printf("Error\n");
exit(1);
}

TgaImageHead APTTga;
APTTga = ReadTga;
APTTga.Width = APT_LINE_SIZE;
APTTga = WriteTgaImage("fileAPT.tga", APTTga);
TgaImageHead APTTga,SecTga,ThirdTga;
APTTga = ReadTga;
SecTga = ReadTga;
ThirdTga = ReadTga;
APTTga = WriteTgaImage("file_col_1.tga", APTTga);
if(APTTga.File==NULL) {printf("Error\n"); exit(1);}
SecTga = WriteTgaImage("file_col_2.tga", SecTga);
if(SecTga.File==NULL) {printf("Error\n"); exit(1);}
ThirdTga = WriteTgaImage("file_col_3.tga", ThirdTga);
if(ThirdTga.File==NULL) {printf("Error\n"); exit(1);}

AptLine AptTrans;
uint8_t frame=1;
Expand All @@ -40,7 +49,7 @@ int main() {
AptTelemetry TelemetryA = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 255};
AptTelemetry TelemetryB = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 255};

for(j=0;j<ReadTga.Height;j++) {
/*for(j=0;j<ReadTga.Height;j++) {
AptTrans = CreateAptLine(frame, currentline, TelemetryA, TelemetryB, ReadTga.File);
frame++;
currentline++;
Expand All @@ -52,13 +61,13 @@ int main() {
APTdata = ConvLine.Value[i];
WriteTGAPixel(APTdata, APTdata, APTdata, APTTga.File);
}
}
}*/


fseek(ReadTga.File, IMG_TGA_HEAD_SIZE, SEEK_SET);
//fseek(ReadTga.File, IMG_TGA_HEAD_SIZE, SEEK_SET);
//write header
//ts = fopen("fileC1.tga", "wb");
TgaImageHead TGAC1, TGAC2, TGAC3;
/*TgaImageHead TGAC1, TGAC2, TGAC3;
TGAC1 = ReadTga;
TGAC2 = ReadTga;
TGAC3 = ReadTga;
Expand All @@ -67,41 +76,103 @@ int main() {
TGAC2 = WriteTgaImage("fileC2.tga", TGAC2);
if(TGAC2.File==NULL) {printf("ErrorC2\n"); exit(1);}
TGAC3 = WriteTgaImage("fileC3.tga", TGAC3);
if(TGAC3.File==NULL) {printf("ErrorC3\n"); exit(1);}
if(TGAC3.File==NULL) {printf("ErrorC3\n"); exit(1);}*/

printf("X: %d, Y:%d Z: %d\n",ReadTga.Width,ReadTga.Height,ReadTga.PixelDepth);

uint8_t gray = 0;
uint8_t color = 0;
uint8_t Rval;
uint8_t Gval;
uint8_t Bval;
RgbColor pixel;
HsvColor hsvcol;
AptColor aptc;
unsigned int pix;
for(i=0;i<ReadTga.Width;i++) {
for(j=0;j<ReadTga.Height;j++) {
pix = ReadTGAPixel(ReadTga.File);
Rval = GetRedSubPixel(pix);
Gval = GetGreenSubPixel(pix);
Bval = GetBlueSubPixel(pix);
Rval = GetRedSubPixel(pix)/1;
Gval = GetGreenSubPixel(pix)/1;
Bval = GetBlueSubPixel(pix)/1;
pixel.r = Rval;
pixel.g = Gval;
pixel.b = Bval;
gray = Rval*0.302 + Gval*0.59 + Bval*0.11;
WriteTGAPixel(gray, gray, gray, TGAC1.File);
gray = ((Rval / 32) << 5) + ((Gval / 32) << 2) + (Bval/ 64);
color = Rval/4+Gval/2+Bval/4;

hsvcol = RgbToHsv(pixel); // To HSV
aptc = HsvToApt(hsvcol,3); // To APT
hsvcol = AptToHsv(aptc,3); // To HSV
pixel = HsvToRgb(hsvcol); // TO RGB

WriteTGAPixel(hsvcol.h,hsvcol.h,hsvcol.h, APTTga.File);
WriteTGAPixel(aptc.sv,aptc.sv,aptc.sv, SecTga.File);
WriteTGAPixel(pixel.r,pixel.g,pixel.b, ThirdTga.File);
//gray = ((Rval / 32) << 5) + ((Gval / 32) << 2) + (Bval/ 64);
//gray = (Rval * 123/3125) << 5 + (Gval *1339/20000) << 2 + (Bval * 33/2500);
//WriteTGAPixel( ((Rval / 32))*((gray)/8) , ((Gval/32))*((gray)/8), ((Bval /64))*((gray)/4), TGAC3.File);
WriteTGAPixel(gray, gray, gray, TGAC3.File);
WriteTGAPixel( ((Rval / 32) << 5) , ((Gval / 32) << 5), (Bval/ 64) << 6, TGAC2.File);
//WriteTGAPixel(gray, gray, gray, TGAC3.File);
//WriteTGAPixel( ((Rval / 32) << 5) , ((Gval / 32) << 5), (Bval/ 64) << 6, TGAC2.File);
}
}



printf("R: %d, G: %d, B: %d, G: %d\n",Rval,Gval,Bval,gray);

printf("R: %d, G: %d, B: %d, G: %d\n",Rval,Gval,Bval,gray);

//CallColorTable();
printf("End\n");

fclose(TGAC1.File);
//fclose(TGAC1.File);
fclose(APTTga.File);
fclose(TGAC2.File);
fclose(TGAC3.File);
//fclose(TGAC2.File);
//fclose(TGAC3.File);
return 0;
}

void CallColorTable() {
float R=255;
float G=0;
float B=0;
uint16_t radius=0;
int i;
for(i=0;i<60;i++) {
printf("%d:%d,%d,%d\n",radius,(uint8_t)R,(uint8_t)G,(uint8_t)B);
G += IMG_COL_STEP;
if(G>255) {G=255;}
radius++;
}
for(i=0;i<60;i++) {
printf("%d:%d,%d,%d\n",radius,(uint8_t)R,(uint8_t)G,(uint8_t)B);
R -= IMG_COL_STEP;
if(R<0) {R=0;}
radius++;
}
for(i=0;i<60;i++) {
printf("%d:%d,%d,%d\n",radius,(uint8_t)R,(uint8_t)G,(uint8_t)B);
B += IMG_COL_STEP;
if(B>255) {B=255;}
radius++;
}
for(i=0;i<60;i++) {
printf("%d:%d,%d,%d\n",radius,(uint8_t)R,(uint8_t)G,(uint8_t)B);
G -= IMG_COL_STEP;
if(G<0) {G=0;}
radius++;
}
for(i=0;i<60;i++) {
printf("%d:%d,%d,%d\n",radius,(uint8_t)R,(uint8_t)G,(uint8_t)B);
R += IMG_COL_STEP;
if(R>255) {R=255;}
radius++;
}
for(i=0;i<60;i++) {
printf("%d:%d,%d,%d\n",radius,(uint8_t)R,(uint8_t)G,(uint8_t)B);
B -= IMG_COL_STEP;
if(B<0) {B=0;}
radius++;
}

}

0 comments on commit 2d49080

Please sign in to comment.