zoukankan      html  css  js  c++  java
  • OpenCV 函数 estimateRigidTransform 使用心得

    最近发现网上关于 estimateRigidTransform 的详细说明很少,因此这里做一个详细的解释。希望对大家有用。

    一、函数定义如下:

    Mat estimateRigidTransform(InputArraysrc,InputArraydst,boolfullAffine)

    前两个参数,可以是 :src=srcImage (变换之前的图片Mat) dst=transImage(变换之后的图片Mat)
    也可以: src=array(变换之前的关键点Array) dst=array(变换之后的关键点Array)
    第三个参数: 1(全仿射变换,包括:rotation, translation, scaling,shearing,reflection)

    0(带有约束的仿射变换)

    默认参数1:全仿射变换。

    fullAffine 与 partialAaffine 主要区别是:变换矩阵中后者可以是刚体变换。(不是必须,体会可以的含义)
    也就可以后者没有尺度缩放。

    二、直观感受:

    paritcalAffine 的变换矩阵必须是如下类型:

    旋转矩阵对角线元素的 绝对值 肯定相等。

    假设我们的矩阵

    |a11|=|a22| 同时|a21|=|a22|.真是基本条件。

    fullAffine 的rotate矩阵可以是:

    旋转矩阵可以没有任何数值上的约束。aii之间无数值上的约束。

    三、fullAffine原理及变换公式
    如果我们有一个点变换之前是[x,y,1],变换后是[x',y',1] 则fullAffine表示如下:

     

     

     展开后表示

     如果我们想求这【a-f】 6个变量需要有6个方程,也就是3组点。但是比三个点多呢?
    比如:20个点。那就是用最小方差。

    四、partial affine的原理及变换公式

    1.尺度变换

     

    2.旋转矩阵

     

    1、2结合后

    注意:这里的tx 指的是x方向的transpose (平移),ty同理。

    解这个T需要四个方程:也就是两组点。同样,点多的情况下用最小方差原理。计算最优变换。

     1 #ifndef _HEAD_H_
     2 #define _HEAD_H_
     3 
     4 #include
     5 
     6 /* definitions of Macros */
     7  
     8 #define PI 3.141592 
     9 #define MAX_COUNT 30 
    10 cv::Mat preTransGray, curTransGray; 
    11 cv::Mat preRotaGray , curRotaGray; 
    12 std::vector transPoints[2], rotaPoints[2],knowPoint[2]; std::vector status; std::vectorerr; 
    13 
    14 void testOpticalFlowEstimation()
    15 { 
    16   std::cout << "optical flow methon for estimating the transform form reference scan " << "to reference scan ..." << std::endl; double refPose_x = 250, refPose_y = 250; // Init rectangle center 
    17   cv::Mat trans_src_image = cv::imread("./testImage/squareRef.png"); // resolution: 500*500 and the rectangle center is (250,250) 
    18   cv::Mat trans_dst_image = cv::imread("./testImage/squareCur.png"); // resolution: 500*500 and the rectangle center is (260,240) 
    19   cv::Mat rota_src_image = cv::imread("./testImage/rotateRectRef.png"); 
    20   cv::Mat rota_dst_image = cv::imread("./testImage/rotateRectCur.png"); 
    21   cv::Mat contra_image = cv::imread("./testImage/contrastRef_Rotate.png"); 
    22   cvtColor(trans_src_image,preTransGray, cv::COLOR_BGR2GRAY); 
    23   cvtColor(trans_dst_image,curTransGray, cv::COLOR_BGR2GRAY); 
    24   cvtColor(rota_src_image,preRotaGray, cv::COLOR_BGR2GRAY); 
    25   cvtColor(rota_dst_image,curRotaGray, cv::COLOR_BGR2GRAY); 
    26   cv::TermCriteria termcrit(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 20 ,0.01); 
    27   cv::Size subPixWinSize(10,10), winSize(31,31); 
    28   goodFeaturesToTrack(preTransGray,transPoints[0],MAX_COUNT,0.01,10); // 
    29   find corners goodFeaturesToTrack(preRotaGray,rotaPoints[0],MAX_COUNT,0.01,10); // find corners /*subpiexl detection*/ //
    30   cornerSubPix(curGray,points[0],subPixWinSize,cv::Size(-1,-1),termcrit); 
    31   cornerSubPix(preTransGray,transPoints[0],subPixWinSize,cv::Size(-1,-1),termcrit); 
    32   cornerSubPix(preRotaGray,rotaPoints[0],subPixWinSize,cv::Size(-1,-1),termcrit); /*PryLK method calculate optical flow*/ //
    33   calcOpticalFlowPyrLK(preGray,curGray,points[0],points[1],status,err,winSize,5,termcrit,0,0.01); 
    34   calcOpticalFlowPyrLK(preTransGray,curTransGray,transPoints[0],transPoints[1],status,err,winSize,3,termcrit,0,0.01); 
    35   calcOpticalFlowPyrLK(preRotaGray,curRotaGray,rotaPoints[0],rotaPoints[1],status,err,winSize,3,termcrit,0,0.01); // Notice the last para in estimateRigidTransform func 
    36 
    37   // if you choose 0 : partAffine , indicate you will perform a rigid transform // choose 1 : fullAffine , indicate you will perform a non-rigid transfrom 
    38   cv::Mat transEstimate = estimateRigidTransform(transPoints[0],transPoints[1],0); 
    39   cv::Mat rotaEstimate = estimateRigidTransform(rotaPoints[0],rotaPoints[1],0); 
    40   #if 0 
    41   This program silce tests some points rigid transform Note :that we already know the Points position before & after transform 
    42   #endif 
    43   cv::Point2f a(230,220),b(270,220),c(270,280),d(230,280); 
    44   cv::Point2f Ta(220,270),Tb(220,230),Tc(280,230),Td(280,270); 
    45   knowPoint[0].push_back(a), knowPoint[1].push_back(Ta); 
    46   knowPoint[0].push_back(b), knowPoint[1].push_back(Tb); 
    47   knowPoint[0].push_back(c), knowPoint[1].push_back(Tc);
    48   knowPoint[0].push_back(d), knowPoint[1].push_back(Td);
    49   cv::Mat pointEstimate = estimateRigidTransform(knowPoint[0],knowPoint[1],0); 
    50   std::cout << "pointEstimate : 
    " << pointEstimate << std::endl; std::cout << "transEstimate : 
    " << transEstimate << std::endl; std::cout << 
    51           "rotaEstimate : 
    " << rotaEstimate << std::endl; std::cout << "Test: before transform the center is " << refPose_x <<" "<< refPose_y << std::endl; refPose_x = transEstimate.at
    52       (0)* refPose_x + transEstimate.at
    53       (1)* refPose_y + transEstimate.at
    54       (2); refPose_y = transEstimate.at
    55       (3)* refPose_x + transEstimate.at
    56       (4)* refPose_y + transEstimate.at
    57       (5);
    58   bool displayKeypoints = false; 
    59   if(displayKeypoints) 
    60   { 
    61     for(auto c:transPoints[0]) 
    62     { 
    63       std::cout << c << std::endl; circle(preTransGray,c,2,cv::Scalar(0,15,255),-1); 
    64     } 
    65     std::cout << "========================== " << std::endl; 
    66     for(auto c:transPoints[1]) 
    67     { 
    68       std::cout << c << std::endl; circle(curTransGray,c,2,cv::Scalar(0,97,25),-1); 
    69     } 
    70   } 
    71   cv::imshow("preGray",preTransGray); 
    72   cv::waitKey(0); 
    73   cv::imshow("vertGray",curTransGray); 
    74   cv::waitKey(0); 
    75   std::cout << "Test after transform the center is " << refPose_x << " "<< refPose_y << std::endl; 
    76 } 
    77 
    78 #endif
  • 相关阅读:
    MFC9.0 Outlook控件的标题显示无法修改
    VS2010 单文档+多视图+Outlook风格
    在VS2010中使用Outlook工具栏
    在MFC中添加用户自定义消息
    读书笔记——Windows环境下32位汇编语言程序设计(13)关于EXCEPTION_DEBUG_INFO结构体
    读书笔记——Windows环境下32位汇编语言程序设计(9)ANSII字符大小写转大写
    读书笔记——Windows环境下32位汇编语言程序设计(6)使用浮点指令进行64位除法
    读书笔记——Windows环境下32位汇编语言程序设计(5)模态对话框
    读书笔记——Windows环境下32位汇编语言程序设计(3)一些基础知识
    设置自己的RadASM颜色
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/15035176.html
Copyright © 2011-2022 走看看