如何使用OpenCV裁剪图片为3:4比例并居中主体且保留原有背景
实现方案
你可以在现有检测到人物框的基础上,补充3:4比例画布计算、边界校验逻辑即可实现需求,完整代码如下:
import cv2 import numpy as np img = cv2.imread("1.jpg") img_h, img_w = img.shape[:2] blurred = cv2.blur(img, (3,3)) canny = cv2.Canny(blurred, 50, 200) # 检测人物的边界框 pts = np.argwhere(canny>0) y1,x1 = pts.min(axis=0) y2,x2 = pts.max(axis=0) person_w = x2 - x1 person_h = y2 - y1 # 计算人物中心坐标 cx = (x1 + x2) // 2 cy = (y1 + y2) // 2 # 3:4比例,宽高比为 宽/高 = 3/4 ratio = 3 / 4 # 计算符合比例且能完整容纳人物的最小裁剪尺寸 if person_h / person_w > 4 /3: # 人物更高,以高度为基准计算宽度 crop_h = person_h crop_w = int(crop_h * ratio) else: # 人物更宽,以宽度为基准计算高度 crop_w = person_w crop_h = int(crop_w / ratio) # 计算裁剪区域的边界,保证人物居中 crop_x1 = cx - crop_w // 2 crop_y1 = cy - crop_h // 2 crop_x2 = crop_x1 + crop_w crop_y2 = crop_y1 + crop_h # 边界校验,避免裁剪区域超出原图范围 if crop_x1 < 0: crop_x1 = 0 crop_x2 = crop_w if crop_x2 > img_w: crop_x2 = img_w crop_x1 = img_w - crop_w if crop_y1 < 0: crop_y1 = 0 crop_y2 = crop_h if crop_y2 > img_h: crop_y2 = img_h crop_y1 = img_h - crop_h # 裁剪得到最终结果 result = img[crop_y1:crop_y2, crop_x1:crop_x2] cv2.imwrite("result.png", result) # 可视化校验 tagged = cv2.rectangle(img.copy(), (crop_x1,crop_y1), (crop_x2,crop_y2), (0,255,0), 3, cv2.LINE_AA) cv2.imshow("result", result) cv2.imshow("tagged", tagged) cv2.waitKey() cv2.destroyAllWindows()
逻辑说明
- 基于原有Canny边缘检测的结果拿到人物的边界框和中心点坐标
- 根据人物的宽高计算符合3:4比例、且能完整容纳人物的最小裁剪尺寸
- 以人物中心点为裁剪区域的中心计算裁剪边界,同时做边界校验避免超出原图范围
- 直接从原图裁剪对应区域即可保留原始背景,同时满足人物居中、比例符合要求的需求
内容的提问来源于stack exchange,提问作者Andie31
相关产品推荐
相关产品推荐

