You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
5.0 KiB
181 lines
5.0 KiB
2 years ago
|
/*=========================================================================
|
||
|
|
||
|
Program: Visualization Toolkit
|
||
|
Module: $RCSfile: vtkWarpLens.cxx,v $
|
||
|
|
||
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
||
|
All rights reserved.
|
||
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
||
|
|
||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
PURPOSE. See the above copyright notice for more information.
|
||
|
|
||
|
=========================================================================*/
|
||
|
#include "vtkWarpLens.h"
|
||
|
|
||
|
#include "vtkInformation.h"
|
||
|
#include "vtkInformationVector.h"
|
||
|
#include "vtkMath.h"
|
||
|
#include "vtkObjectFactory.h"
|
||
|
#include "vtkPointData.h"
|
||
|
#include "vtkPointSet.h"
|
||
|
#include "vtkPoints.h"
|
||
|
|
||
|
vtkCxxRevisionMacro(vtkWarpLens, "$Revision: 1.29 $");
|
||
|
vtkStandardNewMacro(vtkWarpLens);
|
||
|
|
||
|
//
|
||
|
// Preserve old Kappa instance variable. It appears to be the
|
||
|
// second order symmetric radial lens distortion parameter
|
||
|
//
|
||
|
void vtkWarpLens::SetKappa(double kappa)
|
||
|
{
|
||
|
this->SetK1(kappa);
|
||
|
}
|
||
|
|
||
|
double vtkWarpLens::GetKappa()
|
||
|
{
|
||
|
return this->GetK1();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Preserve old Center point instance variable.
|
||
|
// It appears to be the center of radial distortion in pixel coordinates
|
||
|
//
|
||
|
void vtkWarpLens::SetCenter(double centerX, double centerY)
|
||
|
{
|
||
|
this->SetPrincipalPoint(centerX, centerY);
|
||
|
}
|
||
|
|
||
|
double *vtkWarpLens::GetCenter()
|
||
|
{
|
||
|
return this->GetPrincipalPoint();
|
||
|
}
|
||
|
|
||
|
vtkWarpLens::vtkWarpLens()
|
||
|
{
|
||
|
this->PrincipalPoint[0] = 0.0;
|
||
|
this->PrincipalPoint[1] = 0.0;
|
||
|
this->K1 = -1.0e-6;
|
||
|
this->K2 = 0.0;
|
||
|
this->P1 = 0.0;
|
||
|
this->P2 = 0.0;
|
||
|
this->FormatWidth = 1.0;
|
||
|
this->FormatHeight = 1.0;
|
||
|
this->ImageWidth = 1;
|
||
|
this->ImageHeight = 1;
|
||
|
}
|
||
|
|
||
|
int vtkWarpLens::RequestData(
|
||
|
vtkInformation *vtkNotUsed(request),
|
||
|
vtkInformationVector **inputVector,
|
||
|
vtkInformationVector *outputVector)
|
||
|
{
|
||
|
// get the info objects
|
||
|
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
|
||
|
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
||
|
|
||
|
// get the input and ouptut
|
||
|
vtkPointSet *input = vtkPointSet::SafeDownCast(
|
||
|
inInfo->Get(vtkDataObject::DATA_OBJECT()));
|
||
|
vtkPointSet *output = vtkPointSet::SafeDownCast(
|
||
|
outInfo->Get(vtkDataObject::DATA_OBJECT()));
|
||
|
|
||
|
vtkPoints *inPts;
|
||
|
vtkPoints *newPts;
|
||
|
vtkIdType ptId, numPts;
|
||
|
double pixel[3], newPixel[3];
|
||
|
double x;
|
||
|
double y;
|
||
|
double newX;
|
||
|
double newY;
|
||
|
double rSquared;
|
||
|
|
||
|
vtkDebugMacro(<<"Warping data to a point");
|
||
|
|
||
|
// First, copy the input to the output as a starting point
|
||
|
output->CopyStructure( input );
|
||
|
|
||
|
inPts = input->GetPoints();
|
||
|
if (!inPts )
|
||
|
{
|
||
|
vtkErrorMacro(<<"No input data");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
numPts = inPts->GetNumberOfPoints();
|
||
|
newPts = vtkPoints::New();
|
||
|
newPts->SetNumberOfPoints(numPts);
|
||
|
|
||
|
//
|
||
|
// Loop over all pixels, adjusting locations
|
||
|
//
|
||
|
for (ptId=0; ptId < numPts; ptId++)
|
||
|
{
|
||
|
inPts->GetPoint(ptId, pixel);
|
||
|
|
||
|
//
|
||
|
// Convert to working in mm from pixels and make the Principal Point (0,0)
|
||
|
//
|
||
|
x = pixel[0] / this->ImageWidth * this->FormatWidth -
|
||
|
this->PrincipalPoint[0];
|
||
|
y = (- pixel[1]) / this->ImageHeight * this->FormatHeight +
|
||
|
this->PrincipalPoint[1];
|
||
|
|
||
|
//
|
||
|
// Lens distortion causes a point's image on the imaging surface to
|
||
|
// shifted from its true position as if it had been imaged by an ideal pin-
|
||
|
// hole camera.
|
||
|
//
|
||
|
// The corrected location adds the correction for radial len distortion
|
||
|
// and for the decentering lens distortion
|
||
|
//
|
||
|
rSquared = x*x + y*y;
|
||
|
|
||
|
newX = x * (1 + this->K1 * rSquared + this->K2 * rSquared*rSquared ) +
|
||
|
this->P1 * (rSquared + 2 * x*x) + 2 * this->P2 * x * y;
|
||
|
|
||
|
newY = y * (1 + this->K1 * rSquared + this->K2 * rSquared*rSquared ) +
|
||
|
this->P2 * (rSquared + 2 * y*y) + 2 * this->P1 * x * y;
|
||
|
|
||
|
//
|
||
|
// Convert back to pixels
|
||
|
//
|
||
|
newPixel[0] = (newX + this->PrincipalPoint[0]) / this->FormatWidth *
|
||
|
this->ImageWidth;
|
||
|
newPixel[1] = (newY - this->PrincipalPoint[1]) /
|
||
|
this->FormatHeight * this->ImageHeight * -1;
|
||
|
|
||
|
newPixel[2] = pixel[2]; // pixel color
|
||
|
newPts->SetPoint(ptId, newPixel);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Update ourselves and release memory
|
||
|
//
|
||
|
output->GetPointData()->CopyNormalsOff(); // distorted geometry
|
||
|
output->GetPointData()->PassData(input->GetPointData());
|
||
|
|
||
|
output->SetPoints(newPts);
|
||
|
newPts->Delete();
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
void vtkWarpLens::PrintSelf(ostream& os, vtkIndent indent)
|
||
|
{
|
||
|
this->Superclass::PrintSelf(os,indent);
|
||
|
|
||
|
os << indent << "PrincipalPoint: (" << this->PrincipalPoint[0] << ", "
|
||
|
<< this->PrincipalPoint[1] << ") in mm\n";
|
||
|
os << indent << "K1: " << this->K1 << "\n";
|
||
|
os << indent << "K2: " << this->K2 << "\n";
|
||
|
os << indent << "P1: " << this->P1 << "\n";
|
||
|
os << indent << "P2: " << this->P2 << "\n";
|
||
|
os << indent << "FormatWidth: " << this->FormatWidth << " in mm\n";
|
||
|
os << indent << "FormatHeight: " << this->FormatHeight << " in mm\n";
|
||
|
os << indent << "ImageWidth: " << this->ImageWidth << " in pixels\n";
|
||
|
os << indent << "ImageHeight: " << this->ImageHeight << " in pixels\n";
|
||
|
}
|