#include "slicer.h" //#define DISTFILENAME "dist" /* METRICS */ int LIdistance(long a, long b) { return MAX3( ABS( TORED(a)-TORED(b) ), ABS( TOGREEN(a)-TOGREEN(b) ), ABS( TOBLUE(a)-TOBLUE(b) ) ); } int L1distance(long a, long b) { return ABS( TORED(a)-TORED(b) ) + ABS( TOGREEN(a)-TOGREEN(b) ) + ABS( TOBLUE(a)-TOBLUE(b) ); } int Eucldistance(long a, long b) { return sqrt( SQR( TORED(a)-TORED(b) ) + SQR( TOGREEN(a)-TOGREEN(b) ) + SQR( TOBLUE(a)-TOBLUE(b) ) ); } /* THE SLICER FUNCTION */ Graphics::TBitmap *slicer(int (*newDist)(long, long), AnsiString filNam, double TH, double VTH) { static Graphics::TBitmap *original; static Graphics::TBitmap *processed; static Graphics::TBitmap *distance; static Graphics::TBitmap *output; static int actY, actX; static int (*dist)(long, long); static int hist[800]; static int level; double THval, VTHval, newTHval; /* closing the function usage */ if (!TH && !VTH) { if (original) delete original; if (processed) delete processed; if (distance) delete distance; if (output) delete output; return NULL; } /* change distance function used */ if (newDist) dist = newDist; /* initialize if file name is given */ if (filNam != "") { if (original) delete original; if (processed) delete processed; if (distance) delete distance; if (output) delete output; original = new Graphics::TBitmap(); original -> LoadFromFile(filNam); processed = new Graphics::TBitmap(); distance = new Graphics::TBitmap(); output = new Graphics::TBitmap(); processed->Height = original->Height; distance->Height = original->Height; output->Height = original->Height; processed->Width = original->Width; distance->Width = original->Width; output->Width = original->Width; actY = actX = 0; level = 0; for (int x = 0; x < original->Width; ++x) for (int y = 0; y < original->Height; ++y) processed->Canvas->Pixels[x][y] = 0; } /* looking for the seed pixel and returning NULL if no seed is available*/ while (actY < processed->Height && processed->Canvas->Pixels[actX][actY]) { ++actX; if (actX == processed->Width) { actX = 0; ++actY; } } if (actY == processed->Height) return NULL; //printf("\nSeed coordinates: %i,%i\n", actX, actY); ++level; /* calculation THval and VTHval and resetting the histogram */ THval = dist(0, 0x00FFFFFF)*TH/100; VTHval = original->Height*original->Width*VTH/100; for (int i = 0; i < dist(0, 0x00FFFFFF); ++i) hist[i] = 0; /* creating the distance image and the histogram */ int actDist; long seedColor = original->Canvas->Pixels[actX][actY]; for (int x = 0; x < original->Width; ++x) for (int y = 0; y < original->Height; ++y) { actDist = dist(seedColor, original->Canvas->Pixels[x][y]); distance->Canvas->Pixels[x][y] = actDist; ++hist[actDist]; } // saving the distance image /*{ Graphics::TBitmap *toSave = new Graphics::TBitmap; long c; int maxDist = dist(0, 0x00FFFFFF); toSave->Height = distance->Height; toSave->Width = distance->Width; for (int x = 0; x < toSave->Width; ++x) for (int y = 0; y < toSave->Height; ++y) { c = (double) distance->Canvas->Pixels[x][y] / maxDist * 255; toSave->Canvas->Pixels[x][y] = TOCOLOR(c, c, c); } printf("Saving distance image \tno. %i\tby seed at (%i,%i)\n", level-1, actX, actY); toSave->SaveToFile((AnsiString) DISTFILENAME + (level-1) + ".BMP"); }*/ /* searching for minimal threshold value */ newTHval = THval; { int numofExtr = 0; int extremas[800]; short extrtype[800]; // +1 : max, -1 : min // searching for local extremas if (hist[0] != hist[1]) { ++numofExtr; extremas[0] = 0; if (hist[0] > hist[1]) extrtype[0] = 1; else extrtype[0] = -1; } for (int i = 1; i < THval-1; ++i) { if (hist[i] > hist[i-1] && hist[i] > hist[i+1]) { extremas[numofExtr] = i; extrtype[numofExtr] = 1; ++numofExtr; } else if (hist[i] < hist[i-1] && hist[i] < hist[i+1]) { extremas[numofExtr] = i; extrtype[numofExtr] = -1; ++numofExtr; } } // searching for extrema distances larger than Vertical Threshold for (int i = 0; i < numofExtr && extremas[i] < newTHval; ++i) if (extrtype[i] == 1) for (int j = i+1; j < numofExtr && extremas[j] < newTHval; ++j) if ((extrtype[j] == -1) && (hist[extremas[i]]-hist[extremas[j]] >= VTHval)) newTHval = extremas[j]; } /* thresholding the image */ for (int y = 0; y < distance->Height; ++y) for (int x = 0; x < distance->Width; ++x) if (!processed->Canvas->Pixels[x][y] && distance->Canvas->Pixels[x][y] <= newTHval) { output->Canvas->Pixels[x][y] = 0x00FFFFFF; processed->Canvas->Pixels[x][y] = 1; } else output->Canvas->Pixels[x][y] = 0; /* saving the histogram FILE *fil = fopen(((AnsiString) DISTFILENAME + level + ".TXT").c_str(), "w"); fprintf(fil, "Seed coordinates: ( %i, %i )\n", actX, actY); fprintf(fil, "Seed colour: %x\n\n", original->Canvas->Pixels[actX][actY]); fprintf(fil, "Original THval: %i\n", THval); fprintf(fil, "New THval: %i\n", newTHval); fprintf(fil, "Vertical TH : %i\n\n", VTHval); for (int i = 0; i < dist(0, 0x00FFFFFF); ++i) fprintf(fil, "%i\n", hist[i]); fclose(fil);*/ // marking the seed pixel //output->Canvas->Pixels[actX][actY] = 0x00FF0000; return output; }