本系列文章由 youngpan1101 出品,转载请注明出处。
文章链接: http://blog.csdn.net/youngpan1101/article/details/53885689
作者:宋洋鹏(youngpan1101)
邮箱: yangpeng_song@163.com
参考链接
配置环境( OpenCV 库 )
- 运行环境:ubuntu 14.04
- 下载 OpenCV 2.4.13 for Linux
安装流程
安装依赖项
$ sudo apt-get install build-essential libgtk2.0-dev libjpeg-dev libtiff4-dev libjasper-dev libopenexr-dev cmake python-dev python-numpy python-tk libtbb-dev libeigen3-dev yasm libfaac-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev libx264-dev libqt4-dev libqt4-opengl-dev sphinx-common texlive-latex-extra libv4l-dev libdc1394-22-dev libavcodec-dev libavformat-dev libswscale-dev default-jdk ant libvtk5-qt4-dev
解压
$ unzip opencv-2.4.13_linux.zip $ cd opencv-2.4.13
编译生成 Makefile 文件
$ mkdir build $ cd build $ cmake .. -LH # 查看 cmake 的可修改参数,实际运行可跳过该命令 $ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/home/hwj/slambook/ThirdPartyLib ..
编译安装
$ make -j4 $ sudo make install
- 测试 OpenCV 库
CMakeLists.txt
cmake_minimum_required(VERSION 2.8) project(perspective-transformation) # set compiler properties set(CMAKE_CXX_COMPILER "g++") # enable verbose makefile log set(CMAKE_VERBOSE_MAKEFILE on) # set the directory for executable file set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) # set the directory for output lib set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) link_directories(${LIBRARY_OUTPUT_PATH}) # set the directory for header install_files include_directories(${PROJECT_SOURCE_DIR}/include) # set the directory for source files set(SOURCE_DIR ${PROJECT_SOURCE_DIR}/src) set(MAIN_SRC ${SOURCE_DIR}/main.cpp) add_executable(perspective-transformation-demo ${MAIN_SRC}) # add opencv lib set(OpenCV_2_4_13_INCLUDE_DIR /home/hwj/slambook/ThirdPartyLib/include) include_directories(${OpenCV_2_4_13_INCLUDE_DIR}) set(OpenCV_2_4_13_LIBS_DIR /home/hwj/slambook/ThirdPartyLib/lib) set(OpenCV_2_4_13_LIBS ${OpenCV_2_4_13_LIBS_DIR}/libopencv_core.so ${OpenCV_2_4_13_LIBS_DIR}/libopencv_imgproc.so ${OpenCV_2_4_13_LIBS_DIR}/libopencv_highgui.so) # produce lib # link libs target_link_libraries(perspective-transformation-demo ${OpenCV_2_4_13_LIBS} -lstdc++ -lpthread)
src/main.cpp
#include <iostream> //opencv Header #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> int main(int argc, char** argv) { std::cout << "Hello world..." << std::endl; std::string imgPath = "../img_L90_W54.jpg"; cv::Mat img = cv::imread(imgPath); if(img.empty()) { std::cout << "fail to load image..." << std::endl; return -1; } cv::namedWindow("image", CV_WINDOW_AUTOSIZE); cv::imshow("image", img); cv::waitKey(0); cv::destroyWindow("image"); return 1; }
- 测试 OpenCV 库
相机模型
- 建立四个坐标系:物体固联坐标系、相机坐标系、图像坐标系 和 像素坐标系。
- 设物体固联坐标系上一点坐标为
Pb
, 该点经过旋转+平移变换到相机坐标系下
Pcam
:
⎡⎣⎢⎢⎢xcamycamzcam1⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢⎢r11r21r310r12r22r320r13r23r330txtytz1⎤⎦⎥⎥⎥⎥⎡⎣⎢⎢⎢xbybzb1⎤⎦⎥⎥⎥(1) - 相机坐标系下
Pcam
经透视投影(perspective projection)变换到图像坐标系下
Pimg
:
ximgxcam=yimgycam=fzcam(2)
式中:
f —— 相机焦距。
由式 (2) 得:
zcam⎡⎣⎢ximgyimg1⎤⎦⎥=⎡⎣⎢f000f0001000⎤⎦⎥⎡⎣⎢⎢⎢xcamycamzcam1⎤⎦⎥⎥⎥(3) - 图像坐标系下
Pimg
经仿射变换(affine transformation)变换到像素坐标系下
[uv]T
:
⎡⎣⎢uv1⎤⎦⎥=⎡⎣⎢⎢⎢⎢⎢1dx0001dy0u0v01⎤⎦⎥⎥⎥⎥⎥⎡⎣⎢ximgyimg1⎤⎦⎥(4)
式中:
u0,v0 —— 相机坐标系原点(光心)在像素坐标系中的坐标,单位为像素;
dx,dy —— 图像上每一个像素点在 u 轴、v 轴方向上的物理尺寸。 - 综合式 (1)、(3)和(4),物体固联坐标系下
Pb
变换到像素坐标系下
[uv]T
:
zcam⎡⎣⎢uv1⎤⎦⎥=⎡⎣⎢⎢⎢⎢⎢1dx0001dy0u0v01⎤⎦⎥⎥⎥⎥⎥⎡⎣⎢f000f0001000⎤⎦⎥⎡⎣⎢⎢⎢⎢r11r21r310r12r22r320r13r23r330txtytz1⎤⎦⎥⎥⎥⎥⎡⎣⎢⎢⎢xbybzb1⎤⎦⎥⎥⎥(5)
共面点成像 —— planar homography
透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)、射影变换或单应(homography)。而共面点成像则是透视变换中一个特殊情况,即考虑一个平面里点的坐标变换。对于共面的物点,可以令固联坐标系中一个坐标值为 0,不妨设第三维坐标为0( 即
zb=0
),由式 (5) 得:
zcam⎡⎣⎢uv1⎤⎦⎥=⎡⎣⎢⎢⎢⎢⎢1dx0001dy0u0v01⎤⎦⎥⎥⎥⎥⎥⎡⎣⎢f000f0001000⎤⎦⎥⎡⎣⎢⎢⎢⎢r11r21r310r12r22r320r13r23r330txtytz1⎤⎦⎥⎥⎥⎥⎡⎣⎢⎢⎢xbyb01⎤⎦⎥⎥⎥
=⎡⎣⎢⎢⎢⎢⎢1dx0001dy0u0v01⎤⎦⎥⎥⎥⎥⎥⎡⎣⎢f000f0001⎤⎦⎥⎡⎣⎢r11r21r31r12r22r32txtytz⎤⎦⎥⎡⎣⎢xbyb1⎤⎦⎥(6)
式 (6) 可以简化为:
zcam⎡⎣⎢uv1⎤⎦⎥=⎡⎣⎢h11h21h31h12h22h32h13h23h33⎤⎦⎥⎡⎣⎢xbyb1⎤⎦⎥=H⎡⎣⎢xbyb1⎤⎦⎥(7)
由式 (7) 可得像素坐标系下 u 和
u=h11xb+h12yb+h13h31xb+h32yb+h33,v=h21xb+h22yb+h23h31xb+h32yb+h33(8)
对式 (8) 进行重排,得:
h11xb+h12yb+h13−h31xbu−h32ybu−h33u=0h21xb+h22yb+h23−h31xbv−h32ybv−h33v=0(9)
式 (9) 是关于 H 矩阵元素的线性方程,这里设
即
A8×8h8×1=b8×1
通过 h=A−1b 可以求得 H 矩阵。
实现步骤
- 灰度化处理
- 滤波处理
- 边缘检测
- 寻找四个点
- 霍夫变换直线识别 [ref_1]
- 计算
H 矩阵- 消除透视失真 [OpenCV仿射变换]
- 最后的效果如下图,代码链接 [code]
- 消除透视失真 [OpenCV仿射变换]