[关闭]
@nrailgun 2016-07-24T16:45:44.000000Z 字数 1714 阅读 1671

Geometric Image Transformations in OpenCV

程序设计

实际上 OpenCV 在进行仿射变换的时候,计算是从 destination 映射回 source

D(x,y)=S(fx(x,y),fy(x,y))

但是仿射变换的接口

  1. void warpAffine(
  2. InputArray src, OutputArray dst, InputArray M, Size dsize,
  3. int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT,
  4. const Scalar& borderValue=Scalar());

接受的变换矩阵却是 [XS,YS][XD,YD] 的变换矩阵(第一时间没有跟上思路)。

我们称将 [XS,YS][XD,YD] 的矩阵称为变换矩阵,将 [XS,YS][XD,YD] 称为逆变换矩阵。

OpenCV 通过

M=[αββα(1α)xβyβx(1α)y]
计算变换矩阵,
其中 α=σcosθβ=σsinθ。值得注意的是,OpenCV 假设变换前后旋转中心不变。

  1. Mat getRotationMatrix2D(Point2f center, double angle, double scale);

OpenCV 提供了简单的计算逆变换矩阵的接口。

  1. void invertAffineTransform(InputArray M, OutputArray iM);

如果有些时候我们需要变换旋转中心(也就是 Shift / Translation),只需要简单的叠加变换矩阵。

M=M100010txty1

不过我们需要自己写一个变换矩阵生成器。

  1. Mat_<float> affine_matrix(
  2. const Point2i &src, const Point2i &dst, const float angle, const float scale)
  3. {
  4. Mat_<float> M(2, 3);
  5. M(0, 0) = scale * std::cos(angle);
  6. M(0, 1) = scale * std::sin(angle);
  7. M(0, 2) = (1 - M(0, 0)) * dst.x - M(0, 1) * dst.y;
  8. M(1, 0) = -M(0, 1);
  9. M(1, 1) = M(0, 0);
  10. M(1, 2) = M(0, 1) * dst.x + (1 - M(0, 0)) * dst.y;
  11. Mat_<float> T(3, 3);
  12. T(0, 0) = 1;
  13. T(0, 1) = 0;
  14. T(0, 2) = dst.x - src.x;
  15. T(1, 0) = 0;
  16. T(1, 1) = 1;
  17. T(1, 2) = dst.y - src.y;
  18. T(2, 0) = 0;
  19. T(2, 1) = 0;
  20. T(2, 2) = 1;
  21. return M * T;
  22. }

使用方式和普通仿射变换无异。

  1. Mat src, dst;
  2. src = imread("kuuga.jpg", -1);
  3. dst = cv::Mat::zeros(src.rows, src.cols, CV_8UC3);
  4. Point2f src_center(0, 0);
  5. Point2f dst_center(50, 50);
  6. Mat M = affine_matrix(src_center, dst_center, 1.5, 1);
  7. warpAffine(src, dst, M, dst.size());
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注