在学习 OpenCV 和 Matplotlib 处理图像时,遇到了一些关于 cv2.imread()
、cv2.getRotationMatrix2D()
、plt.imshow()
的问题:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('img2.png', 1) # 读取彩色图像(BGR格式)
rows, cols = img.shape[:2] # 获取图像高度和宽度
# 计算旋转变换矩阵
M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1)
# 进行仿射变换并填充空白区域为白色
dst = cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
# 显示原图和旋转后的图像(OpenCV方式)
while(1):
cv2.imshow('img', img)
cv2.imshow('img1', dst)
if cv2.waitKey(1) & 0xFF == 27: # 按 ESC 退出
break
cv2.destroyAllWindows()
# 使用 Matplotlib 显示(转换 BGR → RGB)
plt.imshow(img[:, :, ::-1]) # OpenCV 读取的 BGR 转换为 RGB
plt.show()
问题与解答
1. cv2.imread('img2.png', 1)
里的 1
代表什么?
cv2.imread()
读取图像时,1
代表 以彩色模式(BGR) 读取图像,忽略透明度通道。0
表示灰度模式,-1
表示保留透明度。
✅ 正确用法:
img = cv2.imread('img2.png', cv2.IMREAD_COLOR) # 与 cv2.imread('img2.png', 1) 等效
2. rows, cols = img.shape[:2]
为什么 img.shape
是三维的还能切片?
img.shape
结构是(height, width, channels)
。img.shape[:2]
只取height
和width
,忽略通道数(channels
)。- 因为
cv2.getRotationMatrix2D()
只需要高度和宽度,所以这样写是合理的。
✅ 正确理解:
h, w = img.shape[:2] # 取出高度和宽度,不包括通道数
3. cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1)
里的参数是什么意思?
M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1)
参数 | 作用 |
---|---|
(cols/2, rows/2) |
旋转中心,这里是图像中心 |
45 |
旋转角度 ,正值表示逆时针旋转,负值表示顺时针 |
1 |
缩放因子 ,1 表示不缩放,<1 缩小,>1 放大 |
缩放因子 scale
只影响大小,不影响旋转方向。
✅ 如果想绕左上角旋转:
M = cv2.getRotationMatrix2D((0, 0), 45, 1) # 旋转中心改为左上角
4. cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
是做什么的?
cv2.warpAffine()
用于 应用仿射变换(如旋转、缩放)。borderValue=(255,255,255)
指定 填充空白区域为白色(默认是黑色)。
✅ 示例
dst = cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
5. 为什么 img = cv2.imread("1.jpg")[::-1]
不能转换 BGR → RGB?
-
[::-1]
只是翻转行数(上下翻转),不会改变通道顺序。 -
正确的 BGR → RGB 方法 :
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 推荐方法
或者:
img = img[:, :, ::-1] # 交换 BGR → RGB
✅ 示例
img = cv2.imread("1.jpg")
img_rgb = img[:, :, ::-1] # 颜色通道反转
plt.imshow(img_rgb)
plt.show()
6. 为什么 plt.imshow(range)
会报错?
range
只是整数序列 ,不是 NumPy 数组,Matplotlib 不知道如何绘制它。- 需要转换成 NumPy 数组,并
reshape
成合适的形状。
✅ 正确方法
import numpy as np
plt.imshow(np.array(range(100)).reshape(10,10)) # 转换并 reshape 成 2D 图像
plt.show()
7. plt.imshow(img)
之后为什么还要 plt.show()
?
plt.imshow(img)
只是创建图像对象,但不会自动显示。plt.show()
才会真正渲染和显示图像。
✅ 单张图片
plt.imshow(img)
plt.show() # 需要调用 plt.show() 才会显示
✅ 多张图片(需要分别 plt.show()
)
plt.imshow(img1)
plt.show()
plt.imshow(img2)
plt.show() # 否则 img2 会覆盖 img1
✅ 多张图片同一窗口(用 subplot
)
plt.subplot(1, 2, 1)
plt.imshow(img1)
plt.subplot(1, 2, 2)
plt.imshow(img2)
plt.show() # 只调用一次 plt.show()