数字图像处理学习笔记
1-图像处理基础_哔哩哔哩_bilibili
输出图像像素点需要将图象值要作类型转换,转成Int
图像仿射变换
线性变换+平移
线性变换: 1,变换前直线,变换后仍然直线 2,直线比例不变 3,直线到远点的距离不变
仿射变换计算:
常见变换:
恒等变换:变换前后一致
尺度变换:对尺寸作放大或缩小
旋转变换:图像旋转但是尺寸不变
平移::位置移动尺寸不变
偏移(垂直、水平):垂直或者水平方向变化
代码示例:
import cv2
import numpy as np# 读取图像
img = cv2.imread('image.jpg')# 原图中的三个点
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
# 变换后的三个点
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])# 计算仿射变换矩阵
M = cv2.getAffineTransform(pts1, pts2)# 应用仿射变换
rows, cols, ch = img.shape
dst = cv2.warpAffine(img, M, (cols, rows))# 显示结果
cv2.imshow('Input', img)
cv2.imshow('Affine Transform', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 原图中的三个点
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
# 变换后的三个点
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])# 计算仿射变换矩阵
M = cv2.getAffineTransform(pts1, pts2)
OpenCV 会根据这三个点对(A→A',B→B',C→C')计算出一个仿射变换矩阵,它能把整张图像从原始位置「平移、旋转、缩放、剪切」到目标状态。
仿射变换至少需要三个不共线的点
原因是:
仿射变换的核心是一个 2×3 的矩阵 M,它有 6 个自由度:
这个矩阵控制了图像的:
-
缩放
-
旋转
-
平移
-
剪切
3个点为什么足够?
每个点对(原始点 -> 目标点)能提供两个方程(x 和 y 方向),所以:
-
3个点 × 2 = 6 个方程
-
恰好解出 6 个未知数:a11,a12,a21,a22,tx,ty
cv2.warpAffine
dst = cv2.warpAffine(src, M, dsize)
其中:
-
src
是输入图像 -
M
是 2×3 的仿射变换矩阵 -
dsize
是目标图像的大小,格式为(width, height)
为什么是 (width, height)
?
这是因为 OpenCV 中:
-
图像的
.shape
返回的是(rows, cols, channels)
,即(height, width, channels)
-
但在
cv2.warpAffine()
中,dsize
是图像尺寸,而不是 shape,所以必须按照:dsize=(output_width,output_height)
图像内容被映射到原始画布之外
现象:
-
图像内容扭曲到角落,部分区域成了黑色(像素值为0)
-
原因是变换后的位置超出了目标图像尺寸