1 #include <Image/ImageBlender.hh>
3 #include <MathAlgo/SVD.hh>
4 #include <Base/Common/FileHandling.hh>
5 #include <Base/Image/ImageIO.hh>
6 #include <Utils/ThreeDOut.hh>
7 #include <Base/Image/ImageConvert.hh>
15 ImageBlender::ImageBlender() {
16 cylinderHeight_ = 1.0;
17 SetOuputImageSize((
unsigned int)(1200));
20 drawImageBorders_ =
false;
21 horizonAlignment_ = HORIZON_ALIGNMENT_X;
29 unsigned int weightType) {
32 BIASWARN(
"Projection is invalid! I'll ignore this image...");
38 BIASWARN(
"UUID is invalid! I'll ignore this image...");
45 ImageConvert::ToRGB(camera, temp);
52 for (
unsigned int y = 0; y < temp.
GetHeight(); y++) {
53 for (
unsigned int x = 0; x < temp.
GetWidth(); x++) {
63 ComputeAlphaChannelWeight(temp2, weightType);
69 inputImages_[uuid] = temp2;
70 imageIDs_.push_back(uuid);
84 if (imageIDs_.size() < 1) {
85 BIASWARN(
"I need at least one image to blend!");
98 double superSampling = 1.0;
107 cout <<
"size of final image is "
108 << cylindricImageWidth_ <<
"x" << cylindricImageHeight_ << endl;
110 destination.
Init(cylindricImageWidth_, cylindricImageHeight_, 4);
112 for (
unsigned int y = 0; y < destination.
GetHeight(); y++) {
113 for (
unsigned int x = 0; x < destination.
GetWidth(); x++) {
118 pDA[3] = ALPHA_TRANSPARENT;
125 BIASCDOUT((D_IMAGEBLENDER_MINIMAL | D_IMAGEBLENDER_FILTERING),
126 "filtering images..." << endl << flush);
128 gaussFilter_.SetSigma(gaussSigma);
131 for (
unsigned int i = 0; i < imageIDs_.size(); i++) {
132 BIASCDOUT((D_IMAGEBLENDER_MINIMAL | D_IMAGEBLENDER_FILTERING),
133 "processing image " << i << endl << flush);
135 Projection proj(inputImages_[imageIDs_[i]].GetProj());
140 camCyl.
Init(cylindricImageWidth_, cylindricImageHeight_, 4);
141 for (
unsigned int y = 0; y < camCyl.
GetHeight(); y++) {
142 for (
unsigned int x = 0; x < camCyl.
GetWidth(); x++) {
144 pD[3] = ALPHA_TRANSPARENT;
147 pm.
Map(inputImages_[imageIDs_[i]],
149 mappingQuality,
false,
153 BIASCDOUT((D_IMAGEBLENDER_MINIMAL | D_IMAGEBLENDER_FILTERING),
154 "low-pass filtering with sigma=" << gaussSigma <<
"..."
158 gaussFilter_.Filter(camCyl, lowPassCam);
161 for (
unsigned int y = 0; y < camCyl.
GetHeight(); y++) {
162 for (
unsigned int x = 0; x < camCyl.
GetWidth(); x++) {
170 BIASCDOUT(D_IMAGEBLENDER_FILTERING,
171 "writing temp low-pass image to disk... " << endl << flush);
175 ImageIO::Save(
string(
"tmp_pano_blender_low-pass_")
176 + FileHandling::toString(i)
180 if (DebugLevelIsSet(D_IMAGEBLENDER_FILTERING)) {
181 #ifdef BLENDER_FIX_ME
184 ImageConvert::ConvertST(dynamic_cast<const BIAS::ImageBase>(lowPassCam),
185 dynamic_cast<const BIAS::ImageBase>(temp),
189 s <<
"100_low-pass_image_" << i;
190 cout <<
"writing " << s.str() <<
" to disk..." << endl;
193 ImageIO::Save(s.str(), temp);
198 BIASCDOUT((D_IMAGEBLENDER_MINIMAL | D_IMAGEBLENDER_FILTERING),
199 "high-pass filtering... "<< endl << flush);
207 for (
unsigned int y = 0; y < highPassCam.
GetHeight(); y++) {
208 for (
unsigned int x = 0; x < highPassCam.
GetWidth(); x++) {
213 pDH[0] = pDC[0] - pDL[0];
214 pDH[1] = pDC[1] - pDL[1];
215 pDH[2] = pDC[2] - pDL[2];
221 BIASCDOUT(D_IMAGEBLENDER_FILTERING,
222 "writing temp high-pass image to disk... "<< endl << flush);
226 ImageIO::Save(
string(
"tmp_pano_blender_high-pass_")
227 + FileHandling::toString(i)
231 if (DebugLevelIsSet(D_IMAGEBLENDER_FILTERING)) {
232 #ifdef BLENDER_FIX_ME
235 ImageConvert::ConvertST(highPassCam, temp, ImageBase::CM_RGBA);
238 s <<
"100_high-pass_image_" << i;
239 cout <<
"writing " << s.str() <<
" to disk..." << endl;
242 ImageIO::Save(s.str(), temp);
248 if (!drawImageBorders_) {
249 inputImages_.clear();
253 BIASCDOUT((D_IMAGEBLENDER_MINIMAL | D_IMAGEBLENDER_BLENDING),
254 endl <<
"blending images");
256 float r, g, b, w, rLow, gLow, bLow, wLow;
264 destination.
Clear(0);
272 for (
unsigned int imageCount = 0; imageCount < imageIDs_.size(); imageCount++) {
275 ImageIO::Load(
string(
"tmp_pano_blender_low-pass_") + FileHandling::toString(imageCount)
278 ImageIO::Load(
string(
"tmp_pano_blender_high-pass_") + FileHandling::toString(imageCount)
283 for (
unsigned int i = 0;
288 if ((i % 30000) == 0) {
289 BIASCDOUT((D_IMAGEBLENDER_MINIMAL | D_IMAGEBLENDER_BLENDING),
".");
301 rLow = float(pL[i + 0]);
302 gLow = float(pL[i + 1]);
303 bLow = float(pL[i + 2]);
304 wLow = float(pL[i + 3]);
306 r = (w * r + wLow * rLow) / (w + wLow);
307 g = (w * g + wLow * gLow) / (w + wLow);
308 b = (w * b + wLow * bLow) / (w + wLow);
320 if (pH[i + 3] > pDHigh[i + 3]) {
321 pDHigh[i + 0] = pH[i + 0];
322 pDHigh[i + 1] = pH[i + 1];
323 pDHigh[i + 2] = pH[i + 2];
324 pDHigh[i + 3] = pH[i + 3];
330 for (
unsigned int i = 0;
334 if (pDLow[i + 3] > 0.0) {
336 float sumR = pDLow[i + 0] + pDHigh[i + 0];
337 float sumG = pDLow[i + 1] + pDHigh[i + 1];
338 float sumB = pDLow[i + 2] + pDHigh[i + 2];
339 if (sumR > 255.0) sumR = 255.0;
340 if (sumG > 255.0) sumG = 255.0;
341 if (sumB > 255.0) sumB = 255.0;
342 if (sumR < 0.0) sumR = 0.0;
343 if (sumG < 0.0) sumG = 0.0;
344 if (sumB < 0.0) sumB = 0.0;
347 pDest[i + 0] = (
unsigned char)(sumR);
348 pDest[i + 1] = (
unsigned char)(sumG);
349 pDest[i + 2] = (
unsigned char)(sumB);
350 pDest[i + 3] = ALPHA_OPAQUE;
354 BIASCDOUT((D_IMAGEBLENDER_MINIMAL | D_IMAGEBLENDER_BLENDING),
358 if (drawImageBorders_) {
359 for (
unsigned int i = 0; i < imageIDs_.size(); i++) {
360 cout <<
"drawing border of image " << i << endl;
365 projection = inputImages_[imageIDs_[i]].GetProj();
386 (
unsigned int)(p2DHom[0]),
387 (
unsigned int)(p2DHom[1]),
390 (
unsigned int)(p2DHom[0]),
391 (
unsigned int)(p2DHom[1]),
394 (
unsigned int)(p2DHom[0]),
395 (
unsigned int)(p2DHom[1]),
400 (
unsigned int)(p2DHom[0]),
401 (
unsigned int)(p2DHom[1]),
416 ImageConvert::Convert(destination, rgbim, ImageBase::CM_RGB);
426 scene3D.
VRMLOut(
"cylindricPanorama.wrl");
436 if (imageIDs_.size() < 1) {
437 BIASWARN(
"I need at least one image to compute destination geometry!");
443 RMatrix RTarget(inputImages_[imageIDs_[0]].GetProj().GetR());
452 unsigned int testAlignment = horizonAlignment_;
453 if (horizonAlignment_== HORIZON_ALIGNMENT_AUTO)
456 double bestResiduum = HUGE_VAL;
457 int selectedmode = -1;
461 if (testAlignment == HORIZON_ALIGNMENT_X) {
462 for (
unsigned int i = 0; i < imageIDs_.size(); i++) {
463 RMatrix R = inputImages_[imageIDs_[i]].GetProj().GetR();
464 for (
unsigned int c=0;c<3;c++) M[i][c] = R[c][0];
466 }
else if (testAlignment == HORIZON_ALIGNMENT_Y) {
467 for (
unsigned int i = 0; i < imageIDs_.size(); i++) {
468 RMatrix R = inputImages_[imageIDs_[i]].GetProj().GetR();
469 for (
unsigned int c=0;c<3;c++) M[i][c] = R[c][1];
471 }
else if (testAlignment == HORIZON_ALIGNMENT_UNKNOWN) {
473 for (
unsigned int i = 0; i < imageIDs_.size(); i++) {
474 RMatrix R = inputImages_[imageIDs_[i]].GetProj().GetR();
475 for (
unsigned int c=0;c<3;c++) M[i][c] = R[c][2];
481 SVD svd(M, 0.1,
false);
489 for (
unsigned int i = 0; i < 3; i++) {
491 secondh[i] =vt[vt.
num_rows() - 2][i];
501 double residuum = (M*h).NormL2()/double(h.
Size());
502 double secondresiduum = (M*secondh).NormL2()/double(h.
Size());
503 double thirdresiduum = (M*thirdh).NormL2()/double(h.
Size());
505 if (residuum<1e-10) residuum = 1e-10;
506 if (secondresiduum<1e-10) secondresiduum=1e-10;
507 if (thirdresiduum<1e-10) thirdresiduum=1e-10;
514 bool nullspacedim2 = thirdresiduum / secondresiduum > 10.0;
518 if (residuum<bestResiduum && !nullspacedim2) {
521 bestResiduum = residuum;
522 selectedmode = testAlignment;
525 if (horizonAlignment_== HORIZON_ALIGNMENT_AUTO) testAlignment++;
526 }
while (testAlignment!=horizonAlignment_);
528 if (horizonAlignment_ == HORIZON_ALIGNMENT_AUTO)
switch (selectedmode) {
529 case HORIZON_ALIGNMENT_X:cout<<
"Applying horizontal alignment"<<endl;
break;
530 case HORIZON_ALIGNMENT_Y:cout<<
"Applying vertical alignment"<<endl;
break;
531 default:cout<<
"Applying optical axis alignment"<<endl;
break;
534 horizonAlignment_ = selectedmode;
548 vector< Vector3<double> > projectedVectors;
550 for (
unsigned int imCount = 0; imCount < imageIDs_.size(); imCount++) {
552 RMatrix Rot = inputImages_[imageIDs_[imCount]].GetProj().GetR();
558 if (horizonAlignment_ == HORIZON_ALIGNMENT_X) {
563 else if (horizonAlignment_ == HORIZON_ALIGNMENT_Y) {
575 orig.
Sub(temp, proj);
577 projectedVectors.push_back(proj);
582 BIASASSERT(!projectedVectors.empty());
598 vector< Vector2<double> > vectorsInPlaneSpace(projectedVectors.size());
601 planeTransform[0][0] = a[0];
602 planeTransform[0][1] = a[1];
603 planeTransform[0][2] = a[2];
604 planeTransform[1][0] = v[0];
605 planeTransform[1][1] = v[1];
606 planeTransform[1][2] = v[2];
608 for (
unsigned int i = 0; i < projectedVectors.size(); i++) {
614 planeTransform.Mult(v1, v2);
615 vectorsInPlaneSpace[i] = v2;
618 double norm = vectorsInPlaneSpace[i].
NormL2();
619 vectorsInPlaneSpace[i] /= norm;
621 cout <<
"vec " << i <<
" " << vectorsInPlaneSpace[i]
622 <<
" norm " << vectorsInPlaneSpace[i].NormL2()<< endl;
629 vector<double> angles(vectorsInPlaneSpace.size());
631 for (
unsigned int i = 0; i < vectorsInPlaneSpace.size(); i++) {
632 angles[i] = CalcAngleToXAxis(vectorsInPlaneSpace[i],
true);
633 cout << i <<
". angle relative to reference vector " << angles[i] << endl;
637 vector<bool> visited(vectorsInPlaneSpace.size());
638 vector<double> successiveAngles;
640 double sumAngles = 0.0;
642 for (
unsigned int i = 0; i < visited.size(); i++) {
649 for (
unsigned int i = 1; i < vectorsInPlaneSpace.size(); i++) {
650 double smallestAngle = 361;
654 for (
unsigned int j = 0; j < vectorsInPlaneSpace.size(); j++) {
655 if (!visited[j] && (angles[j] < smallestAngle)) {
656 smallestAngle = angles[j];
660 BIASASSERT(index != -1);
662 visited[index] =
true;
664 if (successiveAngles.empty()) {
665 angle = smallestAngle;
668 angle = smallestAngle - successiveAngles[successiveAngles.size() - 1];
670 successiveAngles.push_back(angle);
671 indices.push_back(index);
676 double sumAnglesRemainder = sumAngles - int(sumAngles);
677 sumAngles = int(sumAngles) % 360;
678 sumAngles += sumAnglesRemainder;
680 cout <<
"sum of all angles is " << sumAngles << endl;
682 BIASASSERT(sumAngles <= 360);
685 successiveAngles.push_back(360 - sumAngles);
686 indices.push_back(0);
688 for (
unsigned int i = 0; i < indices.size(); i++) {
689 cout <<
"index " << indices[i]
690 <<
" angle " << successiveAngles[i] << endl;
694 double biggestAngle = 0.0;
695 int indexL = -1, indexR = -1;
697 for (
unsigned int i = 0; i < indices.size(); i++) {
698 if (successiveAngles[i] > biggestAngle) {
699 biggestAngle = successiveAngles[i];
701 indexL = indices[indices.size() - 1];
704 indexL = indices[i - 1];
710 cout <<
"biggest gap is " << biggestAngle <<
" degrees between axis "
711 << indexL <<
" and " << indexR << endl;
715 if (biggestAngle != 180.0) {
716 midVec = (vectorsInPlaneSpace[indexL] + vectorsInPlaneSpace[indexR]) / 2.0;
727 cout <<
"found 180 deg gap - using rot " << rotTmp << endl;
729 cout <<
"with vec " << vectorsInPlaneSpace[indexL] << endl;
731 rotTmp.
Mult(vectorsInPlaneSpace[indexL], midVec);
733 cout <<
"mid vec is " << midVec << endl;
736 midVec /= midVec.
NormL2();
737 cout <<
"optical axis after norm " << midVec << endl;
742 planeTransformInv = svdInvert.
Invert(planeTransform);
748 planeTransformInv.
Mult(v1, v2);
751 cout <<
"final optical axis is " << a << endl;
754 a.CrossProduct(h, v);
758 RTarget[0][0] = h[0];
759 RTarget[1][0] = h[1];
760 RTarget[2][0] = h[2];
761 RTarget[0][1] = v[0];
762 RTarget[1][1] = v[1];
763 RTarget[2][1] = v[2];
764 RTarget[0][2] = a[0];
765 RTarget[1][2] = a[1];
766 RTarget[2][2] = a[2];
793 ret = ret * 180 / M_PI;
804 ret = 2 * M_PI - ret;
825 ret = ret * 180 / M_PI;
836 ret = 2 * M_PI - ret;
846 cout <<
"checking fov of cameras..." << endl;
848 double minX=1e100, minY=1e100,
849 maxX=-1e100, maxY=-1e100;
852 for (
unsigned int i = 0; i < imageIDs_.size(); i++) {
857 proj = inputImages_[imageIDs_[i]].GetProj();
878 if (!
Equal(norm, 1.0)) {
879 BIASERR(
"ray not unit length: " << ray);
897 if (x[0] < minX) minX = x[0];
898 if (x[1] < minY) minY = x[1];
899 if (x[0] > maxX) maxX = x[0];
900 if (x[1] > maxY) maxY = x[1];
909 BIASCDOUT(D_IMAGEBLENDER_GEOMETRY,
910 "Max field of view of cam "
911 << i <<
" is " << angle << endl << flush);
923 inputImages_[imageIDs_[i]].SetProj(
Projection(*ppp));
927 double halfWidth = cylindricImageWidth_ / 2.0;
928 double halfHeight = cylindricImageHeight_ / 2.0;
930 double xMin = -1.0 * ((halfWidth - minX) / halfWidth);
931 double xMax = (maxX - halfWidth) / halfWidth;
933 double phiMin = -M_PI * ((halfHeight - minY) / halfHeight);
934 double phiMax = M_PI * ((maxY - halfHeight) / halfHeight);
936 double factor = cylindricImageHeight_ / (maxY - minY);
937 cylindricImageWidth_ = (
unsigned int)((maxX - minX) * factor);
941 cylindricImageWidth_,
942 cylindricImageHeight_);
948 inline double CalculateWeightCircular(
int dx,
951 double ret = (1.0 - sqrt(
double(dx * dx + dy * dy)) / distCenter) * 255.0;
960 inline double CalculateWeightRectangular(
unsigned int w,
971 bool aboveAC, aboveBD;
972 double alphaValue = 0.0;
983 m = double(h) / double(w);
986 mp = double(y) / double(x);
995 mp = double(y) / double(mx + (mx - x));
1004 if (aboveAC && aboveBD) {
1005 alphaValue = double(y) / double(my);
1007 else if (aboveAC && !aboveBD) {
1008 alphaValue = double(w - x) / double(mx);
1010 else if (!aboveAC && !aboveBD) {
1011 alphaValue = double(h - y) / double(my);
1013 else if (!aboveAC && aboveBD) {
1014 alphaValue = double(x) / double(mx);
1017 return alphaValue * 255.0;
1025 unsigned int weightType) {
1028 ConvertImageToRGBA(image);
1030 const unsigned int w = image.
GetWidth();
1031 const unsigned int h = image.
GetHeight();
1033 const unsigned int mx = w / 2;
1034 const unsigned int my = h / 2;
1037 const double distCenter = sqrt(
double(mx * mx + my * my));
1045 const double mixRatio = 0.5;
1046 const double gain = 1.0 / (mixRatio * (1.0 - mixRatio));
1048 for (
unsigned int x = 0; x < w; x++) {
1049 for (
unsigned int y = 0; y < h; y++) {
1051 unsigned int dx = mx - x;
1052 unsigned int dy = my - y;
1054 double alphaValue = 0.0;
1056 double rectVal, circVal;
1058 switch (weightType) {
1059 case WEIGHT_TYPE_NONE:
1060 alphaValue = ALPHA_OPAQUE;
1063 case WEIGHT_TYPE_CIRCULAR:
1064 alphaValue = CalculateWeightCircular(dx, dy, distCenter);
1067 case WEIGHT_TYPE_CIRCULAR_FIT:
1069 alphaValue = CalculateWeightCircular(dx, dy, mx);
1072 alphaValue = CalculateWeightCircular(dx, dy, my);
1076 case WEIGHT_TYPE_RECTANGULAR:
1077 alphaValue = CalculateWeightRectangular(w, h, x, y, mx, my);
1080 case WEIGHT_TYPE_MIX:
1081 rectVal = CalculateWeightRectangular(w, h, x, y, mx, my) / 255.0;
1082 circVal = CalculateWeightCircular(dx, dy, distCenter) / 255.0;
1083 alphaValue = (mixRatio * rectVal)
1084 * ((1.0 - mixRatio) * circVal)
1089 case WEIGHT_TYPE_RECT_NONLINEAR:
1090 rectVal = CalculateWeightRectangular(w, h, x, y, mx, my) / 255.0;
1091 alphaValue = rectVal * rectVal * 255.0;
1095 BIASERR(
"Unknown weight type!");
1099 if (alphaValue < 0.0) alphaValue = 0.0;
1100 if (alphaValue > 255.0) alphaValue = 255.0;
1116 ImageConvert::Convert(image, tempImage, ImageBase::CM_RGB);
1126 alphaImage.SetColorModel(ImageBase::CM_RGBA);
1127 for (
unsigned int y = 0; y < alphaImage.GetHeight(); y++) {
1128 for (
unsigned int x = 0; x < alphaImage.GetWidth(); x++) {
1130 float *pDA = &alphaImage.GetImageDataArray()[y][4 * x];
1134 *pDA++ = ALPHA_OPAQUE;
void Release()
reimplemented from ImageBase
InterpolationMethod
accuracy for resampling
unsigned int AddTriangleMesh(const TriangleMesh &mesh, const std::string &name="", const std::string &textureOutputName="", bool writeOutTexture=true, bool calcNormals=false)
Adds triangle mesh as IndexedFaceSet to ThreeDOut mem.
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
computes and holds the singular value decomposition of a rectangular (not necessarily quadratic) Matr...
int VRMLOut(const std::string &sFilename)
flush all 3d objects to a vrml file with name sFilename, this is the function most users would call ...
void GenerateTexturedCamera(const ProjectionParametersBase *PPB, Image< unsigned char > &rgbtexture, const double &scale=1.0, const double &opacity=1.0, const double &resolution=1.0)
generates the sensor plane / cylinder / sphere in 3D space
void ScalarProduct(const Vector2< T > &argvec, T &result) const
scalar product of two vectors, storing the result in result
virtual void SetR(const BIAS::RMatrix &R)
Set orientation from rotation matrix R.
double NormL2() const
Return the L2 norm: sqrt(a^1 + a^2 + ...)
camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
void SetSinkCam(const Projection &P, const Image< float > *sinkdepth=NULL)
Set your sink projection before calling Map(),.
void ScalarProduct(const Vector3< T > &argvec, T &result) const
scalar product (=inner product) of two vectors, storing the result in result
void SetSourceCam(const Projection &P)
Set your source projection before calling Map()
Unified output of 3D entities via OpenGL or VRML.
void SetMinZLocal(const double &minz)
sets minimum z value of unit-ray in local CCS to be accepted as in front of camera (e...
virtual bool DoesPointProjectIntoImage(const HomgPoint3D &X, HomgPoint2D &x, bool IgnoreDistortion=false) const
Checks if 3D point projects into specified image and returns belonging 2D image point.
void Mult(const Vector2< T > &argvec, Vector2< T > &destvec) const
matrix - vector multiplicate this matrix with Vector2, storing the result in destvec calculates: dest...
unsigned int GetWidth() const
virtual void UnProjectToRay(const HomgPoint2D &pos, Vector3< double > &origin, Vector3< double > &direction, bool ignoreDistortion=false) const
Calculates the view ray, which belongs to the given position on the image plane, in global coordinate...
const BIAS::UUID & GetUID() const
returns the UUID of the image
virtual void GetFirstBorderPixel(PixelIterator &it)
call this to start a run at the outer boundary of an image.
void CrossProduct(const Vector3< T > &argvec, Vector3< T > &destvec) const
cross product of two vectors destvec = this x argvec
void Clear(const StorageType value=0)
sets all pixels to zero/value
const ProjectionParametersBase * GetParameters(unsigned int cam=0) const
const parameter access function
const unsigned int Size() const
This class hides the underlying projection model, like projection matrix, spherical camera...
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Create and represent a 3D triangle mesh.
const Matrix< double > & GetVT() const
return VT (=transposed(V))
int SetProj(const Projection &Proj)
void Mult(const T &scalar, Vector3< T > &dest) const
unsigned int GetHeight() const
int Map(const Image< InputStorageType > &src, Image< OutputStorageType > &sink, InterpolationMethod=MapTrilinear, bool newSink=false, double SuperSampling=1.0)
backward mapping with various interpolations
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
void SetPixel(const StorageType &value, const unsigned int &x, const unsigned int &y, const unsigned short int channel=0)
Set the value of a given pixel (x,y) in channel to value.
Can be used to run along the image border.
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
void SetUID(const BIAS::UUID &id)
void Sub(const T &scalar, Vector3< T > &dest) const
Substraction with a scalar, storing results in destination vector.
void Mult(const Matrix< T > &arg, Matrix< T > &result) const
matrix multiplication, result is not allocated
enum EColorModel GetColorModel() const
double x
If using BorderPixel methods these are the coordinates of the pixel.
int UpdateMetaData()
copy P_ and co.
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
double NormL2() const
Return the L2 norm: sqrt(a^2 + b^2)
Matrix< double > Invert()
returns pseudoinverse of A = U * S * V^T A^+ = V * S^+ * U^T
Subscript num_rows() const
virtual void UnProjectLocal(const HomgPoint2D &pos, Vector3< double > &pointOnRay, Vector3< double > &direction, bool IgnoreDistortion=false) const
calculates the viewing ray from the camera center (in the camera coordinate system) which belongs to ...
interface class for producing/storing Universally Unique IDentifiers
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
const BIAS::Projection & GetProj() const
virtual void SetC(const BIAS::Vector3< double > &C)
Set projection center.
Vector3< T > & Normalize()
normalize this vector to length 1
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
bool IsValid() const
checks whether this uuid is valid(true) or unitialized(false)
virtual bool GetNextBorderPixel(PixelIterator &it)
call this iteratively to run at the outer boundary of an image.
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase