00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "BeoSub/BeoMap.H"
00039
00040
00041 BeoMap::BeoMap(float cut_thresh, int size_thresh, bool toCut)
00042 {
00043 CUT_THRESHOLD = cut_thresh;
00044 SIZE_THRESH = size_thresh;
00045 globalcounter = 0;
00046 pw = 0;
00047 ph = 0;
00048 switchcnt = 0;
00049 cut = toCut;
00050 }
00051
00052
00053 BeoMap::~BeoMap()
00054 {
00055
00056 }
00057
00058
00059 void BeoMap::makePanorama(const char* nam1, const char* nam2)
00060 {
00061 MYLOGVERB = LOG_INFO;
00062
00063
00064
00065
00066
00067
00068
00069 ImageSet< PixRGB<byte> > images;
00070
00071
00072 Image< PixRGB<byte> > im1 = Raster::ReadRGB(nam1);
00073 images.push_back(im1);
00074 rutz::shared_ptr<VisualObject> vo1(new VisualObject(nam1, "", im1));
00075 LINFO("keypoint extractions completed for input image (%d keypoints)",
00076 vo1->numKeypoints());
00077
00078
00079 std::vector<SIFTaffine> affines;
00080 SIFTaffine comboaff;
00081 affines.push_back(comboaff);
00082 int minx = 0, miny = 0, maxx = im1.getWidth()-1, maxy = im1.getHeight()-1;
00083 for (int i = 1; i < 2; i ++)
00084 {
00085 Image< PixRGB<byte> > im2 = Raster::ReadRGB(nam2);
00086 images.push_back(im2);
00087
00088 rutz::shared_ptr<VisualObject> vo2;
00089
00090 LINFO("Pass #%d\n", globalcounter);
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 if(!cut){
00105 rutz::shared_ptr<VisualObject>
00106 votemp( new VisualObject(nam2, "", im2));
00107 vo2 = votemp;
00108 }
00109 else{
00110 rutz::shared_ptr<VisualObject>
00111 votemp( new VisualObject(nam2, "", im3));
00112 vo2 = votemp;
00113 }
00114
00115
00116
00117
00118
00119 LINFO("keypoint extractions completed for map (%d keypoints)",
00120 vo2->numKeypoints());
00121
00122
00123 maxx = im2.getWidth()-1, maxy = im2.getHeight()-1;
00124
00125
00126 VisualObjectMatch match(vo1, vo2, VOMA_SIMPLE);
00127 LINFO("%d keypoints matched at pass %d", match.size(), globalcounter);
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 match.prune();
00138
00139
00140
00141 SIFTaffine aff = match.getSIFTaffine();
00142 std::cerr<<aff;
00143
00144
00145 comboaff = comboaff.compose(aff);
00146 affines.push_back(comboaff);
00147
00148
00149
00150
00151 if (comboaff.isInversible() == false) LFATAL("Oooops, singular affine!");
00152 SIFTaffine iaff = comboaff.inverse();
00153 const float ww = float(im2.getWidth() - 1);
00154 const float hh = float(im2.getHeight() - 1);
00155 float xx, yy; int x, y;
00156
00157 iaff.transform(0.0F, 0.0F, xx, yy); x = int(xx); y = int(yy);
00158 if (x < minx) {minx = x; }
00159 if (x > maxx) {maxx = x; }
00160 if (y < miny) {miny = y; }
00161 if (y > maxy) {maxy = y; }
00162
00163 iaff.transform(ww, 0.0F, xx, yy); x = int(xx); y = int(yy);
00164 if (x < minx) {minx = x; }
00165 if (x > maxx) {maxx = x; }
00166 if (y < miny) {miny = y; }
00167 if (y > maxy) {maxy = y; }
00168
00169
00170 iaff.transform(0.0F, hh, xx, yy); x = int(xx); y = int(yy);
00171 if (x < minx) {minx = x; }
00172 if (x > maxx) {maxx = x; }
00173 if (y < miny) {miny = y; }
00174 if (y > maxy) {maxy = y; }
00175
00176
00177 iaff.transform(ww, hh, xx, yy); x = int(xx); y = int(yy);
00178 if (x < minx) {minx = x; }
00179 if (x > maxx) {maxx = x; }
00180 if (y < miny) {miny = y; }
00181 if (y > maxy) {maxy = y; }
00182
00183
00184
00185
00186 im1 = im2; vo1 = vo2; nam1 = nam2;
00187 }
00188
00189
00190
00191 int w = maxx - minx + 1, h = maxy - miny + 1;
00192
00193
00194 if(globalcounter==0){
00195 pw=w;
00196 ph=h;
00197 }
00198
00199
00200
00201
00202 if(w <= pw && h <= ph)
00203 {
00204
00205
00206 if (w < 2 || h < 2) LFATAL("Oooops, panorama too small!");
00207 Image< PixRGB<byte> > pano(w, h, ZEROS);
00208 Image< PixRGB<byte> >::iterator p = pano.beginw();
00209
00210 int minStitchedX=0, maxStitchedX=0,
00211 minStitchedY=0, maxStitchedY=0,
00212 counterStitching = 0;
00213 int minStitchedX2=0, maxStitchedX2=0,
00214 minStitchedY2=0, maxStitchedY2=0,
00215 counterStitching2 = 0;
00216
00217
00218
00219
00220
00221 for (int j = 0; j < h; j ++)
00222 for (int i = 0; i < w; i ++)
00223 {
00224
00225
00226
00227 PixRGB<int> val(0); uint n = 0U;
00228
00229 for (uint k = 0; k < images.size(); k ++)
00230 {
00231
00232 float u, v;
00233 affines[k].transform(float(i + minx), float(j + miny), u, v);
00234
00235
00236 if (images[k].coordsOk(u, v))
00237 {
00238 val += PixRGB<int>(images[k].getValInterp(u, v));
00239
00240 if(k == 0 && counterStitching == 0)
00241 {
00242 minStitchedX = maxStitchedX = i;
00243 minStitchedY = maxStitchedY = j;
00244 counterStitching++;
00245 }
00246 else if(k==0)
00247 {
00248 if(minStitchedX > i)
00249 minStitchedX = i;
00250 if(maxStitchedX < i)
00251 maxStitchedX = i;
00252 if(minStitchedY > j)
00253 minStitchedY = j;
00254 if(maxStitchedY < j)
00255 maxStitchedY = j;
00256 counterStitching++;
00257 }
00258 if(counterStitching2 == 0)
00259 {
00260 minStitchedX2 = maxStitchedX2 = i;
00261 minStitchedY2 = maxStitchedY2 = j;
00262 counterStitching2++;
00263 }
00264 else
00265 {
00266 if(minStitchedX2 > i)
00267 minStitchedX2 = i;
00268 if(maxStitchedX2 < i)
00269 maxStitchedX2 = i;
00270 if(minStitchedY2 > j)
00271 minStitchedY2 = j;
00272 if(maxStitchedY2 < j)
00273 maxStitchedY2 = j;
00274 counterStitching2++;
00275 }
00276
00277 ++ n;
00278 }
00279 }
00280
00281 if (n > 0) *p = PixRGB<byte>(val / n);
00282
00283 ++ p;
00284 }
00285
00286 LINFO("Pixel coordinates of the area Stitched: xmin %d, xmax %d, ymin %d, ymax %d",minStitchedX, maxStitchedX, minStitchedY, maxStitchedY);
00287 LINFO("Pixel coordinates of the area Stitched: xmin2 %d, xmax2 %d, ymin2 %d, ymax2 %d",minStitchedX2, maxStitchedX2, minStitchedY2, maxStitchedY2);
00288
00289
00290
00291 Image< PixRGB<byte> > pano2((maxStitchedX2+10<w)?maxStitchedX2+10:w, (maxStitchedY2+10<h)?maxStitchedY2+10:h, ZEROS);
00292 for(int i = 0; i < pano2.getWidth(); i++)
00293 for(int j = 0; j<pano2.getHeight(); j++)
00294 {
00295 pano2.setVal(i,j,pano.getVal(i,j));
00296
00297 }
00298
00299
00300
00301
00302 if( (pano2.getHeight()*pano2.getWidth()) / (float)((maxStitchedX - minStitchedX+1)*(maxStitchedY - minStitchedY+1)) >= CUT_THRESHOLD )
00303 {
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 medge.rightedge = maxStitchedX + SIZE_THRESH;
00317 medge.leftedge = minStitchedX - SIZE_THRESH;
00318 medge.upperedge = minStitchedY - SIZE_THRESH;
00319 medge.loweredge = maxStitchedY + SIZE_THRESH;
00320
00321 if( (pano2.getWidth() - medge.rightedge) < 20){
00322 medge.rightedge = -1;
00323 }
00324
00325 if(medge.leftedge < 20){
00326 medge.leftedge = -1;
00327 }
00328
00329 if( (medge.upperedge) <= 20){
00330 medge.upperedge = -1;
00331 }
00332
00333 if( (pano2.getHeight() - medge.loweredge) < 20){
00334 medge.loweredge = -1;
00335 }
00336
00337
00338 LINFO("minX %d , maxX %d, minY %d, maxY %d", minStitchedX, maxStitchedX, minStitchedY, maxStitchedY);
00339
00340
00341 if(medge.upperedge > 0) LINFO("UPPER-SIDE : %d \n", medge.upperedge);
00342 else LINFO("UPPER-SIDE : No cut");
00343
00344
00345 if(medge.rightedge > 0) LINFO("RIGHT-SIDE : %d \n", medge.rightedge);
00346 else LINFO("RIGHT-SIDE : No cut");
00347
00348 if(medge.leftedge > 0) LINFO("LEFT-SIDE : %d \n", medge.leftedge);
00349 else LINFO("LEFT-SIDE : No cut");
00350
00351
00352
00353 if(medge.loweredge > 0) LINFO("LOWER-SIDE : %d \n", medge.loweredge);
00354 else LINFO("LOWER-SIDE : No cut");
00355
00356 LINFO("Map size : (Xsize, Ysize) = (%d, %d)\n", w, h);
00357
00358
00359
00360 int widthtmp(pano2.getWidth()); int hswitch(0);
00361
00362
00363
00364
00365
00366 if((medge.rightedge != -1) && (medge.leftedge != -1)){
00367 im3.resize(widthtmp = (medge.rightedge+1) - medge.leftedge, pano2.getHeight());
00368
00369 for(int i = 0; i<im3.getWidth();i++)
00370 for(int j = 0; j <im3.getHeight();j++)
00371 {
00372 im3.setVal(i,j,pano2.getVal(i+medge.leftedge, j));
00373 }
00374 cut = true;
00375 hswitch = 1;
00376 }
00377 else if((medge.rightedge != -1) && (medge.leftedge==-1))
00378 {
00379 im3.resize(widthtmp = (medge.rightedge+1), pano2.getHeight());
00380
00381 for(int i = 0; i<im3.getWidth();i++)
00382 for(int j = 0; j <im3.getHeight();j++)
00383 {
00384 im3.setVal(i,j,pano2.getVal(i, j));
00385 }
00386 cut = true;
00387 hswitch = 2;
00388 }
00389 else if((medge.rightedge == -1) && (medge.leftedge!=-1))
00390 {
00391 im3.resize(widthtmp = (pano2.getWidth()-medge.leftedge-1), pano2.getHeight());
00392
00393 for(int i = 0; i<im3.getWidth();i++)
00394 for(int j = 0; j <im3.getHeight();j++)
00395 {
00396 im3.setVal(i,j,pano2.getVal(i+medge.leftedge, j));
00397 }
00398 cut = true;
00399 hswitch = 3;
00400 }
00401 else{
00402 cut = false;
00403 hswitch = 0;
00404 widthtmp = pano2.getWidth();
00405 }
00406
00407
00408
00409
00410 if((medge.upperedge != -1) && (medge.loweredge != -1)){
00411 im3.resize(widthtmp, medge.loweredge - medge.upperedge );
00412
00413 for(int i = 0; i<im3.getWidth();i++)
00414 for(int j = 0; j <im3.getHeight();j++)
00415 {
00416 if(hswitch == 0)
00417 im3.setVal(i,j,pano2.getVal(i, j+medge.upperedge));
00418 if(hswitch == 1)
00419 im3.setVal(i,j,pano2.getVal(i+medge.leftedge, j+medge.upperedge));
00420 if(hswitch == 2)
00421 im3.setVal(i,j,pano2.getVal(i, j+medge.upperedge));
00422 if(hswitch == 3)
00423 im3.setVal(i,j,pano2.getVal(i+medge.leftedge, j+medge.upperedge));
00424 }
00425 cut = true;
00426 }
00427 else if((medge.upperedge != -1) && (medge.loweredge==-1)){
00428 im3.resize(widthtmp, pano2.getHeight() - medge.upperedge);
00429
00430 for(int i = 0; i<im3.getWidth();i++)
00431 for(int j = 0; j <im3.getHeight();j++)
00432 {
00433
00434 if(hswitch == 0)
00435 im3.setVal(i,j,pano2.getVal(i, j+medge.upperedge));
00436 if(hswitch == 1)
00437 im3.setVal(i,j,pano2.getVal(i+medge.leftedge, j+medge.upperedge));
00438 if(hswitch == 2)
00439 im3.setVal(i,j,pano2.getVal(i, j+medge.upperedge));
00440 if(hswitch == 3)
00441 im3.setVal(i,j,pano2.getVal(i+medge.leftedge, j+medge.upperedge));
00442 }
00443 cut = true;
00444 }
00445 else if((medge.upperedge == -1) && (medge.loweredge !=-1)){
00446 im3.resize(widthtmp, medge.loweredge+1);
00447
00448 for(int i = 0; i<im3.getWidth();i++)
00449 for(int j = 0; j <im3.getHeight();j++)
00450 {
00451
00452
00453 if(hswitch == 0)
00454 im3.setVal(i,j,pano2.getVal(i, j));
00455 if(hswitch == 1)
00456 im3.setVal(i,j,pano2.getVal(i+medge.leftedge, j));
00457 if(hswitch == 2)
00458 im3.setVal(i,j,pano2.getVal(i, j));
00459 if(hswitch == 3)
00460 im3.setVal(i,j,pano2.getVal(i+medge.leftedge, j));
00461 }
00462 cut = true;
00463 }
00464 else{
00465 cut = false;
00466 }
00467
00468
00469
00470
00471
00472 }
00473 else
00474 {
00475 cut = false;
00476 }
00477
00478
00479
00480
00481
00482
00483 Raster::WriteRGB(pano2, nam2);
00484
00485
00486
00487 pw = (int)(pano2.getWidth()*1.5);
00488 ph = (int)(pano2.getHeight()*1.5);
00489 globalcounter++;
00490 }
00491 }