OpenCV 消除平面透视图像的射影失真

本系列文章由 youngpan1101 出品,转载请注明出处。
文章链接: http://blog.csdn.net/youngpan1101/article/details/53885689
作者:宋洋鹏(youngpan1101)
邮箱: yangpeng_song@163.com


参考链接


配置环境( OpenCV 库 )

  1. 运行环境:ubuntu 14.04
  2. 下载 OpenCV 2.4.13 for Linux
  3. 安装流程

    1. 安装依赖项

      $ 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
    2. 解压

      $ unzip opencv-2.4.13_linux.zip
      $ cd opencv-2.4.13
    3. 编译生成 Makefile 文件

      $ mkdir build 
      $ cd build 
      $ cmake .. -LH  # 查看 cmake 的可修改参数,实际运行可跳过该命令
      $ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/home/hwj/slambook/ThirdPartyLib ..
    4. 编译安装

      $ make -j4
      $ sudo make install
      • 测试 OpenCV 库
        perspective_transformation_01.png
      • 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;
          }

        image


相机模型

perspective_transformatioin_02.jpg

  1. 建立四个坐标系:物体固联坐标系、相机坐标系、图像坐标系 和 像素坐标系。
  2. 设物体固联坐标系上一点坐标为 Pb , 该点经过旋转+平移变换到相机坐标系下 Pcam
    xcamycamzcam1=r11r21r310r12r22r320r13r23r330txtytz1xbybzb1(1)
  3. 相机坐标系下 Pcam 经透视投影(perspective projection)变换到图像坐标系下 Pimg
    ximgxcam=yimgycam=fzcam(2)

    式中:
    f —— 相机焦距。
    由式 (2) 得:
    zcamximgyimg1=f000f0001000xcamycamzcam1(3)
  4. 图像坐标系下 Pimg 经仿射变换(affine transformation)变换到像素坐标系下 [uv]T
    uv1=1dx0001dy0u0v01ximgyimg1(4)

    式中:
    u0,v0 —— 相机坐标系原点(光心)在像素坐标系中的坐标,单位为像素;
    dx,dy —— 图像上每一个像素点在 u 轴、v 轴方向上的物理尺寸。
  5. 综合式 (1)、(3)和(4),物体固联坐标系下 Pb 变换到像素坐标系下 [uv]T
    zcamuv1=1dx0001dy0u0v01f000f0001000r11r21r310r12r22r320r13r23r330txtytz1xbybzb1(5)

共面点成像 —— planar homography

透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)、射影变换或单应(homography)。而共面点成像则是透视变换中一个特殊情况,即考虑一个平面里点的坐标变换。对于共面的物点,可以令固联坐标系中一个坐标值为 0,不妨设第三维坐标为0( 即 zb=0 ),由式 (5) 得:

zcamuv1=1dx0001dy0u0v01f000f0001000r11r21r310r12r22r320r13r23r330txtytz1xbyb01

=1dx0001dy0u0v01f000f0001r11r21r31r12r22r32txtytzxbyb1(6)

式 (6) 可以简化为:
zcamuv1=h11h21h31h12h22h32h13h23h33xbyb1=Hxbyb1(7)

由式 (7) 可得像素坐标系下 u v
u=h11xb+h12yb+h13h31xb+h32yb+h33,v=h21xb+h22yb+h23h31xb+h32yb+h33(8)

对式 (8) 进行重排,得:
h11xb+h12yb+h13h31xbuh32ybuh33u=0h21xb+h22yb+h23h31xbvh32ybvh33v=0(9)

式 (9) 是关于 H 矩阵元素的线性方程,这里设 h33=1(射影变换有八个自由度), 四组点对应提供给八个这样的关于 H 元素的线性方程,并足以解出 H (仅相差一个不重要的乘法因子),唯一的限制是这四点必须在“一般位置”上,即要求没有三个点共线。用此方法计算变换 H 的逆矩阵,然后作用于整幅图像,便可消除被选平面的射影失真效应。这里列出四个点组成的线性方程组:
xb10xb20xb30xb40yb10yb20yb30yb40101010100xb10xb20xb30xb40yb10yb20yb30yb401010101xb1u1xb1v1xb2u2xb2v2xb3u3xb3v3xb4u4xb4v4yb1u1yb1v1yb2u2yb2v2yb3u3yb3v3yb4u4yb4v4h11h12h13h21h22h23h31h32=u1v1u2v2u3v3u4v4(10)


A8×8h8×1=b8×1

通过 h=A1b 可以求得 H 矩阵。


实现步骤

  1. 灰度化处理
  2. 滤波处理
  3. 边缘检测
  4. 寻找四个点
    • 霍夫变换直线识别 [ref_1]
  5. 计算 H 矩阵
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值