Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

PGMImg.cc

Go to the documentation of this file.
00001 #include "PGMImg.h"
00002 #include "../SIFTDatabase/keypoint.h"
00003 #include "../SIFTDatabase/keypointpair.h"
00004 #include <cstring>
00005 #include <iostream>
00006 #include <cmath>
00007 #include <cstdlib>
00008 
00009 void PGMImg::setPixel(int x, int y, unsigned char color){
00010   int loc = x+width*y;
00011   if (loc >= 0 && loc < width*height) pixels[x+width*y] = color;
00012 }
00013 
00014 unsigned char PGMImg::getPixel(int x, int y){
00015   int loc = x+width*y;
00016   if (loc >= 0 && loc < width*height) return pixels[x+width*y];
00017   return 0;
00018 }
00019 
00020 PGMImg::PGMImg() : width(0), height(0), base(0), pixels(NULL), filename(), id(0) {}
00021 
00022 void PGMImg::fromFile(std::string imageFilename){
00023   pixels = NULL;
00024   
00025   std::ifstream infile(imageFilename.c_str());
00026   
00027   std::string input;
00028   
00029   infile >> input;
00030   
00031   if (input.compare("P2")){
00032     std::cout << imageFilename << " is not ASCII PGM file\n";
00033   }else{
00034     infile >> input;
00035     while (input[0] == '#'){
00036       getline(infile, input);
00037       infile >> input;
00038     }
00039     width = atoi(input.c_str());
00040     infile >> height;
00041     infile >> base;
00042     
00043     if (base > 255){
00044       std::cout << "Unable to process non 8-bit PGM file\n";
00045     }else{
00046       pixels = (unsigned char*)malloc(sizeof(unsigned char) * width * height);
00047       bzero(pixels, sizeof(pixels));
00048       
00049       int temp;
00050       for (int i = 0; i < height; i++){
00051         for (int j = 0; j < width; j++){
00052           infile >> temp;
00053           setPixel(j, i, (unsigned char)temp);
00054         }
00055       }
00056     }
00057   }
00058   
00059   infile.close();
00060   
00061   filename = imageFilename;
00062 }
00063 
00064 PGMImg::PGMImg(PGMImg* img1, PGMImg* img2, std::vector<keypointPair*>* matches)
00065   : width(0), height(0), base(0), pixels(NULL), filename(), id(0){
00066   if (img1->pixels && img2->pixels){
00067 //    height = (img1->height > img2->height) ? img1->height : img2->height;
00068 //    width = img1->width  + img2->width;
00069     height = img1->height + img2->height;
00070     width = (img1->width > img2->width) ? img1->width : img2->width;
00071     pixels = (unsigned char*)malloc(sizeof(unsigned char) * width * height);
00072     //bzero(pixels, sizeof(pixels));
00073     for (int i = 0; i < height; i++){
00074       for (int j = 0; j < width; j++){
00075         setPixel(j, i, 0);
00076       }
00077     }
00078     base = 255;
00079     
00080     for (int i = 0; i < (int)(*matches).size(); i++){
00081       img1->drawKeypoint((*matches)[i]->getKey2());
00082       img2->drawKeypoint((*matches)[i]->getKey1());
00083     }
00084     
00085     for (int i = 0; i < img1->height; i++){
00086       for (int j = 0; j < img1->width; j++){
00087         setPixel(j, i, img1->getPixel(j,i));
00088       }
00089     }
00090     for (int i = 0; i < img2->height; i++){
00091       for (int j = 0; j < img2->width; j++){
00092         setPixel(j, i+img1->height, img2->getPixel(j,i));
00093       }
00094     }
00095     
00096     for (int i = 0; i < (int)(*matches).size(); i++){
00097       drawLine((int)((*matches)[i]->getKey2()->imageX), (int)((*matches)[i]->getKey2()->imageY), (int)((*matches)[i]->getKey1()->imageX), (int)((*matches)[i]->getKey1()->imageY) + img1->height, 127);
00098     }
00099   }
00100 }
00101 
00102 PGMImg::~PGMImg(){
00103 //  cout << id << " " << (unsigned int)pixels << endl;
00104 //  cout << "checkpoint11\n";
00105   if (pixels) free(pixels);
00106 //  cout << "checkpoint12\n";
00107   pixels = NULL;
00108 //  cout << "checkpoint13\n";
00109 }
00110 
00111 int PGMImg::getHeight(){
00112   return height;
00113 }
00114 
00115 int PGMImg::getWidth(){
00116   return width;
00117 }
00118 
00119 void PGMImg::toFile(std::string imageFilename){
00120   std::ofstream outfile(imageFilename.c_str());
00121 //  std::cout << outfile.good() << outfile.bad() << outfile.fail() << std::endl;
00122   
00123   outfile << "P2\n";
00124   outfile << width << " " << height << std::endl;
00125   outfile << base << std::endl;
00126   
00127   for (int i = 0; i < height; i++){
00128     for (int j = 0; j < width; j++){
00129       char intString[1024];
00130       bzero(intString, sizeof(intString));
00131       outfile << (int)getPixel(j, i) << " ";
00132     }
00133     outfile << std::endl;
00134   }
00135   
00136   outfile.close();
00137 
00138 }
00139 
00140 void PGMImg::drawKeypoint(keypoint* key){
00141   double x, y, scale, orientation;
00142   x = key->imageX;
00143   y = key->imageY;
00144   scale = key->imageScale;
00145   orientation = key->imageOrientation;
00146   double radius = 2.0 * scale;
00147   double centerX = x;
00148   double centerY = y;
00149   double x1 = (x - (radius * std::cos(orientation + (M_PI_4))));
00150   double x2 = (x - (radius * std::cos(orientation + (M_PI_2 + M_PI_4))));
00151   double x3 = (x - (radius * std::cos(orientation - (M_PI_2 + M_PI_4))));
00152   double x4 = (x - (radius * std::cos(orientation - (M_PI_4))));
00153   double y1 = (y - (radius * std::sin(orientation + (M_PI_4))));
00154   double y2 = (y - (radius * std::sin(orientation + (M_PI_2 + M_PI_4))));
00155   double y3 = (y - (radius * std::sin(orientation - (M_PI_2 + M_PI_4))));
00156   double y4 = (y - (radius * std::sin(orientation - (M_PI_4))));
00157   
00158   drawLine((int)(x1), (int)(y1), (int)(x2), (int)(y2), 0);
00159   drawLine((int)(x2), (int)(y2), (int)(x3), (int)(y3), 0);
00160   drawLine((int)(x3), (int)(y3), (int)(x4), (int)(y4), 0);
00161   drawLine((int)(x4), (int)(y4), (int)(x1), (int)(y1), 0);
00162   drawLine((int)((x1 + x4)/2.0), (int)((y1 + y4)/2.0), (int)(centerX), (int)(centerY), 0);
00163   
00164 //  cout << "(" << x << "," << y << ")\n";
00165 //  cout << "(" << (int)x1 << "," << (int)y1 << ")\n";
00166 //  cout << "(" << (int)x2 << "," << (int)y2 << ")\n";
00167 //  cout << "(" << (int)x3 << "," << (int)y3 << ")\n";
00168 //  cout << "(" << (int)x4 << "," << (int)y4 << ")\n";
00169 //  cout << "(" << (int)centerX << "," << (int)centerY << ")\n";
00170 }
00171 
00172 void PGMImg::drawKeypoints(std::vector<keypoint*> keys){
00173   for (int i = 0; i < (int)keys.size(); i++){
00174     drawKeypoint(keys[i]);
00175   }
00176 }
00177 
00178 void PGMImg::drawLine(int x1, int y1, int x2, int y2, unsigned char color){
00179   int dx = x2 - x1;
00180   dx = (dx < 0) ? -dx : dx;
00181   int dy = y2 - y1;
00182   dy = (dy < 0) ? -dy : dy;
00183   
00184 //  cout << "|" << x1 << "-" << x2 << "|=" << dx
00185 //       << "|" << y1 << "-" << y2 << "|=" << dy
00186 //       << endl;
00187   
00188   
00189   if (dx < dy){
00190     if (y1 > y2){
00191       int temp;
00192       temp = x1;
00193       x1 = x2;
00194       x2 = temp;
00195       temp = y1;
00196       y1 = y2;
00197       y2 = temp;
00198     }
00199     double deltax = (double)(x2-x1) / (double)(y2-y1);
00200     
00201 //    cout << "(" << (int)x1 << "," << (int)y1 << ")\n";
00202 //    cout << "(" << (int)x2 << "," << (int)y2 << ")\n";
00203 //    cout << deltax << endl;
00204     
00205     double x = x1 + 0.5;
00206     int y = y1;
00207     for (; y <= y2; y++){
00208       setPixel((int)x, y, color);
00209       x += deltax;
00210     }
00211   }else{
00212     if (x1 > x2){
00213       int temp;
00214       temp = x1;
00215       x1 = x2;
00216       x2 = temp;
00217       temp = y1;
00218       y1 = y2;
00219       y2 = temp;
00220     }
00221     double deltay = (double)(y2-y1) / (double)(x2-x1);
00222     double y = y1 + 0.5;
00223     int x = x1;
00224     for (; x <= x2; x++){
00225       setPixel(x, (int)y, color);
00226       y += deltay;
00227     }
00228   }
00229 }
00230 
00231 void PGMImg::translate(int x, int y, unsigned char color){
00232   int minx, miny, maxx, maxy, newX, newY;
00233   if (x < 0){
00234     minx = x;
00235     maxx = width - 1;
00236     newX = 0;
00237   }else{
00238     minx = 0;
00239     maxx = width + x - 1;
00240     newX = x;
00241   }
00242   if (y < 0){
00243     miny = y;
00244     maxy = height - 1;
00245     newY = 0;
00246   }else{
00247     miny = 0;
00248     maxy = height + y - 1;
00249     newY = y;
00250   }
00251   
00252   int oldWidth  = width;
00253   int oldHeight = height;
00254   
00255   width  = maxx - minx + 1;
00256   height = maxy - miny + 1;
00257   
00258   unsigned char* oldPixels = pixels;
00259   pixels = (unsigned char*)malloc(sizeof(unsigned char) * width * height);
00260   for (int i = 0; i < height; i++){
00261     for (int j = 0; j < width; j++){
00262       setPixel(j, i, color);
00263     }
00264   }
00265   
00266   for (int i = 0; i < oldHeight; i++){
00267     int tempnewX = newX;
00268     for (int j = 0; j < oldWidth; j++){
00269       setPixel(tempnewX, newY, oldPixels[j+oldWidth*i]);
00270       tempnewX++;
00271     }
00272     newY++;
00273   }
00274   
00275   free(oldPixels);
00276 }
00277 
00278 void PGMImg::rotate(double s, unsigned char color){
00279   double centerX, centerY;
00280   
00281   centerX = 0.5 * (double)(width);
00282   centerY = 0.5 * (double)(height);
00283   
00284   unsigned char* oldPixels = pixels;
00285   pixels = (unsigned char*)malloc(sizeof(unsigned char) * width * height);
00286   for (int i = 0; i < height; i++){
00287     for (int j = 0; j < width; j++){
00288       setPixel(j, i, color);
00289     }
00290   }
00291   
00292   for (int i = 0; i < height; i++){
00293     double adjY = centerY - i;
00294     for (int j = 0; j < width; j++){
00295       double adjX = j - centerX;
00296       
00297       if (i == centerY && j == centerX){
00298         setPixel(j, i, oldPixels[(width/2)+width*(height/2)]);
00299         continue;
00300       }
00301       
00302       double h = sqrt(adjX * adjX + adjY * adjY);
00303       double alpha = acos(adjX / h);
00304       if (adjY < 0.0) alpha = acos(-adjX/h) + M_PI;
00305       
00306       double adjXPrime = h * cos(s + alpha);
00307       double adjYPrime = h * sin(s + alpha);
00308       
00309       double xPrime = adjXPrime + centerX;
00310       double yPrime = centerY - adjYPrime;
00311       
00312       int intX = (int)xPrime;
00313       int intY = (int)yPrime;
00314       double px = xPrime - (double)intX;
00315       double py = yPrime - (double)intY;
00316       
00317       double sum = 0.0;
00318       double base1 = 0.0;
00319       
00320       int index;
00321       
00322       index = intX + width * intY;
00323       if (index >= 0 && index < width*height){
00324         sum  += (1-px) * (1-py) * oldPixels[index];
00325         base1 += (1-px) * (1-py);
00326       }
00327       index = (intX+1) + width * intY;
00328       if (index >= 0 && index < width*height){
00329         sum  += px     * (1-py) * oldPixels[index];
00330         base1 += px     * (1-py);
00331       }
00332       index = intX + width * (intY+1);
00333       if (index >= 0 && index < width*height){
00334         sum  += (1-px) * py     * oldPixels[index];
00335         base1 += (1-px) * py;
00336       }
00337       index = (intX+1) + width * (intY+1);
00338       if (index >= 0 && index < width*height){
00339         sum  += px     * py     * oldPixels[index];
00340         base1 += px     * py;
00341       }
00342       
00343 //      if ((unsigned char)(sum/base1+0.5) != oldPixels[j+i*width]) cout << "(" << j << "," << i << ") --> (" << xPrime << "," << yPrime << ") " << px << "," << py << " " << sum << "," << base1 << "," << (sum/base1) << "," << (int)((unsigned char)(sum/base1 +0.5)) << " " << (int)(oldPixels[j+i*width]) << "\n";
00344       
00345       if (base1 != 0.0){
00346         setPixel(j, i, (unsigned char)(sum/base1+0.5));
00347       }
00348 //      setPixel(j, i, (unsigned char)(
00349 //                 px     * py     * oldPixels[smallX + width * smallY]
00350 //               + px     * (1-py) * oldPixels[smallX + width * largeY]
00351 //               + (1-px) * py     * oldPixels[largeX + width * smallY]
00352 //               + (1-px) * (1-py) * oldPixels[largeX + width * largeY]
00353 //              ));
00354     }
00355     
00356   }
00357   
00358 }
00359 
00360 void PGMImg::doubleSize(double s, unsigned char color){
00361   int oldWidth  = width;
00362 //  int oldHeight = height;
00363   
00364   int scaleFactor = 1;
00365   for (int i = 0; i < (int)s; i++){
00366     scaleFactor*= 2;
00367   }
00368   
00369   width  *= scaleFactor;
00370   height *= scaleFactor;
00371   
00372   unsigned char* oldPixels = pixels;
00373   pixels = (unsigned char*)malloc(sizeof(unsigned char) * width * height);
00374   for (int i = 0; i < height; i++){
00375     for (int j = 0; j < width; j++){
00376       setPixel(j, i, oldPixels[(j/scaleFactor)+oldWidth*(i/scaleFactor)]);
00377     }
00378   }
00379   free(oldPixels);
00380 }
00381 
00382 void PGMImg::halfSize(double s, unsigned char color){
00383   int oldWidth  = width;
00384 //  int oldHeight = height;
00385   
00386   int scaleFactor = 1;
00387   for (int i = 0; i < (int)s; i++){
00388     scaleFactor*= 2;
00389   }
00390   
00391   width  /= scaleFactor;
00392   height /= scaleFactor;
00393   
00394   unsigned char* oldPixels = pixels;
00395   pixels = (unsigned char*)malloc(sizeof(unsigned char) * width * height);
00396   for (int i = 0; i < height; i++){
00397     for (int j = 0; j < width; j++){
00398       int sum = 0;
00399       int starti = i * scaleFactor;
00400       int startj = j * scaleFactor;
00401       for (int ii = 0; ii < scaleFactor; ii++){
00402         for (int jj = 0; jj < scaleFactor; jj++){
00403           sum += (int)(oldPixels[(startj+jj)+oldWidth*(starti+ii)]);
00404         }
00405       }
00406       setPixel(j, i, (unsigned char)(sum/(scaleFactor*scaleFactor)));
00407     }
00408   }
00409   free(oldPixels);
00410 }
00411 
00412 void PGMImg::cropImage(int startx, int starty, int endx, int endy, unsigned char color){
00413   int oldWidth  = width;
00414   int oldHeight = height;
00415   
00416   width  = endx - startx + 1;
00417   height = endy - starty + 1;
00418   
00419   unsigned char* oldPixels = pixels;
00420   pixels = (unsigned char*)malloc(sizeof(unsigned char) * width * height);
00421   for (int i = 0; i < height; i++){
00422     for (int j = 0; j < width; j++){
00423       setPixel(j, i, color);
00424     }
00425   }
00426   
00427   int visibleStartX = (startx > 0) ? startx : 0;
00428   int visibleStartY = (starty > 0) ? starty : 0;
00429 
00430   int visibleEndX = (endx > oldWidth  - 1) ? oldWidth  - 1 : endx;
00431   int visibleEndY = (endy > oldHeight - 1) ? oldHeight - 1 : endy;
00432   
00433   for (int i = visibleStartY; i <= visibleEndY; i++){
00434     for (int j = visibleStartX; j <= visibleEndX; j++){
00435 //      cout << "Setting pixel (" << j << "," << i << ")\n";
00436       setPixel(j - startx, i - starty, oldPixels[j+oldWidth*i]);
00437     }
00438   }
00439   
00440   free(oldPixels);
00441   
00442 }

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:45 2016 by Doxygen 1.6.3