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
00068
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
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
00104
00105 if (pixels) free(pixels);
00106
00107 pixels = NULL;
00108
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
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
00165
00166
00167
00168
00169
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
00185
00186
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
00202
00203
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
00344
00345 if (base1 != 0.0){
00346 setPixel(j, i, (unsigned char)(sum/base1+0.5));
00347 }
00348
00349
00350
00351
00352
00353
00354 }
00355
00356 }
00357
00358 }
00359
00360 void PGMImg::doubleSize(double s, unsigned char color){
00361 int oldWidth = width;
00362
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
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
00436 setPixel(j - startx, i - starty, oldPixels[j+oldWidth*i]);
00437 }
00438 }
00439
00440 free(oldPixels);
00441
00442 }