計算機視覺life從零開始一起學習SLAM 學習筆記
文章目錄
- 相機成像模型
- 討論
相機成像模型
以下題目來自計算機視覺life從零開始一起學習SLAM系列
題目: 相機視場角比較小(比如手機攝像頭)時,一般可以近似為針孔相機成像,三維世界中的直線成像也是直線,但是很多時候需要用到廣角甚至魚眼相機,此時會產生畸變,三維世界中的直線在影像里會彎曲,因此,需要做去畸變, 本題給定一張廣角畸變影像,以及相機的內參,請完成影像去畸變程序,
框架鏈接:https://pan.baidu.com/s/17KNXoprrYmY87s_xcDYK_g 密碼:z2f0
參考答案:
#include <opencv2/opencv.hpp>
using namespace std;
string image_file = "./test.png"; // 請確保路徑正確
int main(int argc, char **argv) {
double k1 = -0.28340811, k2 = 0.07395907; // 畸變引數
double fx = 458.654, fy = 457.296, cx = 367.215, cy = 248.375;
cv::Mat image = cv::imread(image_file, CV_8UC1); // 影像是灰度圖
int rows = image.rows, cols = image.cols;
cv::Mat image_undistort = cv::Mat(rows, cols, CV_8UC1); // 去畸變以后的圖
cv::imshow("image distorted", image);
// 計算去畸變后影像的內容
for (int v = 0; v < rows; v++)
for (int u = 0; u < cols; u++) {
double u_distorted = 0, v_distorted = 0;
// 開始代碼,注意(u,v)要先轉化為歸一化坐標
double x1 = (u-cx)/fx;
double y1 = (v-cy)/fy;
double r = sqrt(x1*x1 + y1*y1);
double x2 = x1*(1+k1*pow(r,2)+k2*pow(r,4));
double y2 = y1*(1+k1*pow(r,2)+k2*pow(r,4));
u_distorted = x2*fx + cx;
v_distorted = y2*fy + cy;
// 結束代碼
if (u_distorted >= 0 && v_distorted >= 0 && u_distorted < cols && v_distorted < rows) {
image_undistort.at<uchar>(v, u) = image.at<uchar>((int) v_distorted, (int) u_distorted);
} else {
image_undistort.at<uchar>(v, u) = 0;
}
}
cv::imshow("image undistorted", image_undistort);
cv::waitKey();
return 0;
}
CMakeLists.txt:
cmake_minimum_required( VERSION 2.8 )
project( undistort )
set( CMAKE_CXX_FLAGS "-std=c++11" )
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( undistort_image undistort_image.cpp )
target_link_libraries( undistort_image ${OpenCV_LIBS} )
討論
投影順序:
世界坐標系中的3D點->相機坐標系中的3D點->歸一化平面(X/Z,Y/Z,1)->乘以內參矩陣得到像素坐標(u,v),
( u v 1 ) = 1 Z ( f x 0 c x 0 f y c y 0 0 1 ) [ R t 0 T 1 ] ( x w y w z w 1 ) = 1 Z K T ( x w y w z w 1 ) \left(\begin{array}{l} u \\ v \\ 1 \end{array}\right)=\frac{1}{Z}\left(\begin{array}{ccc} f_{x} & 0 & c_{x} \\ 0 & f_{y} & c_{y} \\ 0 & 0 & 1 \end{array}\right)\left[\begin{array}{cc} \boldsymbol{R} & \boldsymbol{t} \\ \boldsymbol{0}^{T} & 1 \end{array}\right]\left(\begin{array}{c} x_{w} \\ y_{w} \\ z_{w} \\ 1 \end{array}\right)=\frac{1}{Z} \boldsymbol{K} T\left(\begin{array}{c} x_{w} \\ y_{w} \\ z_{w} \\ 1 \end{array}\right) ???uv1????=Z1????fx?00?0fy?0?cx?cy?1????[R0T?t1?]?????xw?yw?zw?1??????=Z1?KT?????xw?yw?zw?1??????
畸變主要有徑向畸變和切向畸變,
切向畸變切向畸變是由于透鏡和CMOS或者CCD的安裝位置誤差導致,隨著相機制造工藝的大大提升,這種情況很少出現了,我們一般也不考慮切向的畸變,
標定可以得到相機的所有畸變系數,用標定的畸變系數就能對畸變的影像進行去畸變,
去畸變公式:
x distorted = x ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 ) y distorted = y ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 ) r 2 = x 2 + y 2 \begin{array}{l} x_{\text {distorted }}=x\left(1+k_{1} r^{2}+k_{2} r^{4}+k_{3} r^{6}\right) \\ y_{\text {distorted }}=y\left(1+k_{1} r^{2}+k_{2} r^{4}+k_{3} r^{6}\right) \\ r^{2}=x^{2}+y^{2} \end{array} xdistorted ?=x(1+k1?r2+k2?r4+k3?r6)ydistorted ?=y(1+k1?r2+k2?r4+k3?r6)r2=x2+y2?
課后題里面利用已有的去畸變影像,也就是假設已知x,y(不知道(x,y)處的像素值),然后帶入右邊式子,最后得到一個x_distorted, y_distorted的坐標,這個坐標對應的就是扭曲的圖里的坐標,把這個坐標的像素值填入去畸變影像的(x,y)位置,
參考:
從零開始一起學習SLAM | 相機成像模型
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/280690.html
標籤:其他
上一篇:【基礎教程】基于matlab影像處理(表示方法+資料結構+基本格式+型別轉換+讀取+點運算+代數運算)【含Matlab原始碼 834期】
下一篇:雙非碩士的辛酸求職之旅--談談我是如何同時找到Java、Python、Go等開發崗和國企銀行的科技崗位Offer
