/bin/color_indexer/main.cpp

http://hppg.googlecode.com/ · C++ · 212 lines · 140 code · 52 blank · 20 comment · 32 complexity · c22c198292dbbca51bfa25206c6445a1 MD5 · raw file

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <cv.h>
  5. #include <highgui.h>
  6. /**
  7. * Reference
  8. * http://www.compuphase.com/cmetric.htm
  9. */
  10. typedef struct {
  11. unsigned char r, g, b;
  12. } RGB;
  13. double getDistance(RGB e1, RGB e2)
  14. {
  15. long rmean = ( (long)e1.r + (long)e2.r ) / 2;
  16. long r = (long)e1.r - (long)e2.r;
  17. long g = (long)e1.g - (long)e2.g;
  18. long b = (long)e1.b - (long)e2.b;
  19. return sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8));
  20. }
  21. bool pointIsInsideEllipse(int pointToCheckX, int pointToCheckY, int ellipsePosX, int ellipsePosY, int ellipseHeight, int ellipseWidth)
  22. {
  23. double xComponent = (float)(pow((float)pointToCheckX - (float)ellipsePosX, 2.0) / (float)pow((float)ellipseWidth/2, 2.0));
  24. double yComponent = (float)(pow((float)pointToCheckY - (float)ellipsePosY, 2.0) / (float)pow((float)ellipseHeight/2, 2.0));
  25. double value = xComponent + yComponent;
  26. if (value <= 1.0)
  27. return true;
  28. return false;
  29. }
  30. // Our pallete item
  31. typedef struct {
  32. int pallete_id,red,green,blue,count;
  33. } palleteItem;
  34. int main(int argc, char *argv[])
  35. {
  36. IplImage* img = 0;
  37. int height,width,step,channels;
  38. uchar *data;
  39. int i,j,k,treshold,insideHeight,insideWidth;
  40. RGB RGBImage,RGBPallete;
  41. palleteItem palletesp[200];
  42. FILE * filehandle;
  43. char lyne[121];
  44. char *item,*palleteFile,*methodForm;
  45. int reccount = 0;
  46. uchar *aPixelIn, *aPixelOut;
  47. if(argc<4){
  48. printf("Usage: color_indexer <image-file-name> <pallete-file-name> <threshold> <inside_height> <inside_width> <method>\n\7");
  49. exit(0);
  50. }
  51. // Our treshold
  52. treshold = atoi(argv[3]);
  53. // Pallete txt file
  54. palleteFile = argv[2];
  55. // How many percent inside image height pixels
  56. insideHeight = atoi(argv[4]);
  57. // How many percent inside image width pixels
  58. insideWidth = atoi(argv[5]);
  59. // Rectangle or ellipse
  60. methodForm = argv[6];
  61. // load an image
  62. img=cvLoadImage(argv[1]);
  63. if(!img){
  64. printf("Could not load image file: %s\n",argv[1]);
  65. exit(0);
  66. }
  67. /*
  68. * Reference
  69. * http://www.wellho.net/resources/ex.php4?item=c209/lunches.c
  70. */
  71. filehandle = fopen(palleteFile,"r");
  72. /* Read file line by line */
  73. while (fgets(lyne,120,filehandle)) {
  74. item = strtok(lyne,";");
  75. palletesp[reccount].pallete_id = atoi(item);
  76. item = strtok(NULL,";");
  77. palletesp[reccount].red = atoi(item);
  78. item = strtok(NULL,";");
  79. palletesp[reccount].green = atoi(item);
  80. item = strtok(NULL,";");
  81. palletesp[reccount].blue = atoi(item);
  82. palletesp[reccount].count = 0;
  83. reccount++;
  84. }
  85. /* Close file */
  86. fclose(filehandle);
  87. // get the image data
  88. height = img->height;
  89. width = img->width;
  90. int heightOriginal = height;
  91. int widthOriginal = width;
  92. int startI = 0;
  93. int startJ = 0;
  94. step = img->widthStep;
  95. channels = img->nChannels;
  96. data = (uchar *)img->imageData;
  97. //printf("Processing a %dx%d image with %d channels\n",height,width,channels);
  98. aPixelIn = (uchar *)img->imageData;
  99. aPixelOut = (uchar *)img->imageData;
  100. int ellipsePosX = 0,
  101. ellipsePosY = 0,
  102. ellipseHeight = 0,
  103. ellipseWidth = 0;
  104. if (strcmp(methodForm,"ellipse") == 0)
  105. {
  106. ellipsePosX = (int)((float)widthOriginal/2);
  107. ellipsePosY = (int)((float)heightOriginal/2);
  108. if (insideHeight != 100) {
  109. height = (int)(height * ((float)insideHeight / 100));
  110. startI = (int)((float)(heightOriginal - height) / 2);
  111. }
  112. if (insideWidth != 100) {
  113. width = (int)(width * ((float)insideWidth / 100));
  114. startJ = (int)((float)(widthOriginal - width) / 2);
  115. }
  116. ellipseHeight = height;
  117. ellipseWidth = width;
  118. } else {
  119. if (insideHeight != 100) {
  120. height = (int)(height * ((float)insideHeight / 100));
  121. startI = (int)((float)(heightOriginal - height) / 2);
  122. }
  123. if (insideWidth != 100) {
  124. width = (int)(width * ((float)insideWidth / 100));
  125. startJ = (int)((float)(widthOriginal - width) / 2);
  126. }
  127. }
  128. for(i=0;i<heightOriginal;i++) {
  129. for(j=0;j<widthOriginal;j++) {
  130. if ( (strcmp(methodForm,"rectangle") == 0 && i < height+startI && i > startI && j > startJ && j<width+startJ) || (strcmp(methodForm,"ellipse") == 0 && pointIsInsideEllipse(j, i, ellipsePosX, ellipsePosY, ellipseHeight, ellipseWidth) == true )) {
  131. int R, B, G, currentPalleteKey = 0;
  132. double minimumdistance = -1,currentDistance = 0;
  133. B = aPixelIn[ i * img->widthStep + j * 3 + 0 ];
  134. G = aPixelIn[ i * img->widthStep + j * 3 + 1 ];
  135. R = aPixelIn[ i * img->widthStep + j * 3 + 2 ];
  136. RGBImage.r = (char)R;
  137. RGBImage.g = (char)G;
  138. RGBImage.b = (char)B;
  139. for (k=0; k<reccount; k++) {
  140. RGBPallete.r = palletesp[k].red;
  141. RGBPallete.g = palletesp[k].green;
  142. RGBPallete.b = palletesp[k].blue;
  143. currentDistance = getDistance(RGBImage,RGBPallete);
  144. if (minimumdistance < 0 || minimumdistance > currentDistance){
  145. minimumdistance = currentDistance;
  146. currentPalleteKey = k;
  147. }
  148. }
  149. palletesp[currentPalleteKey].count++;
  150. }
  151. }
  152. }
  153. for (k=0; k<reccount; k++) {
  154. if (palletesp[k].count > treshold)
  155. printf("%d-%d\n",palletesp[k].pallete_id,palletesp[k].count);
  156. }
  157. // release the image
  158. cvReleaseImage(&img );
  159. return 0;
  160. }