00001 #include "SiftTekkotsu.h"
00002 #include "DualCoding/Sketch.h"
00003 #include "Shared/newmat/newmat.h"
00004 #include "Shared/mathutils.h"
00005
00006 #include "SiftMatch.h"
00007 #include "Vision/SIFT/SIFTDatabase/keypoint.h"
00008 #include "Vision/SIFT/SIFTDatabase/keypointpair.h"
00009 #include "Vision/SIFT/SIFTDatabase/model.h"
00010 #include "Vision/SIFT/SIFTDatabase/object.h"
00011 #include "Vision/SIFT/SIFTPP/sift.hpp"
00012 #include "Vision/SIFT/SIFTPP/sift-driver.hpp"
00013
00014 #include <cstring>
00015
00016 using namespace std;
00017 using namespace DualCoding;
00018
00019 SiftTekkotsu::SiftTekkotsu() : kb(), imageDatabase(), testSIFTImage(), siftImageMaxID(0),
00020 argv(new char*[20]), argvCopy(argv), argc(7) {
00021 argv[0] = new char[1024];
00022 argv[1] = new char[1024];
00023 argv[2] = new char[1024];
00024 argv[3] = new char[1024];
00025 argv[4] = new char[1024];
00026 argv[5] = new char[1024];
00027 argv[6] = new char[1024];
00028 }
00029
00030 SiftTekkotsu::~SiftTekkotsu(){
00031 argv = argvCopy;
00032 for (int i = 0; i < argc; i++)
00033 delete [] argv[i];
00034
00035 delete [] argv;
00036
00037 for (unsigned int i = 0; i < imageDatabase.size(); i++){
00038 imageDatabase[i]->clearImage();
00039 delete imageDatabase[i];
00040 }
00041
00042 clearTestState();
00043 }
00044
00045 void SiftTekkotsu::detectKeypoints(ImageBuffer buffer, vector<keypoint*>& keys, vector< vector< vector<int> > >& gaussianSpace){
00046
00047
00048 vector<double> keyValues;
00049 int numKeypoints;
00050
00051 numKeypoints = 0;
00052
00053 strcpy(argv[0], "siftpp");
00054
00055 strcpy(argv[1], "bogusImage");
00056 strcpy(argv[2], "-o");
00057 strcpy(argv[3], "/tmp/siftTekkotsu.key");
00058 strcpy(argv[4], "--image-provided");
00059 strcpy(argv[5], "--verbose");
00060 strcpy(argv[6], "--save-gss");
00061
00062 VL::pixel_t* tempPixelArray = (VL::pixel_t*)malloc(sizeof(float) * buffer.width * buffer.height);
00063 int tempPixelArrayPtr = 0;
00064 for (int i = 0; i < buffer.height; i++){
00065 for (int j = 0; j < buffer.width; j++){
00066 tempPixelArray[tempPixelArrayPtr] = buffer.byteArray[tempPixelArrayPtr] / 255.f;
00067 tempPixelArrayPtr++;
00068 }
00069 }
00070 VL::Sift* sift = siftdriver(5, argv, &numKeypoints, &keyValues, gaussianSpace, tempPixelArray, buffer.width, buffer.height);
00071 free(tempPixelArray);
00072
00073 delete sift;
00074
00075
00076
00077 for (int i = 0; i < numKeypoints; i++){
00078 int j = i * (128+6);
00079 keypoint* key = new keypoint();
00080
00081 key->imageX = key->modelX = keyValues[j++];
00082 key->imageY = key->modelY = keyValues[j++];
00083 key->imageScale = key->modelScale = keyValues[j++];
00084 key->imageOrientation = key->modelOrientation = keyValues[j++];
00085 key->imageIntScale = (int)keyValues[j++];
00086 key->imageIntOctave = (int)keyValues[j++];
00087 for (int jj = 0; jj < 128; jj++){
00088 key->desc.push_back(keyValues[j+jj]);
00089 }
00090 keys.push_back(key);
00091 }
00092
00093 }
00094
00095 void SiftTekkotsu::findInImage(ImageBuffer buffer, vector<SiftMatch*>& matchesFound, bool objectSpecified, int wantedObjectID){
00096 clearTestState();
00097 testSIFTImage.buffer.width = buffer.width;
00098 testSIFTImage.buffer.height = buffer.height;
00099 testSIFTImage.buffer.byteArray = (unsigned char*)malloc(buffer.width*buffer.height*sizeof(unsigned char));
00100 memcpy(testSIFTImage.buffer.byteArray, buffer.byteArray, buffer.width*buffer.height*sizeof(unsigned char));
00101 detectKeypoints(buffer, testSIFTImage.keypoints, testSIFTImage.gaussianSpace);
00102 findInImage(testSIFTImage.keypoints, matchesFound, objectSpecified, wantedObjectID);
00103 }
00104
00105 void SiftTekkotsu::findInImage(vector<keypoint*>& keys, vector<SiftMatch*>& matchesFound, bool objectSpecified, int wantedObjectID){
00106
00107 size_t objectsSize = kb.objects.size();
00108 size_t maxNumModels1 = kb.maxNumModels+1;
00109 vector< vector< vector<keypoint*> > > matches;
00110 matches.resize(objectsSize);
00111 for (size_t i = 0; i < objectsSize; i++){
00112 matches[i].resize(maxNumModels1);
00113 }
00114 vector< vector< vector<keypoint*> > > imageKey;
00115 imageKey.resize(objectsSize);
00116 for (size_t i = 0; i < objectsSize; i++){
00117 imageKey[i].resize(maxNumModels1);
00118 }
00119 kb.keypointMatching(&keys, matches, imageKey, objectSpecified, wantedObjectID);
00120
00121
00122 vector<KnowledgeBase::modelMatchingInfo*> mminfo;
00123 kb.modelMatching(keys.size(), matches, imageKey, mminfo);
00124
00125 if (mminfo.size() > 0){
00126 for (int i = 0; i < (int)mminfo[0]->inliers->size(); i++){
00127 (*(mminfo[0]->inliers))[i]->getKey1()->finalMatch = (*(mminfo[0]->inliers))[i]->getKey2();
00128 if ((*(mminfo[0]->inliers))[i]->getKey2() != NULL) (*(mminfo[0]->inliers))[i]->getKey2()->matches.push_back((*(mminfo[0]->inliers))[i]->getKey1());
00129 }
00130 }
00131
00132
00133 for (unsigned int i = 0; i < mminfo.size(); i++){
00134 SiftMatch *sMatch = new SiftMatch;
00135 convertSiftMatchFromModelMatchingInfo(*sMatch, *(mminfo[i]));
00136 matchesFound.push_back(sMatch);
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 for (unsigned int i = 0; i < mminfo.size(); i++){
00148 delete mminfo[i];
00149 }
00150
00151 }
00152
00153 void SiftTekkotsu::clearTestState(){
00154 testSIFTImage.clearImage();
00155 for (unsigned int i = 0; i < testSIFTImage.keypoints.size(); i++){
00156 if (testSIFTImage.keypoints[i]->finalMatch != NULL){
00157 for (vector<keypoint*>::iterator iter = testSIFTImage.keypoints[i]->finalMatch->matches.begin(); iter != testSIFTImage.keypoints[i]->finalMatch->matches.end(); iter++){
00158 if (*iter == testSIFTImage.keypoints[i]){
00159 testSIFTImage.keypoints[i]->finalMatch->matches.erase(iter);
00160 break;
00161 }
00162 }
00163 }
00164 delete testSIFTImage.keypoints[i];
00165 }
00166 testSIFTImage.keypoints.clear();
00167 testSIFTImage.gaussianSpace.clear();
00168 testSIFTImage.clearImage();
00169 }
00170
00171 void SiftTekkotsu::convertSiftMatchFromModelMatchingInfo(SiftMatch& sMatch, KnowledgeBase::modelMatchingInfo& mminfo){
00172 NEWMAT::Matrix* transform = mminfo.solution;
00173
00174
00175 double scale = sqrt((*transform)(1,1) * (*transform)(1,1) + (*transform)(2,1) * (*transform)(2,1));
00176 double recoveredCos = (*transform)(1,1) / scale;
00177 double theta = acos(max(-1.0, min(1.0, recoveredCos)));
00178 double tx = (*transform)(3,1);
00179 double ty = (*transform)(4,1);
00180
00181 if (isnan(theta)) theta = 0.0;
00182 if ((*transform)(2,1) / scale < 0.0) theta = -theta;
00183
00184
00185
00186
00187
00188 sMatch.objectID = mminfo.matchedModel->O->getID();
00189 sMatch.objectName = mminfo.matchedModel->O->getName();
00190 sMatch.modelID = mminfo.matchedModel->getID();
00191 sMatch.modelName = mminfo.matchedModel->getName();
00192 sMatch.probOfMatch = mminfo.probOfMatch;
00193 sMatch.error = mminfo.error;
00194 sMatch.scale = scale;
00195 sMatch.orientation = theta;
00196 sMatch.columnTranslation = tx;
00197 sMatch.rowTranslation = ty;
00198 for (vector<keypointPair*>::const_iterator it = mminfo.inliers->begin();
00199 it != mminfo.inliers->end(); it++ )
00200 sMatch.inliers.push_back(*(*it));
00201
00202 sMatch.computeBoundingBox();
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212 int SiftTekkotsu::train_addNewObject(string PGMFileName){
00213 unsigned int siftImageID;
00214 return train_addNewObject(PGMFileName, siftImageID);
00215 }
00216 int SiftTekkotsu::train_removeObject(string PGMFileName, int oID){
00217 unsigned int siftImageID;
00218 return train_removeObject(PGMFileName, siftImageID, oID);
00219 }
00220 int SiftTekkotsu::train_addNewObject(string PGMFileName, unsigned int& siftImageID){
00221 ImageBuffer buffer;
00222 PGMImg pgmImg;
00223 pgmImg.fromFile(PGMFileName);
00224 convertPGMImgToImageBuffer(pgmImg, buffer);
00225
00226 int returnVal = train_addNewObject(buffer, siftImageID);
00227 free(buffer.byteArray);
00228 return returnVal;
00229 }
00230 int SiftTekkotsu::train_removeObject(string PGMFileName, unsigned int& siftImageID, int oID){
00231 ImageBuffer buffer;
00232 PGMImg pgmImg;
00233 pgmImg.fromFile(PGMFileName);
00234 convertPGMImgToImageBuffer(pgmImg, buffer);
00235
00236 int returnVal = train_removeObject(buffer, siftImageID, oID);
00237 free(buffer.byteArray);
00238 return returnVal;
00239 }
00240 int SiftTekkotsu::train_addNewObject(ImageBuffer buffer){
00241 unsigned int siftImageID;
00242 return train_addNewObject(buffer, siftImageID);
00243 }
00244 int SiftTekkotsu::train_removeObject(ImageBuffer buffer, int oID){
00245 unsigned int siftImageID;
00246 return train_removeObject(buffer, siftImageID, oID);
00247 }
00248
00249 int SiftTekkotsu::train_addNewObject(ImageBuffer buffer, unsigned int& siftImageID){
00250
00251 SIFTImage* sImage = new SIFTImage(siftImageMaxID++);
00252
00253 siftImageID = siftImageMaxID-1;
00254 imageDatabase.push_back(sImage);
00255 sImage->buffer.width = buffer.width;
00256 sImage->buffer.height = buffer.height;
00257 sImage->buffer.byteArray = (unsigned char*)malloc(buffer.width*buffer.height*sizeof(unsigned char));
00258 memcpy(sImage->buffer.byteArray, buffer.byteArray, buffer.width*buffer.height*sizeof(unsigned char));
00259 detectKeypoints(buffer, sImage->keypoints, sImage->gaussianSpace);
00260 return train_addNewObject(sImage->keypoints);
00261 }
00262 int SiftTekkotsu::train_removeObject(ImageBuffer buffer, unsigned int& siftImageID, int oID){
00263
00264 SIFTImage* sImage = new SIFTImage(siftImageMaxID++);
00265
00266 siftImageID = siftImageMaxID-1;
00267 imageDatabase.push_back(sImage);
00268 sImage->buffer.width = buffer.width;
00269 sImage->buffer.height = buffer.height;
00270 sImage->buffer.byteArray = (unsigned char*)malloc(buffer.width*buffer.height*sizeof(unsigned char));
00271 memcpy(sImage->buffer.byteArray, buffer.byteArray, buffer.width*buffer.height*sizeof(unsigned char));
00272 detectKeypoints(buffer, sImage->keypoints, sImage->gaussianSpace);
00273 return train_removeObject(sImage->keypoints, oID);
00274 }
00275 int SiftTekkotsu::train_addNewObject(vector<keypoint*>& keys){
00276 return (kb.learn_newObject(&keys))->getID();
00277 }
00278 int SiftTekkotsu::train_removeObject(vector<keypoint*>& keys, int oID){
00279 return (kb.unlearn_Object(&keys, oID))->getID();
00280 }
00281
00282
00283
00284 int SiftTekkotsu::train_addToObject(int objectID, string PGMFileName){
00285 unsigned int siftImageID;
00286 SiftMatch matchFound;
00287 return train_addToObject(objectID, PGMFileName, siftImageID, matchFound);
00288 }
00289 int SiftTekkotsu::train_removefromObject(int objectID, string PGMFileName) {
00290 cout << "Call recieved by siftTekkotsu...";
00291 unsigned int siftImageID;
00292 SiftMatch matchFound;
00293 return train_removefromObject(objectID, PGMFileName, siftImageID, matchFound);
00294 }
00295 int SiftTekkotsu::train_addToObject(int objectID, string PGMFileName, unsigned int& siftImageID, SiftMatch& matchFound){
00296 ImageBuffer buffer;
00297 PGMImg pgmImg;
00298 pgmImg.fromFile(PGMFileName);
00299 convertPGMImgToImageBuffer(pgmImg, buffer);
00300
00301 int returnVal = train_addToObject(objectID, buffer, siftImageID, matchFound);
00302 free(buffer.byteArray); return returnVal;
00303 }
00304 int SiftTekkotsu::train_removefromObject(int objectID, string PGMFileName, unsigned int& siftImageID, SiftMatch& matchFound){
00305 ImageBuffer buffer;
00306 PGMImg pgmImg;
00307 pgmImg.fromFile(PGMFileName);
00308 convertPGMImgToImageBuffer(pgmImg, buffer);
00309
00310 int returnVal = train_removefromObject(objectID, buffer, siftImageID, matchFound);
00311 free(buffer.byteArray); return returnVal;
00312 }
00313 int SiftTekkotsu::train_addToObject(int objectID, ImageBuffer buffer){
00314 unsigned int siftImageID;
00315 SiftMatch matchFound;
00316 return train_addToObject(objectID, buffer, siftImageID, matchFound);
00317 }
00318 int SiftTekkotsu::train_removefromObject(int objectID, ImageBuffer buffer){
00319 unsigned int siftImageID;
00320 SiftMatch matchFound;
00321 return train_removefromObject(objectID, buffer, siftImageID, matchFound);
00322 }
00323
00324 int SiftTekkotsu::train_addToObject(int objectID, ImageBuffer buffer, unsigned int& siftImageID, SiftMatch& matchFound){
00325 object* wantedObject = kb.objectExists(objectID);
00326 if (!wantedObject) return -1;
00327
00328
00329 SIFTImage* sImage = new SIFTImage(siftImageMaxID++);
00330
00331 siftImageID = siftImageMaxID-1;
00332 imageDatabase.push_back(sImage);
00333 sImage->buffer.width = buffer.width;
00334 sImage->buffer.height = buffer.height;
00335 sImage->buffer.byteArray = (unsigned char*)malloc(buffer.width*buffer.height*sizeof(unsigned char));
00336 memcpy(sImage->buffer.byteArray, buffer.byteArray, buffer.width*buffer.height*sizeof(unsigned char));
00337 detectKeypoints(buffer, sImage->keypoints, sImage->gaussianSpace);
00338 return train_addToObject(objectID, sImage->keypoints, wantedObject, matchFound);
00339 }
00340 int SiftTekkotsu::train_removefromObject(int objectID, ImageBuffer buffer, unsigned int& siftImageID, SiftMatch& matchFound){
00341 object* wantedObject = kb.objectExists(objectID);
00342 if (!wantedObject) return -1;
00343
00344
00345 SIFTImage* sImage = new SIFTImage(siftImageMaxID++);
00346
00347 siftImageID = siftImageMaxID-1;
00348 imageDatabase.push_back(sImage);
00349 sImage->buffer.width = buffer.width;
00350 sImage->buffer.height = buffer.height;
00351 sImage->buffer.byteArray = (unsigned char*)malloc(buffer.width*buffer.height*sizeof(unsigned char));
00352 memcpy(sImage->buffer.byteArray, buffer.byteArray, buffer.width*buffer.height*sizeof(unsigned char));
00353 detectKeypoints(buffer, sImage->keypoints, sImage->gaussianSpace);
00354 return train_removefromObject(objectID, sImage->keypoints, wantedObject, matchFound);;
00355 }
00356 int SiftTekkotsu::train_addToObject(int , vector<keypoint*>& keys, object* wantedObject, SiftMatch& matchFound){
00357
00358 size_t objectsSize = kb.objects.size();
00359 size_t maxNumModels1 = kb.maxNumModels+1;
00360 vector< vector< vector<keypoint*> > > matches;
00361 matches.resize(objectsSize);
00362 for (size_t i = 0; i < objectsSize; i++){
00363 matches[i].resize(maxNumModels1);
00364 }
00365 vector< vector< vector<keypoint*> > > imageKey;
00366 imageKey.resize(objectsSize);
00367 for (size_t i = 0; i < objectsSize; i++){
00368 imageKey[i].resize(maxNumModels1);
00369 }
00370 kb.keypointMatching(&keys, matches, imageKey, false, -1);
00371
00372
00373 vector<KnowledgeBase::modelMatchingInfo*> mminfo;
00374 kb.modelMatching(keys.size(), matches, imageKey, mminfo);
00375
00376
00377 int bestModelIndex = -1;
00378 model* bestModel = NULL;
00379 double bestError = numeric_limits<double>::infinity();
00380 for (unsigned int i = 0; i < mminfo.size(); i++){
00381 if (mminfo[i]->matchedModel->O == wantedObject){
00382 bestModelIndex = (int)i;
00383 bestModel = mminfo[i]->matchedModel;
00384 bestError = mminfo[i]->error;
00385 break;
00386 }
00387 }
00388 if (bestModelIndex != -1){
00389 for (int i = 0; i < (int)mminfo[bestModelIndex]->inliers->size(); i++){
00390 (*(mminfo[bestModelIndex]->inliers))[i]->getKey1()->finalMatch = (*(mminfo[bestModelIndex]->inliers))[i]->getKey2();
00391 if ((*(mminfo[bestModelIndex]->inliers))[i]->getKey2() != NULL) (*(mminfo[bestModelIndex]->inliers))[i]->getKey2()->matches.push_back((*(mminfo[bestModelIndex]->inliers))[i]->getKey1());
00392 }
00393 }
00394
00395 double threshold = 0.01 * MAXIMAGEDIM;
00396
00397 if (bestModel == NULL || bestError > threshold ){
00398
00399 bestModel = kb.learn_newModel(&keys, wantedObject, mminfo);
00400 matchFound.objectID = bestModel->O->getID();
00401 matchFound.modelID = bestModel->getID();
00402 matchFound.probOfMatch = 1.0;
00403 matchFound.error = 0;
00404 matchFound.scale = 1.0;
00405 matchFound.orientation = 0;
00406 matchFound.columnTranslation = 0;
00407 matchFound.rowTranslation = 0;
00408 }else{
00409
00410 kb.learn_toModel(&keys, bestModel, mminfo[bestModelIndex]->solution);
00411
00412 convertSiftMatchFromModelMatchingInfo(matchFound, *(mminfo[bestModelIndex]));
00413 }
00414
00415
00416 for (unsigned int i = 0; i < mminfo.size(); i++){
00417 delete mminfo[i];
00418 }
00419
00420 return bestModel->getID();
00421 }
00422 int SiftTekkotsu::train_removefromObject(int , vector<keypoint*>& keys, object* wantedObject, SiftMatch& matchFound){
00423
00424 cout << "Final siftTekkotsu function called... \n";
00425 size_t objectsSize = kb.objects.size();
00426 size_t maxNumModels1 = kb.maxNumModels+1;
00427 vector< vector< vector<keypoint*> > > matches;
00428 matches.resize(objectsSize);
00429 for (size_t i = 0; i < objectsSize; i++){
00430 matches[i].resize(maxNumModels1);
00431 }
00432 vector< vector< vector<keypoint*> > > imageKey;
00433 imageKey.resize(objectsSize);
00434 for (size_t i = 0; i < objectsSize; i++){
00435 imageKey[i].resize(maxNumModels1);
00436 }
00437 kb.keypointMatching(&keys, matches, imageKey, false, -1);
00438
00439
00440 vector<KnowledgeBase::modelMatchingInfo*> mminfo;
00441 kb.modelMatching(keys.size(), matches, imageKey, mminfo);
00442
00443
00444 int bestModelIndex = -1;
00445 model* bestModel = NULL;
00446 double bestError = numeric_limits<double>::infinity();
00447 for (unsigned int i = 0; i < mminfo.size(); i++){
00448 if (mminfo[i]->matchedModel->O == wantedObject){
00449 bestModelIndex = (int)i;
00450 bestModel = mminfo[i]->matchedModel;
00451 bestError = mminfo[i]->error;
00452 break;
00453 }
00454 }
00455 if (bestModelIndex != -1){
00456 for (int i = 0; i < (int)mminfo[bestModelIndex]->inliers->size(); i++){
00457 (*(mminfo[bestModelIndex]->inliers))[i]->getKey1()->finalMatch = (*(mminfo[bestModelIndex]->inliers))[i]->getKey2();
00458 if ((*(mminfo[bestModelIndex]->inliers))[i]->getKey2() != NULL) (*(mminfo[bestModelIndex]->inliers))[i]->getKey2()->matches.push_back((*(mminfo[bestModelIndex]->inliers))[i]->getKey1());
00459 }
00460 }
00461
00462 double threshold = 0.01 * MAXIMAGEDIM;
00463
00464 if (bestModel == NULL || bestError > threshold ){
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 }else{
00476
00477 cout << "Calling unlearn in Knowledge Base \n";
00478 kb.unlearn_fromModel(&keys, bestModel, mminfo[bestModelIndex]->solution);
00479
00480 convertSiftMatchFromModelMatchingInfo(matchFound, *(mminfo[bestModelIndex]));
00481 }
00482
00483
00484 for (unsigned int i = 0; i < mminfo.size(); i++){
00485 delete mminfo[i];
00486 }
00487 return 0;
00488
00489 }
00490
00491
00492
00493
00494 int SiftTekkotsu::train_addNewModel(int objectID, string PGMFileName){
00495 unsigned int siftImageID;
00496 return train_addNewModel(objectID, PGMFileName, siftImageID);
00497 }
00498 int SiftTekkotsu::train_removeModel(int objectID, string PGMFileName, int mID){
00499 unsigned int siftImageID;
00500 return train_removeModel(objectID, PGMFileName, siftImageID, mID);
00501 }
00502 int SiftTekkotsu::train_addNewModel(int objectID, string PGMFileName, unsigned int& siftImageID){
00503 ImageBuffer buffer;
00504 PGMImg pgmImg;
00505 pgmImg.fromFile(PGMFileName);
00506 convertPGMImgToImageBuffer(pgmImg, buffer);
00507
00508 int returnVal = train_addNewModel(objectID, buffer, siftImageID);
00509 free(buffer.byteArray);
00510 return returnVal;
00511 }
00512 int SiftTekkotsu::train_removeModel(int objectID, string PGMFileName, unsigned int& siftImageID, int mID){
00513 ImageBuffer buffer;
00514 PGMImg pgmImg;
00515 pgmImg.fromFile(PGMFileName);
00516 convertPGMImgToImageBuffer(pgmImg, buffer);
00517
00518 int returnVal = train_removeModel(objectID, buffer, siftImageID, mID);
00519 free(buffer.byteArray);
00520 return returnVal;
00521 }
00522 int SiftTekkotsu::train_addNewModel(int objectID, ImageBuffer buffer){
00523 unsigned int siftImageID;
00524 return train_addNewModel(objectID, buffer, siftImageID);
00525 }
00526 int SiftTekkotsu::train_removeModel(int objectID, ImageBuffer buffer, int mID){
00527 unsigned int siftImageID;
00528 return train_removeModel(objectID, buffer, siftImageID, mID);
00529 }
00530 int SiftTekkotsu::train_addNewModel(int objectID, ImageBuffer buffer, unsigned int& siftImageID){
00531 object* wantedObject = kb.objectExists(objectID);
00532 if (!wantedObject) return -1;
00533
00534
00535 SIFTImage* sImage = new SIFTImage(siftImageMaxID++);
00536
00537 siftImageID = siftImageMaxID-1;
00538 imageDatabase.push_back(sImage);
00539 sImage->buffer.width = buffer.width;
00540 sImage->buffer.height = buffer.height;
00541 sImage->buffer.byteArray = (unsigned char*)malloc(buffer.width*buffer.height*sizeof(unsigned char));
00542 memcpy(sImage->buffer.byteArray, buffer.byteArray, buffer.width*buffer.height*sizeof(unsigned char));
00543 detectKeypoints(buffer, sImage->keypoints, sImage->gaussianSpace);
00544 return train_addNewModel(objectID, sImage->keypoints, wantedObject);
00545 }
00546 int SiftTekkotsu::train_removeModel(int objectID, ImageBuffer buffer, unsigned int& siftImageID, int mID){
00547 object* wantedObject = kb.objectExists(objectID);
00548 if (!wantedObject) return -1;
00549
00550
00551 SIFTImage* sImage = new SIFTImage(siftImageMaxID++);
00552
00553 siftImageID = siftImageMaxID-1;
00554 imageDatabase.push_back(sImage);
00555 sImage->buffer.width = buffer.width;
00556 sImage->buffer.height = buffer.height;
00557 sImage->buffer.byteArray = (unsigned char*)malloc(buffer.width*buffer.height*sizeof(unsigned char));
00558 memcpy(sImage->buffer.byteArray, buffer.byteArray, buffer.width*buffer.height*sizeof(unsigned char));
00559 detectKeypoints(buffer, sImage->keypoints, sImage->gaussianSpace);
00560 return train_removeModel(objectID, sImage->keypoints, wantedObject, mID);
00561 }
00562 int SiftTekkotsu::train_addNewModel(int , vector<keypoint*>& keys, object* wantedObject){
00563
00564 size_t objectsSize = kb.objects.size();
00565 size_t maxNumModels1 = kb.maxNumModels+1;
00566 vector< vector< vector<keypoint*> > > matches;
00567 matches.resize(objectsSize);
00568 for (size_t i = 0; i < objectsSize; i++){
00569 matches[i].resize(maxNumModels1);
00570 }
00571 vector< vector< vector<keypoint*> > > imageKey;
00572 imageKey.resize(objectsSize);
00573 for (size_t i = 0; i < objectsSize; i++){
00574 imageKey[i].resize(maxNumModels1);
00575 }
00576 kb.keypointMatching(&keys, matches, imageKey, false, -1);
00577
00578
00579
00580 vector<KnowledgeBase::modelMatchingInfo*> mminfo;
00581 kb.modelMatching(keys.size(), matches, imageKey, mminfo);
00582
00583
00584 int modelID = (kb.learn_newModel(&keys, wantedObject, mminfo))->getID();
00585
00586
00587 for (unsigned int i = 0; i < mminfo.size(); i++){
00588 delete mminfo[i];
00589 }
00590
00591 return modelID;
00592
00593 }
00594 int SiftTekkotsu::train_removeModel(int , vector<keypoint*>& keys, object* wantedObject, int mID){
00595
00596 cout << "kill me \n";
00597 size_t objectsSize = kb.objects.size();
00598 size_t maxNumModels1 = kb.maxNumModels+1;
00599 vector< vector< vector<keypoint*> > > matches;
00600 matches.resize(objectsSize);
00601 for (size_t i = 0; i < objectsSize; i++){
00602 matches[i].resize(maxNumModels1);
00603 }
00604 vector< vector< vector<keypoint*> > > imageKey;
00605 imageKey.resize(objectsSize);
00606 for (size_t i = 0; i < objectsSize; i++){
00607 imageKey[i].resize(maxNumModels1);
00608 }
00609 kb.keypointMatching(&keys, matches, imageKey, false, -1);
00610
00611
00612
00613 vector<KnowledgeBase::modelMatchingInfo*> mminfo;
00614 kb.modelMatching(keys.size(), matches, imageKey, mminfo);
00615
00616
00617 cout << "Removing model...";
00618 int modelID = (kb.unlearn_Model(&keys, wantedObject, mminfo, mID))->getID();
00619
00620
00621 for (unsigned int i = 0; i < mminfo.size(); i++){
00622 delete mminfo[i];
00623 }
00624
00625 return modelID;
00626
00627 }
00628
00629
00630
00631
00632
00633 void SiftTekkotsu::findObjectInImage(int objectID, string PGMFileName, vector<SiftMatch*>& matchesFound){
00634 ImageBuffer buffer;
00635 PGMImg pgmImg;
00636 pgmImg.fromFile(PGMFileName);
00637 convertPGMImgToImageBuffer(pgmImg, buffer);
00638
00639 findObjectInImage(objectID, buffer, matchesFound);
00640 free(buffer.byteArray);
00641 }
00642 void SiftTekkotsu::findObjectInImage(int objectID, ImageBuffer buffer, vector<SiftMatch*>& matchesFound){
00643 if (!kb.objectExists(objectID)) return;
00644
00645 findInImage(buffer, matchesFound, true, objectID);
00646 }
00647
00648
00649
00650 void SiftTekkotsu::findAllObjectsInImage(string PGMFileName, vector<SiftMatch*>& matchesFound){
00651 ImageBuffer buffer;
00652 PGMImg pgmImg;
00653 pgmImg.fromFile(PGMFileName);
00654 convertPGMImgToImageBuffer(pgmImg, buffer);
00655
00656 findAllObjectsInImage(buffer, matchesFound);
00657 free(buffer.byteArray);
00658 }
00659
00660 void SiftTekkotsu::findAllObjectsInImage(ImageBuffer buffer, vector<SiftMatch*>& matchesFound){
00661 findInImage(buffer, matchesFound, false, -1);
00662 }
00663
00664
00665
00666
00667
00668
00669 bool SiftTekkotsu::setObjectName(int objectID, string Name){
00670
00671 object* O = kb.objectExists(objectID);
00672 if (!O) return false;
00673
00674
00675 if (getObjectID(Name) != -1) return false;
00676
00677 O->setName(Name);
00678
00679 return true;
00680 }
00681
00682 string SiftTekkotsu::getObjectName(int objectID){
00683
00684 object* O = kb.objectExists(objectID);
00685 if (!O) {
00686 return "";
00687 }
00688
00689 return O->getName();
00690 }
00691
00692 int SiftTekkotsu::getObjectID(string Name){
00693 for (unsigned int i = 0; i < kb.objects.size(); i++){
00694 if (kb.objects[i]->getName().compare(Name) == 0){
00695 return (int)i;
00696 }
00697 }
00698 return -1;
00699 }
00700
00701
00702 bool SiftTekkotsu::setModelName(int objectID, int modelID, string Name){
00703
00704 object* O = kb.objectExists(objectID);
00705 if (!O) return false;
00706
00707
00708 model* M = O->modelExists(modelID);
00709 if (!M) return false;
00710
00711
00712 if (getModelID(objectID, Name) != -1) return false;
00713
00714 M->setName(Name);
00715
00716 return true;
00717 }
00718
00719 string SiftTekkotsu::getModelName(int objectID, int modelID){
00720
00721 object* O = kb.objectExists(objectID);
00722 if (!O) {
00723 return "";
00724 }
00725
00726
00727 model* M = O->modelExists(modelID);
00728 if (!M){
00729 return "" ;
00730 }
00731
00732 return M->getName();
00733 }
00734
00735 int SiftTekkotsu::getModelID(int objectID, string Name){
00736
00737 object* O = kb.objectExists(objectID);
00738 if (!O) {
00739 return -1;
00740 }
00741
00742 for (unsigned int i = 0; i < O->models.size(); i++){
00743 if (O->models[i]->getName().compare(Name) == 0){
00744 return (int)i;
00745 }
00746 }
00747
00748 return -1;
00749 }
00750
00751
00752
00753
00754
00755 void SiftTekkotsu::setParameter(const char* paramName, double paramVal){
00756 kb.setParameter(paramName, paramVal);
00757 }
00758
00759 double SiftTekkotsu::getParameter(const char* paramName){
00760 return kb.getParameter(paramName);
00761 }
00762
00763 void SiftTekkotsu::saveToFile(const std::string &filename, bool saveImages){
00764 clearTestState();
00765
00766 ofstream outfile;
00767 outfile.open(filename.c_str());
00768 outfile.precision(8);
00769 outfile.setf(ios::fixed);
00770 outfile.setf(ios::showpoint);
00771
00772 outfile << saveImages << endl;
00773
00774 if (saveImages){
00775
00776 outfile << siftImageMaxID << endl;
00777
00778 outfile << imageDatabase.size() << endl;
00779 for (unsigned int i = 0; i < imageDatabase.size(); i++){
00780
00781 outfile << imageDatabase[i]->id << endl;
00782
00783 outfile << imageDatabase[i]->buffer.width << " " << imageDatabase[i]->buffer.height << endl;
00784 for (int j = 0; j < imageDatabase[i]->buffer.width*imageDatabase[i]->buffer.height; j++){
00785 outfile << (unsigned int)(imageDatabase[i]->buffer.byteArray[j]) << " ";
00786 }
00787 outfile << endl;
00788
00789 outfile << imageDatabase[i]->gaussianSpace.size() << endl;
00790 for (int ii = 0; ii < (int)imageDatabase[i]->gaussianSpace.size(); ii++){
00791 outfile << imageDatabase[i]->gaussianSpace[ii].size() << endl;
00792 for (int j = 0; j < (int)imageDatabase[i]->gaussianSpace[ii].size(); j++){
00793 outfile << imageDatabase[i]->gaussianSpace[ii][j].size() << endl;
00794 for (int k = 0; k < (int)imageDatabase[i]->gaussianSpace[ii][j].size(); k++){
00795 outfile << imageDatabase[i]->gaussianSpace[ii][j][k] << " ";
00796 }
00797 }
00798 outfile << endl;
00799 }
00800
00801 outfile << imageDatabase[i]->keypoints.size() << endl;
00802 for (unsigned int j = 0; j < imageDatabase[i]->keypoints.size(); j++){
00803 outfile << imageDatabase[i]->keypoints[j]->getID() << " ";
00804 }
00805 outfile << endl;
00806 }
00807 }
00808
00809
00810 kb.saveToFile(outfile);
00811
00812 outfile.close();
00813 }
00814
00815 void SiftTekkotsu::loadFile(const std::string &filename){
00816 bool verbose = true;
00817
00818 if (verbose) cout << "Loading SiftTekkotsu database from " << filename << endl;
00819
00820
00821 for (unsigned int i = 0; i < imageDatabase.size(); i++){
00822 imageDatabase[i]->clearImage();
00823 delete imageDatabase[i];
00824 }
00825 imageDatabase.clear();
00826 clearTestState();
00827
00828 ifstream infile;
00829 infile.open(filename.c_str());
00830
00831
00832 bool saveImages;
00833 infile >> saveImages;
00834
00835 vector< vector<int> > keypointIDs;
00836 unsigned int imageDatabaseSize;
00837 if (saveImages){
00838 infile >> siftImageMaxID;
00839
00840 infile >> imageDatabaseSize;
00841 if (verbose) cout << "Number of images: " << imageDatabaseSize << endl;
00842 for (unsigned int i = 0; i < imageDatabaseSize; i++){
00843 if (verbose) cout << "Reading SIFTImage #" << i << endl;
00844 int id;
00845 infile >> id;
00846 SIFTImage* sImage = new SIFTImage(id);
00847 if (verbose) cout << "\tReading ImageBuffer\n";
00848
00849 infile >> sImage->buffer.width >> sImage->buffer.height;
00850 if (verbose) cout << "\t\t" << sImage->buffer.height << "x" << sImage->buffer.width << endl;
00851 sImage->buffer.byteArray = (unsigned char*)malloc(sImage->buffer.width * sImage->buffer.height * sizeof(unsigned char));
00852 for (int j = 0; j < sImage->buffer.width*sImage->buffer.height; j++){
00853 unsigned int temp;
00854 infile >> temp;
00855 sImage->buffer.byteArray[j] = (unsigned char)temp;
00856 }
00857 if (verbose) cout << "\tReading Gaussian Space\n";
00858
00859 int numOctaves;
00860 infile >> numOctaves;
00861 if (verbose) cout << "\t\tnumOctaves = " << numOctaves << endl;
00862 for (int ii = 0; ii < numOctaves; ii++){
00863 vector< vector<int> > octaveGaussianSpace;
00864 int numLevels;
00865 infile >> numLevels;
00866
00867 for (int j = 0; j < numLevels; j++){
00868 vector<int> levelSpace;
00869 int numVals;
00870 infile >> numVals;
00871
00872 for (int k = 0; k < numVals; k++){
00873 int val;
00874 infile >> val;
00875 levelSpace.push_back(val);
00876 }
00877 octaveGaussianSpace.push_back(levelSpace);
00878 }
00879 sImage->gaussianSpace.push_back(octaveGaussianSpace);
00880 }
00881 if (verbose) cout << "\tReading keypoint IDs\n";
00882
00883 int numKeys;
00884 infile >> numKeys;
00885 vector<int> keys;
00886 for (int j = 0; j < numKeys; j++){
00887 int keyID;
00888 infile >> keyID;
00889 keys.push_back(keyID);
00890 }
00891 keypointIDs.push_back(keys);
00892 imageDatabase.push_back(sImage);
00893 }
00894 }
00895
00896
00897 if (verbose) cout << "Reading Knowledgebase\n";
00898 kb.readFromFile(infile);
00899
00900 if (verbose) cout << "Check: imageDatabase.size() == " << imageDatabase.size() << "; keypointIDs.size() == " << keypointIDs.size() << endl;
00901
00902
00903 for (unsigned int i = 0; i < imageDatabase.size(); i++){
00904 if (verbose) cout << "Linking imageDatabase[" << i << "]\n";
00905 for (unsigned int j = 0; j < keypointIDs[i].size(); j++){
00906 for (unsigned int k = 0; k < kb.keys.size(); k++){
00907 if (keypointIDs[i][j] == kb.keys[k]->getID()){
00908
00909 imageDatabase[i]->keypoints.push_back(kb.keys[k]);
00910 break;
00911 }
00912 }
00913 }
00914 }
00915
00916 infile.close();
00917
00918 }
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930 int SiftTekkotsu::convertSiftImageIDToIndex(int siftImageID){
00931 for (unsigned int i = 0; i < imageDatabase.size(); i++){
00932 if (imageDatabase[i]->id == siftImageID) return (int)i;
00933 }
00934 return -1;
00935 }
00936
00937
00938
00939
00940 bool SiftTekkotsu::trainImage_getImageBuffer( unsigned int siftImageID, ImageBuffer& buffer){
00941 int index = convertSiftImageIDToIndex(siftImageID);
00942 if (index == -1) return false;
00943
00944 buffer.width = imageDatabase[index]->buffer.width;
00945 buffer.height = imageDatabase[index]->buffer.height;
00946 buffer.byteArray = (unsigned char*)malloc(buffer.width*buffer.height*sizeof(unsigned char));
00947 memcpy(buffer.byteArray, imageDatabase[index]->buffer.byteArray, buffer.width*buffer.height*sizeof(unsigned char));
00948
00949 return true;
00950 }
00951
00952 bool SiftTekkotsu::trainImage_getGaussianSpace(unsigned int siftImageID, vector< vector< vector<int> > >& gaussianSpace){
00953 int index = convertSiftImageIDToIndex(siftImageID);
00954 if (index == -1) return false;
00955
00956 gaussianSpace.clear();
00957 for (unsigned int i = 0; i < imageDatabase[index]->gaussianSpace.size(); i++){
00958 vector< vector<int> > octaveSpace;
00959 for (unsigned int j = 0; j < imageDatabase[index]->gaussianSpace[i].size(); j++){
00960 vector<int> levelSpace;
00961 for (unsigned int k = 0; k < imageDatabase[index]->gaussianSpace[i][j].size(); k++){
00962 levelSpace.push_back(imageDatabase[index]->gaussianSpace[i][j][k]);
00963 }
00964 octaveSpace.push_back(levelSpace);
00965 }
00966 gaussianSpace.push_back(octaveSpace);
00967 }
00968
00969 return true;
00970 }
00971
00972 bool SiftTekkotsu::trainImage_getKeypoints( unsigned int siftImageID, vector<keypoint*>& keypoints){
00973 int index = convertSiftImageIDToIndex(siftImageID);
00974 if (index == -1) return false;
00975
00976 keypoints.clear();
00977 for (unsigned int i = 0; i < imageDatabase[index]->keypoints.size(); i++){
00978 keypoints.push_back(imageDatabase[index]->keypoints[i]);
00979 }
00980
00981 return true;
00982 }
00983
00984
00985
00986 void SiftTekkotsu::testImage_getImageBuffer( ImageBuffer& buffer){
00987 buffer.width = testSIFTImage.buffer.width;
00988 buffer.height = testSIFTImage.buffer.height;
00989 buffer.byteArray = (unsigned char*)malloc(buffer.width*buffer.height*sizeof(unsigned char));
00990 memcpy(buffer.byteArray, testSIFTImage.buffer.byteArray, buffer.width*buffer.height*sizeof(unsigned char));
00991 }
00992
00993 void SiftTekkotsu::testImage_getGaussianSpace(vector< vector< vector<int> > >& gaussianSpace){
00994 gaussianSpace.clear();
00995 for (unsigned int i = 0; i < testSIFTImage.gaussianSpace.size(); i++){
00996 vector< vector<int> > octaveSpace;
00997 for (unsigned int j = 0; j < testSIFTImage.gaussianSpace[i].size(); j++){
00998 vector<int> levelSpace;
00999 for (unsigned int k = 0; k < testSIFTImage.gaussianSpace[i][j].size(); k++){
01000 levelSpace.push_back(testSIFTImage.gaussianSpace[i][j][k]);
01001 }
01002 octaveSpace.push_back(levelSpace);
01003 }
01004 gaussianSpace.push_back(octaveSpace);
01005 }
01006 }
01007
01008 void SiftTekkotsu::testImage_getKeypoints( vector<keypoint*>& keypoints){
01009 keypoints.clear();
01010 for (unsigned int i = 0; i < testSIFTImage.keypoints.size(); i++){
01011 keypoints.push_back(testSIFTImage.keypoints[i]);
01012 }
01013 }
01014
01015 ImageBuffer SiftTekkotsu::sketchToBuffer(const DualCoding::Sketch<DualCoding::uchar>& sk) {
01016 ImageBuffer buffer;
01017 buffer.height = sk.height;
01018 buffer.width = sk.width;
01019 size_t buffsize = sizeof(unsigned char)*buffer.height*buffer.width;
01020 cout << "buffsize = " << buffsize << endl;
01021 unsigned char *imgBuf = (unsigned char *)malloc(buffsize);
01022 sk->savePixels((char *)imgBuf,buffsize);
01023 buffer.byteArray = imgBuf;
01024 return buffer;
01025 }