一、CMakeLists文件
cmake_minimum_required(VERSION
3.15)
project(undistorImage
)
find_package(OpenCV REQUIRED
)
include_directories($
{OpenCV_INCLUDE_DIRS
})
set(CMAKE_CXX_STANDARD
14)
add_executable(undistorImage main
.cpp
)
target_link_libraries(undistorImage $
{OpenCV_LIBS
})
二、.cpp文件
#include <iostream>
#include <opencv2
#include <string>
using namespace std
;
string image_file
= "/home/zhangman/slambook2-master/ch5/imageBasics/distorted.png";
int main() {
double k1
= -0.28340811,k2
= 0.07395907, p1
= 0.00019359, p2
= 1.76187114e-05;
double fx
= 458.654, fy
= 457.296, cx
= 367.215, cy
= 248.375;
cv
::Mat image
= cv
::imread(image_file
,0);
int rows
= image
.rows
,cols
= image
.cols
;
cv
::Mat image_undistored
= cv
::Mat(rows
,cols
,CV_8UC1
);
for(int v
= 0; v
< rows
; v
++){
for(int u
= 0; u
< cols
; u
++){
double x
= (u
- cx
) / fx
, y
= (v
- cy
) / fy
;
double r
= sqrt(x
* x
+ y
*y
);
double x_distored
= x
* (1 + k1
* r
* r
+ k2
* r
* r
* r
* r
) + 2 * p1
* x
* y
+ p2
* (r
* r
+ 2 * x
* x
);
double y_distored
= y
* (1 + k1
* r
* r
+ k2
* r
* r
* r
* r
) + p1
* (r
* r
+ 2 * y
* y
) + 2 * p2
* x
* y
;
double u_distored
= x_distored
* fx
+ cx
;
double v_distored
= y_distored
* fy
+ cy
;
if(v_distored
> 0 && u_distored
> 0 && u_distored
< cols
&& v_distored
< rows
){
image_undistored
.at
<uchar
>(v
,u
) = image
.at
<uchar
>((int) v_distored
, (int) u_distored
);
} else{
image_undistored
.at
<uchar
>(v
,u
) = 0;
}
}
}
cv
::imshow("image_distored", image
);
cv
::imshow("image_undistored", image_undistored
);
cv
::waitKey(0);
cv
::destroyAllWindows();
return 0;
}
三、imread()第二个参数数值详解
四、opencv中Mat格式的数据访问.at
opencv3中图形存储基本为Mat格式,如果我们想获取像素点的灰度值或者RGB值,可以通过image.at(i,j)的方式轻松获取。
Mat类中的at方法对于获取图像矩阵某点的RGB值或者改变某点的值很方便,对于单通道的图像,则可以使用:
image
.at
<uchar
>(i
, j
)
其中有一个要注意的地方是i对应的是点的y坐标,j对应的是点的x坐标,而不是我们习惯的(x,y)
来获取或改变该点的值,而RGB通道的则可以使用:
image
.at
<Vec3b
>(i
, j
)[0]
image
.at
<Vec3b
>(i
, j
)[1]
image
.at
<Vec3b
>(i
, j
)[2]