Python OpenCV 图像平移,取经之旅第 10 天

今天是持续写作的第 43 / 100 天。
如果你有想要交流的想法、技术,欢迎在评论区留言。

本篇博客学习 OpenCV 中关于图像平移的方法,核心学习到的方法是 warpAffine 。

OpenCV 图像的平移

每次学习新东西的时候,橡皮擦都是去海量检索,然后找到适合自己理解的部分。

再将其拼凑成一个小的系统,争取对该内容有初步理解。

今天这 1 个小时,核心要学习的是图像的平移,在电脑上随便打开一张图片,实现移动都非常简单,但是在代码中,出现了一些新的概念。

检索 OpenCV 图像平移相关资料时,碰到的第一个新概念是就是 仿射变换

每次看到这样子的数学名字,必然心中一凉,做为一个数学小白,又要瑟瑟发抖了。

百度一下,看看百科中是如何介绍的。

Python OpenCV 图像平移,取经之旅第 10 天
看过上图中的一些相关简介之后,对于这个概念也并没有太深刻的理解,本着先用起来,在补充理论的学习观点,我们先实现图像平移。

学习过程中,碰到一些概念性的东西,可以先应用起来,然后在后续的深入学习过程中,逐步去完善它们。

cv2.warpAffine() 仿射变换

基于该方法去寻找相关资料,得到仿射变换的基本概念,从二维坐标到二维坐标之间的线性变换,并且要保持二维图形的“平直性” 和 “平行性”。

仿射变换中,包含平移,缩放,翻转,旋转,剪切。

该方法的语法结构如下:

dst = cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

参数说明:

  • src:输入图像
  • M:2*3 transformation matrix (转变矩阵)
  • dsize:输出图像的大小,格式为(cols,rows),width 对应 cols,height 对应 rows
  • flags: 可选参数,插值方法的组合(int 类型),默认值 INTER_LINEAR
  • borderMode:可选参数,边界像素模式(int 类型),默认值 BORDER_CONSTANT
  • borderValue:可选参数,边界填充值; 默认情况下,默认值 Scalar()即 0

官方可查阅的英文资料如下:
Python OpenCV 图像平移,取经之旅第 10 天
插值方式(flags)有如下类型:

  • INTER_LINEAR 线性插值
  • INTER_NEAREST 最近邻插值
  • INTER_AREA 区域插值
  • INTER_CUBIC 三次样条插值
  • INTER_LANCZOS4 Lanczos 插值

一般情况下,使用 wrapAffine 前三个参数,即 warpAffine(img,M,(rows,cols)) 实现基本的仿射变换效果,但是这种情况会出现 黑边 现象。

最后一个参数为 borderValue,边界填充的颜色,默认为黑色,可以自行设置为其它颜色。

具体代码

图像平移是图像位置的移动。在平移前,需要先转换矩阵 M,,其中 txty 表示在(x,y)方向上的位移,如下所示:
Python OpenCV 图像平移,取经之旅第 10 天
测试代码如下,重要部分在注释中进行说明。

import numpy as np
import cv2 as cv

img = cv.imread('10.jpg', 1)
rows, cols, channels = img.shape
# [1,0,100] 右移 100, [0,1,50] 下移 50
M = np.float32([[1, 0, 100], [0, 1, 50]])
res = cv.warpAffine(img, M, (cols, rows))
cv.imshow("img", res)
cv.waitKey()

特别说明:
cv.warpAffine 方法的第三个参数是输出图像的大小,其形式应为(width,height)。记住 width =列数(cols),height =行数(rows)。

以下为代码运行结果。
Python OpenCV 图像平移,取经之旅第 10 天
关于 borderMode 参数值的说明:
该部分内容涉及边缘处理,翻阅手册过程找到的说明指向 BorderTypes。翻阅了一下,依旧是有些超纲,可以先记录下相关内容,日后在进行回顾,参考地址

所有值罗列如下:

  • BORDER_CONSTANT = 0
  • BORDER_REPLICATE = 1
  • BORDER_REFLECT = 2
  • BORDER_WRAP = 3
  • BORDER_REFLECT_101 = 4
  • BORDER_TRANSPARENT = 5
  • BORDER_REFLECT101 = BORDER_REFLECT_101
  • BORDER_DEFAULT = BORDER_REFLECT_101
  • BORDER_ISOLATED = 16

Python OpenCV 图像平移,取经之旅第 10 天
borderValue:当图像边界处理方式为 BORDER_CONSTANT 时的填充值。

测试代码如下:

import numpy as np
import cv2 as cv

img = cv.imread('10.jpg', 1)
rows, cols, channels = img.shape
M = np.float32([[1, 0, 100], [0, 1, 50]])
res = cv.warpAffine(img, M, (cols, rows),
                    borderMode=cv.BORDER_CONSTANT, borderValue=(200, 66, 66))
cv.imshow("img", res)
cv.waitKey()

OpenCV 尾声

1 个小时又过去了,对 Python OpenCV 相关的知识点,你掌握了吗?

空闲之余,可以订阅橡皮擦的爬虫百例课程学习爬虫知识。

想学 Python 爬虫,可以订阅橡皮擦专栏哦~ 🈲🈲🈲🈲 点击发现惊喜 🈲🈲🈲🈲

好的,以下是一个简单的示例代码,使用dlib库中的人脸关键点检测和仿射变换实现人脸矫正: ```c++ #include <dlib/opencv.h> #include <opencv2/opencv.hpp> using namespace dlib; cv::Mat face_alignment(cv::Mat img) { // Load face detection and landmark detection models frontal_face_detector detector = get_frontal_face_detector(); shape_predictor sp; deserialize("shape_predictor_68_face_landmarks.dat") >> sp; // Convert OpenCV Mat to dlib image cv_image<bgr_pixel> dlib_img(img); // Detect faces in the image std::vector<rectangle> dets = detector(dlib_img); // Iterate over detected faces for (rectangle& det : dets) { // Get the landmarks for the face full_object_detection shape = sp(dlib_img, det); // Calculate the transformation matrix for face alignment std::vector<cv::Point2f> src_points, dst_points; for (unsigned i = 0; i < shape.num_parts(); ++i) { const point& pt = shape.part(i); src_points.push_back(cv::Point2f(pt.x(), pt.y())); // Define the destination points for face alignment // You can adjust these points to fit your specific needs dst_points.push_back(cv::Point2f(0.3*img.cols, 0.3*img.rows)); dst_points.push_back(cv::Point2f(0.7*img.cols, 0.3*img.rows)); dst_points.push_back(cv::Point2f(0.5*img.cols, 0.7*img.rows)); } cv::Mat H = cv::getAffineTransform(src_points, dst_points); // Apply the transformation to the original image cv::Mat aligned_img; cv::warpAffine(img, aligned_img, H, img.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar()); return aligned_img; } return cv::Mat(); } ``` 该函数接受一个OpenCV的cv::Mat类型的图像作为输入,并返回矫正后的图像。请注意,该函数加载了一个预训练的人脸关键点检测器和一个形状预测器,这些模型需要从dlib官方网站下载并放置在当前目录下。 该函数做了以下几件事情: 1. 将OpenCV中的cv::Mat图像转换为dlib中的图像类型cv_image<bgr_pixel>; 2. 使用dlib中的人脸检测器检测图像中的人脸,并使用形状预测器获取人脸关键点; 3. 根据关键点计算仿射变换矩阵,将人脸对齐到指定的目标位置; 4. 应用仿射变换将原始图像矫正,并将结果作为cv::Mat类型返回。 在实际使用中,您可以调整目标位置的定义以适应您的具体需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦想橡皮擦

如有帮助,来瓶可乐

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值