mirror of
https://github.com/opencv/opencv.git
synced 2026-07-25 21:33:04 +04:00
40ddc700aa
Inverted imgproc-geometry dependency and moved more functions to geometry #29230 Fixes: https://github.com/opencv/opencv/issues/20267 Continues: https://github.com/opencv/opencv/pull/29175 OpenCV Contrib: https://github.com/opencv/opencv_contrib/pull/4137 OpenCV Extra: https://github.com/opencv/opencv_extra/pull/1377 Summary: - LSD returned back to imgproc - drawing functions moved to imgproc - undistort image and related perf-pixel functions moved to imgproc - moments moved to geometry - estimateXXXtransform moved to geometry After the patch the geometry module depends on code and Flann and may be used everywhere without potential circular dependencies ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [ ] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake
129 lines
4.5 KiB
C++
129 lines
4.5 KiB
C++
// This file is part of OpenCV project.
|
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
|
// of this distribution and at http://opencv.org/license.html
|
|
|
|
#include "precomp.hpp"
|
|
#include "opencv2/core/affine.hpp"
|
|
|
|
namespace cv {
|
|
namespace fisheye {
|
|
|
|
void initUndistortRectifyMap( InputArray K, InputArray D, InputArray R, InputArray P,
|
|
const cv::Size& size, int m1type, OutputArray map1, OutputArray map2 )
|
|
{
|
|
CV_INSTRUMENT_REGION();
|
|
|
|
CV_Assert( m1type == CV_16SC2 || m1type == CV_32F || m1type <=0 );
|
|
map1.create( size, m1type <= 0 ? CV_16SC2 : m1type );
|
|
map2.create( size, map1.type() == CV_16SC2 ? CV_16UC1 : CV_32F );
|
|
|
|
CV_Assert((K.depth() == CV_32F || K.depth() == CV_64F) && (D.depth() == CV_32F || D.depth() == CV_64F));
|
|
CV_Assert((P.empty() || P.depth() == CV_32F || P.depth() == CV_64F) && (R.empty() || R.depth() == CV_32F || R.depth() == CV_64F));
|
|
CV_Assert(K.size() == Size(3, 3) && (D.empty() || D.total() == 4));
|
|
CV_Assert(R.empty() || R.size() == Size(3, 3) || R.total() * R.channels() == 3);
|
|
CV_Assert(P.empty() || P.size() == Size(3, 3) || P.size() == Size(4, 3));
|
|
|
|
Vec2d f, c;
|
|
if (K.depth() == CV_32F)
|
|
{
|
|
Matx33f camMat = K.getMat();
|
|
f = Vec2f(camMat(0, 0), camMat(1, 1));
|
|
c = Vec2f(camMat(0, 2), camMat(1, 2));
|
|
}
|
|
else
|
|
{
|
|
Matx33d camMat = K.getMat();
|
|
f = Vec2d(camMat(0, 0), camMat(1, 1));
|
|
c = Vec2d(camMat(0, 2), camMat(1, 2));
|
|
}
|
|
|
|
Vec4d k = Vec4d::all(0);
|
|
if (!D.empty())
|
|
k = D.depth() == CV_32F ? (Vec4d)*D.getMat().ptr<Vec4f>(): *D.getMat().ptr<Vec4d>();
|
|
|
|
Matx33d RR = Matx33d::eye();
|
|
if (!R.empty() && R.total() * R.channels() == 3)
|
|
{
|
|
Vec3d rvec;
|
|
R.getMat().convertTo(rvec, CV_64F);
|
|
RR = Affine3d(rvec).rotation();
|
|
}
|
|
else if (!R.empty() && R.size() == Size(3, 3))
|
|
R.getMat().convertTo(RR, CV_64F);
|
|
|
|
Matx33d PP = Matx33d::eye();
|
|
if (!P.empty())
|
|
P.getMat().colRange(0, 3).convertTo(PP, CV_64F);
|
|
|
|
Matx33d iR = (PP * RR).inv(cv::DECOMP_SVD);
|
|
|
|
for( int i = 0; i < size.height; ++i)
|
|
{
|
|
float* m1f = map1.getMat().ptr<float>(i);
|
|
float* m2f = map2.getMat().ptr<float>(i);
|
|
short* m1 = (short*)m1f;
|
|
ushort* m2 = (ushort*)m2f;
|
|
|
|
double _x = i*iR(0, 1) + iR(0, 2),
|
|
_y = i*iR(1, 1) + iR(1, 2),
|
|
_w = i*iR(2, 1) + iR(2, 2);
|
|
|
|
for( int j = 0; j < size.width; ++j)
|
|
{
|
|
double u, v;
|
|
if( _w <= 0)
|
|
{
|
|
u = (_x > 0) ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();
|
|
v = (_y > 0) ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity();
|
|
}
|
|
else
|
|
{
|
|
double x = _x/_w, y = _y/_w;
|
|
|
|
double r = sqrt(x*x + y*y);
|
|
double theta = std::atan(r);
|
|
|
|
double theta2 = theta*theta, theta4 = theta2*theta2, theta6 = theta4*theta2, theta8 = theta4*theta4;
|
|
double theta_d = theta * (1 + k[0]*theta2 + k[1]*theta4 + k[2]*theta6 + k[3]*theta8);
|
|
|
|
double scale = (r == 0) ? 1.0 : theta_d / r;
|
|
u = f[0]*x*scale + c[0];
|
|
v = f[1]*y*scale + c[1];
|
|
}
|
|
|
|
if( m1type == CV_16SC2 )
|
|
{
|
|
int iu = cv::saturate_cast<int>(u*static_cast<double>(cv::INTER_TAB_SIZE));
|
|
int iv = cv::saturate_cast<int>(v*static_cast<double>(cv::INTER_TAB_SIZE));
|
|
m1[j*2+0] = (short)(iu >> cv::INTER_BITS);
|
|
m1[j*2+1] = (short)(iv >> cv::INTER_BITS);
|
|
m2[j] = (ushort)((iv & (cv::INTER_TAB_SIZE-1))*cv::INTER_TAB_SIZE + (iu & (cv::INTER_TAB_SIZE-1)));
|
|
}
|
|
else if( m1type == CV_32FC1 )
|
|
{
|
|
m1f[j] = (float)u;
|
|
m2f[j] = (float)v;
|
|
}
|
|
|
|
_x += iR(0, 0);
|
|
_y += iR(1, 0);
|
|
_w += iR(2, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void undistortImage(InputArray distorted, OutputArray undistorted,
|
|
InputArray K, InputArray D, InputArray Knew, const Size& new_size)
|
|
{
|
|
CV_INSTRUMENT_REGION();
|
|
|
|
Size size = !new_size.empty() ? new_size : distorted.size();
|
|
|
|
Mat map1, map2;
|
|
fisheye::initUndistortRectifyMap(K, D, Matx33d::eye(), Knew, size, CV_16SC2, map1, map2 );
|
|
cv::remap(distorted, undistorted, map1, map2, INTER_LINEAR, BORDER_CONSTANT);
|
|
}
|
|
|
|
} // namespace fisheye
|
|
} // namespace cv
|