图像变换中的点变换小结

发布时间:2026/7/17 17:53:44
图像变换中的点变换小结 #include opencv2/opencv.hpp #include iostream // 20251105 透视变换逆变换 // 输入透视变换后图片上一点 透视变换矩阵 // 输出透视变换前图片上对应点 int perspInv(cv::Point2f centerPt, cv::Mat M, cv::Point2f centerPt2) { cv::Mat srcT cv::Mat::zeros(cv::Size(1, 1), CV_32FC2); srcT.atcv::Vec2f(0, 0)[0] centerPt.x; srcT.atcv::Vec2f(0, 0)[1] centerPt.y; cv::Mat M_inv; cv::invert(M, M_inv); cv::Mat srcT_inv; cv::perspectiveTransform(srcT, srcT_inv, M_inv); centerPt2.x srcT_inv.atcv::Vec3f(0, 0)[0]; centerPt2.y srcT_inv.atcv::Vec3f(0, 0)[1]; return 0; } void perspInv2(const cv::Point2f centerPt, const cv::Mat M, cv::Point2f centerPt2) { cv::Mat M_inv; cv::invert(M, M_inv); std::vectorcv::Point2f srcF{centerPt}, srcT; cv::perspectiveTransform(srcF, srcT, M_inv); centerPt2 srcT[0]; } // 20251105 去畸变逆变换 // 输入去畸变后图片上一点 相机参数 // 输出去畸变前图片上对应点 int undistInv(cv::Point2f centerPt2, cv::Mat cameraMat, cv::Mat distCoeffs, cv::Point2f centerPt3) { double cx cameraMat.atdouble(0, 2); double cy cameraMat.atdouble(1, 2); double fx cameraMat.atdouble(0, 0); double fy cameraMat.atdouble(1, 1); double k1 distCoeffs.atdouble(0, 0); double k2 distCoeffs.atdouble(0, 1); double k3 distCoeffs.atdouble(0, 4); double p1 distCoeffs.atdouble(0, 2); double p2 distCoeffs.atdouble(0, 3); double xx static_castdouble(centerPt2.x); double yy static_castdouble(centerPt2.y); xx (xx - cx) / fx; yy (yy - cy) / fy; double rr xx * xx yy * yy; double xxx xx * (1 k1 * rr k2 * rr * rr k3 * rr * rr * rr) 2 * p1 * xx * yy p2 * (rr 2 * xx * xx); double yyy yy * (1 k1 * rr k2 * rr * rr k3 * rr * rr * rr) 2 * p2 * xx * yy p1 * (rr 2 * yy * yy); centerPt3.x static_castdouble(fx * xxx cx); centerPt3.y static_castdouble(fy * yyy cy); return 0; } // 20251106 透视变换逆变换去畸变逆变换 // 输入透视变换后图片上一点 透视变换矩阵 相机参数 // 输出去畸变前图片上对应点 int perspInvAndUndistInv(cv::Point2f centerPt, cv::Mat cameraMat, cv::Mat distCoeffs, cv::Mat M, cv::Point2f centerPt3) { cv::Mat srcT cv::Mat::zeros(cv::Size(1, 1), CV_32FC2); srcT.atcv::Vec2f(0, 0)[0] centerPt.x; srcT.atcv::Vec2f(0, 0)[1] centerPt.y; cv::Mat M_inv; cv::invert(M, M_inv); cv::Mat srcT_inv; cv::perspectiveTransform(srcT, srcT_inv, M_inv); cv::Point2f centerPt2; centerPt2.x srcT_inv.atcv::Vec3f(0, 0)[0]; centerPt2.y srcT_inv.atcv::Vec3f(0, 0)[1]; double cx cameraMat.atdouble(0, 2); double cy cameraMat.atdouble(1, 2); double fx cameraMat.atdouble(0, 0); double fy cameraMat.atdouble(1, 1); double k1 distCoeffs.atdouble(0, 0); double k2 distCoeffs.atdouble(0, 1); double k3 distCoeffs.atdouble(0, 4); double p1 distCoeffs.atdouble(0, 2); double p2 distCoeffs.atdouble(0, 3); double xx static_castdouble(centerPt2.x); double yy static_castdouble(centerPt2.y); xx (xx - cx) / fx; yy (yy - cy) / fy; double rr xx * xx yy * yy; double xxx xx * (1 k1 * rr k2 * rr * rr k3 * rr * rr * rr) 2 * p1 * xx * yy p2 * (rr 2 * xx * xx); double yyy yy * (1 k1 * rr k2 * rr * rr k3 * rr * rr * rr) 2 * p2 * xx * yy p1 * (rr 2 * yy * yy); centerPt3.x static_castdouble(fx * xxx cx); centerPt3.y static_castdouble(fy * yyy cy); return 0; } // 20251105 去畸变透视变换 // 输入去畸变前图片上一点 相机参数 // 输出去畸变透视变换后图片上对应点 int undistAndPersp(cv::Point2f centerPt3, cv::Mat cameraMat, cv::Mat distCoeffs, cv::Mat M, cv::Point2f centerPt) { std::vectorcv::Point2f fromPts; fromPts.push_back(centerPt3); std::vectorcv::Point2f toPts; cv::undistortPoints(fromPts, toPts, cameraMat, distCoeffs, cv::Mat(), cameraMat); cv::Mat srcF cv::Mat::zeros(cv::Size(1, 1), CV_32FC2); srcF.atcv::Vec3f(0, 0)[0] toPts[0].x; srcF.atcv::Vec3f(0, 0)[1] toPts[0].y; cv::Mat srcT; cv::perspectiveTransform(srcF, srcT, M); centerPt.x srcT.atcv::Vec3f(0, 0)[0]; centerPt.y srcT.atcv::Vec3f(0, 0)[1]; return 0; } // 透视点变换 void persp(const cv::Point2f srcPt, const cv::Mat M, cv::Point2f dstPt) { // 合法性校验避免perspectiveTransform崩溃 CV_Assert(M.type() CV_64F M.size() cv::Size(3, 3)); std::vectorcv::Point2f src{srcPt}, dst; cv::perspectiveTransform(src, dst, M); dstPt dst[0]; } // 透视点变换2 void persp2(const cv::Point2f srcPt, const cv::Mat M, cv::Point2f dstPt) { CV_Assert(M.type() CV_64F M.rows 3 M.cols 3); const double* m M.ptrdouble(); float x srcPt.x; float y srcPt.y; // 齐次坐标分母 double w m[6] * x m[7] * y m[8]; if (std::abs(w) 1e-9) { // 无穷远点可自定义处理这里置0 dstPt cv::Point2f(0, 0); return; } double nx m[0] * x m[1] * y m[2]; double ny m[3] * x m[4] * y m[5]; dstPt.x static_castfloat(nx / w); dstPt.y static_castfloat(ny / w); } int main() { return 0; }