2.2 缩放、裁剪与拼接
总目录:1.1 OpenCV介绍与学习路线 | 第二章:基础图像处理 | 编号:2.2
← 上一节:2.1 颜色空间与通道 | 下一节:2.3 绘制图形与文字 →
2.2 缩放、裁剪与拼接
这三件事看起来都是“摆弄图片大小”,底层却不一样:缩放会重新计算像素,裁剪只是取出一块区域,拼接则把多个数组接起来。
一、resize:真正修改图像尺寸
resized = cv2.resize(image, (640, 480))
第二个参数是 (宽, 高),又和 shape 的 (高, 宽) 反过来了😢
按比例缩放更不容易写错:
resized = cv2.resize(
image,
dsize=None,
fx=0.5,
fy=0.5,
interpolation=cv2.INTER_AREA,
)
保持长宽比,把宽度改为 800:
h, w = image.shape[:2]
new_w = 800
new_h = round(h * new_w / w)
resized = cv2.resize(image, (new_w, new_h))
二、插值方法怎样选
缩放后出现的新像素从哪里来?这就是插值。
| 插值 | 常见用途 | 特点 |
|---|---|---|
INTER_NEAREST |
二值标签、像素风图 | 最快,不创造中间值,锯齿明显 |
INTER_LINEAR |
日常缩放 | 默认,速度和效果平衡 |
INTER_AREA |
缩小图像 | 常用且抗混叠较好 |
INTER_CUBIC |
放大图像 | 较平滑,但更慢 |
二值蒙版若使用线性插值,边缘可能出现 0 和 255 之外的灰度值。此时优先 INTER_NEAREST,或缩放后重新阈值化。
三、裁剪其实是 NumPy 切片
cropped = image[y1:y2, x1:x2]
例如:
cropped = image[0:200, 200:500]
表示取 y 从 0 到 199、x 从 200 到 499 的区域;切片右端不包含在结果里。

坐标来自检测结果时要先限制范围:
h, w = image.shape[:2]
x1 = max(0, x1)
y1 = max(0, y1)
x2 = min(w, x2)
y2 = min(h, y2)
roi = image[y1:y2, x1:x2].copy()
四、横向与纵向拼接
NumPy 写法:
horizontal = np.hstack((image_a, image_b))
vertical = np.vstack((image_a, image_b))
OpenCV 也提供:
horizontal = cv2.hconcat([image_a, image_b])
vertical = cv2.vconcat([image_a, image_b])
拼接很适合一次显示原图、灰度、蒙版和结果图。不过灰度图是 (H, W),彩色图是 (H, W, 3),不能直接混着拼。
gray_bgr = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
preview = cv2.hconcat([image, gray_bgr])
五、拼接为什么经常报尺寸错误
横向拼接要求高度一致;纵向拼接要求宽度一致;通道数和数据类型也应一致。
hconcat → 高度、通道、dtype 一致
vconcat → 宽度、通道、dtype 一致
一个简单的统一尺寸函数:
def to_preview(image, size=(480, 320)):
if image.ndim == 2:
image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
return cv2.resize(image, size, interpolation=cv2.INTER_AREA)
preview = cv2.hconcat([
to_preview(original),
to_preview(mask),
to_preview(result),
])
← 上一节:2.1 颜色空间与通道 | 下一节:2.3 绘制图形与文字 →
留言区
不收集任何个人信息;昵称只绑定浏览器里的随机 Cookie。