
Thread
2005.05.25 13:27 "Re: [Tiff] Help me on convert from TIFF 24 bit or 8 bit grayscale tobilevel image", by Nguyen Anh Tuan
Hello Joris,
Thanks for your reply quickly. You're alright, but right now i have a problem on threshold algorithm. If you can, please help me. Below, this is the my threshold algorithm (convert 8 bit grayscale to one bit image), the result image is very bad.
Best Regards,
Tuan
////////////////////////////////////////////////////////////////////////////
void COmrImage::LoadTIFFImage(TIFF *tif){
this->fname = fname;
unsigned short bitspersample, samplesperpixel;
unsigned short config, photo_interp;
int row;
image_word *dest;
int bpw; // bytes_per_word
float xres, yres;
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &(this->size.cx));
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &(this->size.cy));
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config);
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photo_interp);
TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
if (xres != yres)
AfxMessageBox("Horizontal and vertical resolution must be the same!");
this->resolution = xres;
bpw = sizeof(image_word);
this->w_word = (TIFFScanlineSize(tif) + ((bpw / 2) + 1)) / bpw;
this->offset = 0;
this->origin.x = 0;
this->origin.y = 0;
this->data = (image_word *)malloc(this->w_word * this->size.cy *
sizeof(image_word));
if ((config == PLANARCONFIG_SEPARATE) && (samplesperpixel >= 1))
samplesperpixel -= 1;
dest = this->data;
for (row = 0; row < this->size.cy; row++)
if (TIFFReadScanline(tif, (unsigned char*)dest, row,
(unsigned int)samplesperpixel) == 1) {
dest += this->w_word;
}
if(bitspersample == 8) GreyToMonoImage();
// the result image is not correct
this->SaveTIFFImage("threshold.tif");
}
void COmrImage::GreyToMonoImage()
{
unsigned char *src, max = 0, min = 255, *gnew, mask = 0x80, threshold;
int i, j;
int bitfield = 0, byte = 0, extra = 0;
int w_byte = this->w_word * sizeof(image_word);
// Check if extra bits will be present and add an extra byte if so
if ((w_byte % 8) != 0) extra = 1;
gnew = (unsigned char *)calloc(this->GetSize().cy , ((w_byte / 8) +
extra));
src = (unsigned char *)this->data;
// Using max and min values, determine conversion threshold.
for(i = 0; i < this->size.cy; i++)
{
for (j = 0; j < w_byte; j++)
{
if (src[j] > max)
max = src[j];
if (src[j] < min)
min = src[j];
}
src += w_byte;
}
threshold = (unsigned char)((max+min)/2.2);
src = (unsigned char *)this->data;
for(i = 0; i < this->size.cy; i++)
{
for (j = 0; j < w_byte; j++)
{
if (src[j] >= threshold)
gnew[byte] |= mask;
if (bitfield >= 7)
{
byte++;
bitfield = 0;
mask = 0x80;
}
else
{
mask >>= 1;
bitfield++;
}
}
if (bitfield != 0)
{
byte++;
bitfield = 0;
mask = 0x80;
}
src += w_byte;
}
this->w_word = (this->w_word / 8) + extra;
this->size.cx = this->w_word * BITS_PER_WORD ; //BITS_PER_WORD =32
free(this->data);
this->data = (image_word *)gnew;
}