The pseudo color generation program
Below is the C++ program used to take a grayscale 8 bits per channel, 1 channel, RAW input image and convert it into a pseudo color 8 bits per channel, 3 channel, RAW color interlaced output image. The program does this by first reading in the b/w image and determining what the intensity range of the image is. The program then re-reads the input image one scanline at a time and it takes each pixel's red, green and blue components and linearly scales the components into the user's selected output color range. Each color scanline is then written out to the output image.
/*******************************************
Program: Pseudo Colorize
Written By: Timothy S. Fox
Date: September 3, 1999
*******************************************/
#include "stdio.h"
#include "stdlib.h"
main()
{
int file_width, file_height;
FILE *matte_ptr, *output_ptr;
int n_written, row, col, result_color_comp;
float red_slope, green_slope, blue_slope, normalized_value;
unsigned char *output_image = NULL;
unsigned char *matte_pixels = NULL;
unsigned char start_color_red, start_color_green;
unsigned char start_color_blue;
unsigned char end_color_red, end_color_green, end_color_blue;
unsigned char intensity_difference;
unsigned char red_delta, green_delta, blue_delta;
unsigned char min_intensity, max_intensity;
char path[80];
char base_name[] = "holo";
//starting color at low end
start_color_red = 11;
start_color_green = 35;
start_color_blue = 54;
//ending color at high end
end_color_red = 150;
end_color_green = 200;
end_color_blue = 250;
//array space to hold one scanline of b/w and output images
output_image = (unsigned char *) malloc(9000);
matte_pixels = (unsigned char *) malloc(3000);
file_width = 700; /*file width*/
file_height = 292; /*file height*/
printf("image width = %d\n", file_width);
printf("image height = %d\n", file_height);
//now lets open up the b/w input file
sprintf(path, "Krusty:%s.matte", base_name);
matte_ptr = fopen(path, "rb");
if (matte_ptr == NULL)
{
free(output_image);
free(matte_pixels);
printf("Not able to open the b/w file %s\n", path);
exit(1);
}
printf("Scanning b/w file to determine intensity range..\n");
//initialize our limit variables
min_intensity = 255;
max_intensity = 0;
//now lets go through the input b/w file and determine what
//the lower and upper intensity limits are for the file
for (row=1; row <= file_height; row++)
{
//read in a 8 bit matte pixel scanline
if (fread((void *) matte_pixels, sizeof(char),
file_width, matte_ptr) != file_width)
{
fclose(matte_ptr);
free(output_image);
free(matte_pixels);
printf("Unable to read matte pixel block %d.\n", row);
exit(1);
}
//lets look through the scanline one pixel at a time
//and determine if we have a new min or max intensity
for (col=0; col < file_width; col++)
{
if (matte_pixels[col] < min_intensity)
min_intensity = matte_pixels[col];
if (matte_pixels[col] > max_intensity)
max_intensity = matte_pixels[col];
}
}
//what is the difference between the max intensity and the
//min intensity
intensity_difference = max_intensity - min_intensity;
printf("Finished scanning the input b/w image.\n");
printf("intensity range = %d\n", intensity_difference);
fclose(matte_ptr); //close input file
matte_ptr = fopen(path, "rb"); //lets reopen the input file
printf("matte image = %s\n", path);
//create an empty output file that will store the resulting
//pseudo color output image
sprintf(path, "Krusty:%s.out", base_name);
output_ptr = fopen(path, "wb");
if (output_ptr == NULL)
{
fclose(matte_ptr);
free(output_image);
free(matte_pixels);
printf("Unable to open output file %s for write.\n", path);
exit(1);
}
printf("output image = %s\n", path);
//are we going up or down to go from the starting color
//to the ending color for the red, blue, and green components
if (end_color_red > start_color_red)
{
red_slope = 1.0;
red_delta = end_color_red - start_color_red;
}
else
{
red_slope = -1.0;
red_delta = start_color_red - end_color_red;
}
if (end_color_green > start_color_green)
{
green_slope = 1.0;
green_delta = end_color_green - start_color_green;
}
else
{
green_slope = -1.0;
green_delta = start_color_green - end_color_green;
}
if (end_color_blue > start_color_blue)
{
blue_slope = 1.0;
blue_delta = end_color_blue - start_color_blue;
}
else
{
blue_slope = -1.0;
blue_delta = start_color_blue - end_color_blue;
}
//now lets go through and retrieve each row of the b/w image
for (row=1; row <= file_height; row++)
{
//read in a 8 bit b/w input image scanline
if (fread((void *) matte_pixels, sizeof(char),
file_width, matte_ptr) != file_width)
{
fclose(matte_ptr);
fclose(output_ptr);
free(output_image);
free(matte_pixels);
printf("Unable to read matte pixel block %d.\n", row);
exit(1);
}
for (col=0; col < file_width; col++)
{
//normalize the matte value
normalized_value = (matte_pixels[col] - min_intensity) /
((float) intensity_difference);
//calculate the resulting red color component
//for this pixel in the scanline
result_color_comp = start_color_red + (red_slope *
normalized_value * red_delta);
//make sure the color is within 0-255 range
if (result_color_comp > 255)
output_image[col*3] = 255;
else if (result_color_comp < 0)
output_image[col*3] = 0;
else
output_image[col*3] = result_color_comp;
//calculate the resulting green color component
//for this pixel in the scanline
result_color_comp = start_color_green + (green_slope *
normalized_value * green_delta);
//make sure the color is within 0-255 range
if (result_color_comp > 255)
output_image[col*3+1] = 255;
else if (result_color_comp < 0)
output_image[col*3+1] = 0;
else
output_image[col*3+1] = result_color_comp;
//calculate the resulting blue color component
//for this pixel in the scanline
result_color_comp = start_color_blue + (blue_slope *
normalized_value * blue_delta);
//make sure the color is within 0-255 range
if (result_color_comp > 255)
output_image[col*3+2] = 255;
else if (result_color_comp < 0)
output_image[col*3+2] = 0;
else
output_image[col*3+2] = result_color_comp;
}
//write the pseudo color scanline out to the output file
n_written = fwrite((void *) output_image, sizeof(char),
file_width*3, output_ptr);
if (n_written != file_width*3)
{
fclose(matte_ptr);
fclose(output_ptr);
printf("Unable to write scanline to output file.\n");
exit(1);
}
printf("wrote out image row %d\n", row);
}
//close all the input and output files
fclose(matte_ptr);
fclose(output_ptr);
exit(0);
}
Last Updated: September 2, 1999
HTML URL: http://www.oocities.org/~special_effect/sw_pseudo_colorize.html
E-Mail: special_effect@oocities.com or click here