#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <fstream>
using namespace cv;
using namespace std;
class DistortF :public cv::MinProblemSolver::Function
{
public:
DistortF(double _distortU, double _distortV) : distortU(_distortU), distortV(_distortV)
{
Mat cameraMatrix = (Mat_<double>(3, 3) << 422.47278482, 0., 337.95105539, 0., 421.51185173, 230.2749964, 0., 0., 1.);
inverseCameraMatrix = (cameraMatrix.colRange(0,3)).inv(DECOMP_LU);
k1 = -0.36446607;
k2 = 0.10597863;
p1 = 0.00088569;
p2 = -0.00112412;
k3 = 0.;
k4 = 0.;
k5 = 0.;
k6 = 0.;
s1 = 0.;
s2 = 0.;
s3 = 0.;
s4 = 0.;
tauX = 0.;
tauY = 0.;
}
int getDims() const { return 2; }
double calc(const double* x)const{
double undistortU = x[0];
double undistortV = x[1];
const double* ir = &inverseCameraMatrix(0, 0);
//cout<< ir[0]<<endl;
Mat cameraMatrix = (Mat_<double>(3, 3) << 422.47278482, 0, 337.95105539, 0, 421.51185173, 230.2749964, 0, 0, 1);
const double* pA = (const double*)cameraMatrix.data;
double Xd = undistortU * ir[0] + undistortV * ir[1] + ir[2], Yd = undistortU * ir[3] + undistortV * ir[4] + ir[5], Wd = undistortU * ir[6] + undistortV * ir[7] + ir[8];
Wd = 1. / Wd;
Xd = Xd * Wd;
Yd = Yd * Wd;
double Xd_2 = Xd*Xd, Yd_2 = Yd * Yd, r_2 = Xd_2 + Yd_2, _2XdYd = 2 * Xd * Yd;
double kr = (1 + ((k3*r_2 + k2)*r_2 + k1)*r_2) / (1 + ((k6*r_2 + k5)*r_2 + k4)*r_2);
double Xdd = (Xd*kr + p1*_2XdYd + p2*(r_2 + 2 * Xd_2) + s1*r_2 + s2*r_2*r_2);;
double Ydd = (Yd*kr + p1*(r_2 + 2 * Yd_2) + p2*_2XdYd + s3*r_2 + s4*r_2*r_2);
double Wdd = Wd;
double distortU_d = pA[0] * Xdd + pA[1] * Ydd + pA[2] * Wdd;
double distortV_d = pA[3] * Xdd + pA[4] * Ydd + pA[5] * Wdd;
//printf("%f\n",sqrt((distortU - distortU_d) * (distortU - distortU_d) + (distortV - distortV_d) * (distortV - distortV_d)));
return sqrt((distortU - distortU_d) * (distortU - distortU_d) + (distortV - distortV_d) * (distortV - distortV_d));
}
private:
double distortU, distortV;
double k1;
double k2;
double p1;
double p2;
double k3;
double k4;
double k5;
double k6;
double s1;
double s2;
double s3;
double s4;
double tauX;
double tauY;
Mat_<double> inverseCameraMatrix;
};
string image_file = "images/4433.jpg";
int main() {
cv::Mat image = cv::imread(image_file,0); // 图像是灰度图,CV_8UC1
int rows = image.rows, cols = image.cols;
cv::Mat image_undistort = cv::Mat(rows, cols, CV_8UC1);
ofstream oFile;
oFile.open("/2.csv", ios::out | ios::trunc);
oFile << "x_distortion" << "," << "y_distortion" << "," << "x_nodistor" << "," << "y_nodistor" << endl;
for (int v_distorted = 0; v_distorted < rows; v_distorted++)
for (int u_distorted = 0; u_distorted < cols; u_distorted++) {
double u = 0, v = 0;
cv::Ptr<cv::DownhillSolver> solver = cv::DownhillSolver::create();
cv::Ptr<cv::MinProblemSolver::Function> ptr_F = cv::makePtr<DistortF>(u_distorted, v_distorted);//x,y为有畸变的点
int lFaliedUndistCount=0;
cv::Mat solution;
solution= (cv::Mat_<double>(1, 2) << u_distorted, v_distorted);
cv::Mat step;
step= (cv::Mat_<double>(2, 1) << -0.5, -0.5);
solver->setFunction(ptr_F);
solver->setInitStep(step);
float res=solver->minimize(solution);
// cout<<res<<endl;
u = solution.at<double>(0, 0);
v = solution.at<double>(0, 1);
if (u>= 0 && v >= 0 && u < cols && v < rows) {
int a=0;
a=image.at<uchar>((int) v_distorted, (int) u_distorted);
image_undistort.at<uchar>((int)v, (int)u) =a;
}
oFile << u_distorted << "," << v_distorted<< "," << (int)u << "," << (int)v << endl;
}
cv::imshow("image undistorted", image_undistort);
cv::waitKey();
return 0;
}
对应的cmake.txt
cmake_minimum_required(VERSION 3.10)
project(untitled8)
set(CMAKE_CXX_STANDARD 11)
add_executable(untitled8 main.cpp)
target_link_libraries(untitled8 opencv_core opencv_highgui opencv_imgproc opencv_imgcodecs )
必须opencv3,这个是3.3.0
单个点的:
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"
#include<time.h>
#define UNDISTORT_FAILED_THRES 0.1
using namespace cv;
using namespace std;
//非线性最小化计算函数
class DistortF :public cv::MinProblemSolver::Function
{
public:
DistortF(double _distortU, double _distortV) : distortU(_distortU), distortV(_distortV)
{
Mat cameraMatrix = (Mat_<double>(3, 3) << 422.47278482, 0., 337.95105539, 0., 421.51185173, 230.2749964, 0., 0., 1.);
inverseCameraMatrix = (cameraMatrix.colRange(0,3)).inv(DECOMP_LU);
k1 = -0.36446607;
k2 = 0.10597863;
p1 = 0.00088569;
p2 = -0.00112412;
k3 = 0.;
k4 = 0.;
k5 = 0.;
k6 = 0.;
s1 = 0.;
s2 = 0.;
s3 = 0.;
s4 = 0.;
tauX = 0.;
tauY = 0.;
}
int getDims() const { return 2; }
double calc(const double* x)const{
double undistortU = x[0];
double undistortV = x[1];
const double* ir = &inverseCameraMatrix(0, 0);
//cout<< ir[0]<<endl;
Mat cameraMatrix = (Mat_<double>(3, 3) << 422.47278482, 0, 337.95105539, 0, 421.51185173, 230.2749964, 0, 0, 1);
const double* pA = (const double*)cameraMatrix.data;
double Xd = undistortU * ir[0] + undistortV * ir[1] + ir[2], Yd = undistortU * ir[3] + undistortV * ir[4] + ir[5], Wd = undistortU * ir[6] + undistortV * ir[7] + ir[8];
Wd = 1. / Wd;
Xd = Xd * Wd;
Yd = Yd * Wd;
double Xd_2 = Xd*Xd, Yd_2 = Yd * Yd, r_2 = Xd_2 + Yd_2, _2XdYd = 2 * Xd * Yd;
double kr = (1 + ((k3*r_2 + k2)*r_2 + k1)*r_2) / (1 + ((k6*r_2 + k5)*r_2 + k4)*r_2);
double Xdd = (Xd*kr + p1*_2XdYd + p2*(r_2 + 2 * Xd_2) + s1*r_2 + s2*r_2*r_2);;
double Ydd = (Yd*kr + p1*(r_2 + 2 * Yd_2) + p2*_2XdYd + s3*r_2 + s4*r_2*r_2);
double Wdd = Wd;
double distortU_d = pA[0] * Xdd + pA[1] * Ydd + pA[2] * Wdd;
double distortV_d = pA[3] * Xdd + pA[4] * Ydd + pA[5] * Wdd;
//printf("%f\n",sqrt((distortU - distortU_d) * (distortU - distortU_d) + (distortV - distortV_d) * (distortV - distortV_d)));
return sqrt((distortU - distortU_d) * (distortU - distortU_d) + (distortV - distortV_d) * (distortV - distortV_d));
}
private:
double distortU, distortV;
double k1;
double k2;
double p1;
double p2;
double k3;
double k4;
double k5;
double k6;
double s1;
double s2;
double s3;
double s4;
double tauX;
double tauY;
Mat_<double> inverseCameraMatrix;
};
//输入畸变图中的x,y点
int main() {
double x,y;
cout << "Input x: ";
cin >> x;
cout << "Input y: ";
cin >> y;
clock_t start,finish;
double totaltime;
start=clock();
cv::Ptr<cv::DownhillSolver> solver = cv::DownhillSolver::create();
cv::Ptr<cv::MinProblemSolver::Function> ptr_F = cv::makePtr<DistortF>(x, y);//x,y为有畸变的点
int lFaliedUndistCount=0;
cv::Mat solution;
solution= (cv::Mat_<double>(1, 2) << x, y);
cv::Mat step;
step= (cv::Mat_<double>(2, 1) << -0.5, -0.5);
solver->setFunction(ptr_F);
solver->setInitStep(step);
float res=solver->minimize(solution);
// cout<<res<<endl;
double u = solution.at<double>(0, 0);
double v = solution.at<double>(0, 1);
finish=clock();
totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
cout<<"\n此程序的运行时间为"<<totaltime<<"秒!"<<endl;
cout<<int(u)<<endl;
cout<<int(v)<<endl;
}