Example for image rectification.
#include <iostream>
#include <Base/Image/ImageIO.hh>
#include <Image/Camera.hh>
#include <Image/PlanarRectification.hh>
#include <Image/CylindricalRectification.hh>
#include <Image/SphericalRectification.hh>
#include <Image/RectificationBase.hh>
#include <Utils/Param.hh>
#include <Utils/ThreeDOut.hh>
#include <Base/Image/ImageConvert.hh>
using namespace std;
using namespace BIAS;
#define OutStorageType unsigned char
int main(int argc, char* argv[])
{
"Write out VRML with rectified geometry?",
false);
bool* pointsonly =
"Do not use texture but colored vertices instead?",
false);
enum {cylindrical = 0, spherical, planar};
vector<string> rectificationTypes;
rectificationTypes.push_back("cylindrical");
rectificationTypes.push_back("spherical");
rectificationTypes.push_back("planar");
int* rectType =
"Specifies type of rectification to perform:"
" [cylindrical], spherical, planar",
rectificationTypes);
vector<string> interpolationType;
interpolationType.push_back("Trilinear");
interpolationType.push_back("Bilinear");
int* interType =
"Specifies type interpolation to use:"
" [Trilinear], Bilinear",
interpolationType);
double* resolution =
"Scales the resolution of rectified images",
0.8, 0.001);
bool* useLUT =
"Turn off usage of lookup tables", true);
string* rectSetupName =
params.
AddParamString(
"rectSetup",
"File that contains or shall contain the"
" rectification setup", "", 0, -1);
if(argc<3 || *help) {
cout<<"Determines rectification and stores them in name."<<endl<<endl;
cout<<"Usage: "<<argv[0]<<" [options] <origImgA> <origImgB>"<<endl;
return 0;
}
if(ImageIO::Load(argv[fup], camA)!=0) {
cerr<<"[ERROR] Unable to load first camera!"<<endl;
return -1;
}
if(ImageIO::Load(argv[fup+1], camB)!=0) {
cerr<<"[ERROR] Unable to second first camera!"<<endl;
return -1;
}
bool useSetup = false;
bool generateSetup = false;
if(rectSetupName->size()>0) {
useSetup = true;
if(ImageIO::Load(*rectSetupName, rectSetup)<0) {
cerr<<"[ERROR] Could not open rectification setup file "
<<*rectSetupName<<endl;
cerr<<" It will be created from given parameters."<<endl;
generateSetup = true;
}
}
rectifierPM = NULL;
switch(*rectType) {
case cylindrical :
rectifier = rectifierPM =
break;
case spherical :
rectifier = rectifierPM =
break;
case planar :
rectifier = rectifierPM =
break;
default:
cerr<<"[ERROR] Unknown rectification type "
<<*rectType<<" given!"<<endl;
return -1;
}
switch(*interType) {
case Trilinear:
break;
break;
default:
cerr<<"[ERROR] Unknown interpolation method "
<<*interType<<" given!"<<endl;
return -1;
}
cerr<<"[ERROR] Invalid camera type for camera A!"<<endl;
delete rectifier;
return -1;
}
cerr<<"[ERROR] Invalid camera type for camera B!"<<endl;
delete rectifier;
return -1;
}
if(useSetup) {
if(generateSetup) {
cerr<<"[ERROR] Failed to create rectification setup!"<<endl;
return -1;
}
if(ImageIO::Save(*rectSetupName, rectSetup)<0) {
cerr<<"[ERROR] Failed to write rectification setup to "
<<*rectSetupName<<endl;
return -1;
}
} else {
cerr<<"[ERROR] Failed to load rectification setup!"<<endl;
return -1;
}
}
}
cerr<<"[ERROR] Failed to retrieve rectification parameters!"<<endl;
delete rectifier;
return -1;
}
cerr<<"Found rectification parameters!"<<endl;
cerr<<"- Camera A rectification state: "<<*rectPPA<<endl;
cerr<<"- Camera B rectification state: "<<*rectPPB<<endl<<endl;
cerr<<"Starting rectification... "<<flush;
cerr<<" failed!"<<endl;
delete rectifier;
delete rectPPA;
delete rectPPB;
return -1;
}
cerr<<" done!"<<endl;
string path1, basename1, suffix1;
string path2, basename2, suffix2;
FileHandling::SplitName(argv[fup], path1, basename1, suffix1);
FileHandling::SplitName(argv[fup+1], path2, basename2, suffix2);
string firstName = basename1+"_rect";
string secondName = basename2+"_rect";
if(ImageIO::Save(firstName, rectA, ImageIO::FF_mip)!=0) {
cerr<<"[ERROR] Failed to write first rectified image!"<<endl;
}
if(ImageIO::Save(secondName, rectB, ImageIO::FF_mip)!=0) {
cerr<<"[ERROR] Failed to write second rectified image!"<<endl;
}
if(*vrml) {
cerr<<"Generating VRML models with rectification data:"<<endl;
cerr<<"- First VRML containing coordinate systems only... "<<flush;
bool good = false;
if(tdo.
VRMLOut(
"rectCoordinates.wrl")!=0) {
good = false;
} else {
good = true;
}
if(good) {
cerr<<"done!";
} else {
cerr<<"failed!";
}
cerr<<endl;
cerr<<"- Generating VRML models containing projected images... "<<flush;
unsigned int width = 0, height = 0;
double scale = 3.0;
if (*pointsonly) {
for (unsigned int y=0; y<height; y++) {
for (unsigned int x=0; x<width; x++) {
if (p3.
NormL2()<0.1)
continue;
RGBAuc theColor((
unsigned char)color,(
unsigned char)color,
(unsigned char)color,255);
}
}
} else {
ImageConvert::ToRGB(rectA, RGBrectA);
ImageConvert::ConvertST(RGBrectA, tmp, ImageBase::ST_unsignedchar);
}
if (*pointsonly) {
for (unsigned int y=0; y<height; y++) {
for (unsigned int x=0; x<width; x++) {
if (p3.
NormL2()<0.1)
continue;
unsigned char color =
RGBAuc theColor(color,color,color,255);
}
}
} else {
ImageConvert::ToRGB(rectB, RGBrectB);
ImageConvert::ConvertST(RGBrectB, tmp, ImageBase::ST_unsignedchar);
}
cerr<<"done!"<<endl<<flush;
tdo.
VRMLOut(
"rectCoordinates_image.wrl");
cerr<<"- Writing mipview3d animation file 'cylindersweep.anim'... "<<flush;
ofstream myanimfile("cylindersweep.anim");
myanimfile <<"[0] :43 0 0 0 0 1 0 0 0"<<endl
<<"[0] :43 1000 " <<c[0]<<" "<<c[1]<<" "<<c[2]
<<" 1 0 0 0"<<endl;
cerr<<"done!"<<endl;
cerr<<"- Generating VRML models with original cameras... "<<flush;
ImageConvert::ToRGB(camA, RGBcamA);
ImageConvert::ToRGB(camB, RGBcamB);
scale*0.1, scale);
scale*0.1, scale);
cerr<<"done!"<<endl<<flush;
}
delete rectPPA;
delete rectPPB;
delete rectifier;
return 0;
}