如何用Python检测扫描棒球卡边缘并裁剪图像至仅保留卡片
棒球卡裁剪实现方案
针对带保护套的棒球卡扫描图裁剪需求,用OpenCV实现是高效可靠的方案,以下是具体步骤和代码:
核心思路
利用卡片与保护套的边缘差异,通过轮廓检测定位卡片区域,再通过透视变换矫正并裁剪出目标区域(支持轻微倾斜的卡片)。
具体步骤与代码
- 图像预处理
先将彩色图转灰度,再做高斯模糊降噪,最后用Canny边缘检测提取轮廓:
import cv2 import numpy as np # 读取图像 img = cv2.imread("baseball_card.jpg") # 转灰度图 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 高斯模糊降噪(核大小可根据实际调整) blurred = cv2.GaussianBlur(gray, (5, 5), 0) # Canny边缘检测(阈值可根据图像调整) edges = cv2.Canny(blurred, 50, 150)
- 定位卡片轮廓
提取图像中的所有轮廓,筛选出面积最大的轮廓(即卡片区域):
# 查找轮廓 contours, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 按轮廓面积排序,取最大的那个 contours = sorted(contours, key=cv2.contourArea, reverse=True)[:1] card_contour = contours[0]
- 获取卡片外接矩形与透视变换
用最小外接矩形获取卡片的四个顶点,排序后做透视变换,矫正并裁剪:
# 获取最小外接矩形的四个顶点 rect = cv2.minAreaRect(card_contour) box = cv2.boxPoints(rect) box = np.int0(box) # 对顶点排序(左上、右上、右下、左下) def order_points(pts): rect = np.zeros((4, 2), dtype="float32") s = pts.sum(axis=1) rect[0] = pts[np.argmin(s)] rect[2] = pts[np.argmax(s)] diff = np.diff(pts, axis=1) rect[1] = pts[np.argmin(diff)] rect[3] = pts[np.argmax(diff)] return rect rect = order_points(box) (tl, tr, br, bl) = rect # 计算目标图像的宽度和高度 widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2)) widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2)) maxWidth = max(int(widthA), int(widthB)) heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2)) heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2)) maxHeight = max(int(heightA), int(heightB)) # 定义目标图像的顶点坐标,如需略超边缘,可给宽高增加像素(如各加10) dst = np.array([ [0, 0], [maxWidth - 1, 0], [maxWidth - 1, maxHeight - 1], [0, maxHeight - 1]], dtype="float32") # 计算透视变换矩阵并应用 M = cv2.getPerspectiveTransform(rect, dst) warped = cv2.warpPerspective(img, M, (maxWidth, maxHeight)) # 保存裁剪后的图像 cv2.imwrite("cropped_card.jpg", warped)
注意事项
- 若扫描图存在反光或保护套边缘不清晰,可调整
cv2.GaussianBlur的核大小、cv2.Canny的高低阈值,或增加形态学操作(如cv2.dilate膨胀边缘)优化轮廓检测效果。 - 若需要略超出卡片边缘,可在计算
maxWidth和maxHeight时增加固定像素值,同时调整dst的坐标偏移量。
内容的提问来源于stack exchange,提问作者TechDH
相关产品推荐
相关产品推荐

