I've done some sample program that removes lens distortion from the chessboard like fish eye images, and it works ok, here's the screen shot
Next I wanted to use the fish eye chessboard pattern (right image above) in order to remove the same lens distortion but from the real image and had no luck - the curvature still remains on the undistorted image, thus I got this instead
the code
void getObjectPoints(cv::Size, std::vector<std::vector<cv::Point3f>>&);
bool getImagePoints(cv::Mat&, cv::Size&, std::vector<std::vector<cv::Point2f>>&);
void runCalibration(cv::Mat& image, cv::Matx33d&, cv::Vec4d&);
cv::Mat removeFisheyeLensDist(cv::Mat&, cv::Matx33d&, cv::Vec4d&);
// ... definitions
void getObjectPoints(cv::Size patternSize, std::vector<std::vector<cv::Point3f>>& objectPoints)
{
const float squareSize = 0.0015f;
std::vector<cv::Point3f> knownBoardPositions;
for (int i = 0; i < patternSize.height; ++i)
{
for (int j = 0; j < patternSize.width; ++j)
{
knownBoardPositions.push_back(cv::Point3f(j*squareSize, i*squareSize, 0.0f));
}
}
if (knownBoardPositions.size() > 0)
objectPoints.push_back(knownBoardPositions);
}
bool getImagePoints(cv::Mat& image, cv::Size& patternSize, std::vector<std::vector<cv::Point2f>>& imagePoints)
{
bool patternFound = false;
while (!patternFound)
{
std::vector<cv::Point2f> corners;
for (int i = 7; i <= 30; ++i)
{
int w = i;
int h = i - 2;
patternFound = cv::findChessboardCorners(image, cv::Size(w, h), corners,
cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_NORMALIZE_IMAGE);
if (patternFound)
{
patternSize.width = w;
patternSize.height = h;
imagePoints.push_back(corners);
break;
}
}
}
return patternFound;
}
void runCalibration(cv::Mat& image, cv::Matx33d& K, cv::Vec4d& D)
{
std::vector< std::vector<cv::Point2f> > imagePoints;
std::vector< std::vector<cv::Point3f> > objectPoints;
cv::Size patternSize;
bool patternFound = getImagePoints(image, patternSize, imagePoints);
if (patternFound)
{
getObjectPoints(patternSize, objectPoints);
std::vector<cv::Vec3d> rvecs;
std::vector<cv::Vec3d> tvecs;
cv::fisheye::calibrate(
objectPoints,
imagePoints,
image.size(),
K,
D,
rvecs,
tvecs,
cv::fisheye::CALIB_FIX_SKEW | cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC
| cv::fisheye::CALIB_FIX_K1 | cv::fisheye::CALIB_FIX_K2
| cv::fisheye::CALIB_FIX_K3 | cv::fisheye::CALIB_FIX_K4
// cv::TermCriteria(3, 20, 1e-6)
);
}
}
cv::Mat removeFisheyeLensDist(cv::Mat& distorted, cv::Matx33d& K, cv::Vec4d& D)
{
cv::Mat undistorted;
cv::Matx33d newK = K;
cv::fisheye::undistortImage(distorted, undistorted, K, D, newK);
return undistorted;
}
int main(int argc, char* argv[])
{
cv::Mat chessBoardPattern = //..
cv::Mat distortedImage = //...
cv::imshow("distorted", distortedImage);
cv::Matx33d K; cv::Vec4d D;
runCalibration(chessBoardPattern, K, D);
cv::Mat undistoredImage = removeFisheyeLensDist(distortedImage, K, D);
cv::imshow("undistored", undistoredImage);
cv::waitKey(0);
return 0;
}
As I think the image with the tower has very simillar curvatures as a chessboard on the right so the same pattern should've work for tower image ...
What Am I doing wrong there ? And Why it's not fixing lens distortion for the tower image ?