如何使用OpenCV对阈值化后的图像进行动态裁剪?

动态裁剪功能实现方案
针对你已完成阈值化的图像,可通过轮廓检测定位尖端位置,进而实现动态裁剪,以下是整合到现有代码的具体实现:
import cv2 as cv import numpy as np X = [] # Image data y = [] # Labels # Loops through imagepaths to load images and labels into arrays for path in imagepaths: img = cv.imread(path) # Reads image and returns np.array img = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # Converts into the correct colorspace (GRAY) img_thresh = cv.threshold(img, 50, 225, cv.THRESH_BINARY)[1] # Thresholds the grayscale image img_thresh = cv.bitwise_not(img_thresh) # --- 动态裁剪核心代码 --- # 提取图像轮廓,只保留最外层轮廓 contours, _ = cv.findContours(img_thresh, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) img_cropped = img_thresh # 默认保留原图像,防止轮廓检测失败 if contours: # 筛选出面积最大的轮廓(假设目标是图像中的主要区域) target_contour = max(contours, key=cv.contourArea) # 定位尖端:此处假设尖端为轮廓最右侧点,可根据实际方向调整 rightmost_point = tuple(target_contour[target_contour[:, :, 0].argmax()][0]) # 定义裁剪范围:保留尖端左侧150px到尖端右侧10px的区域,上下保留完整高度 crop_left = max(0, rightmost_point[0] - 150) crop_right = rightmost_point[0] + 10 img_cropped = img_thresh[:, crop_left:crop_right] # --- 裁剪代码结束 --- X.append(img_cropped) # 处理标签逻辑 category = path.split("\\")[4] label = int(category.split("_")[0][1]) # 将10_down转为00_down避免报错 y.append(label) # 转换为numpy数组,适配后续模型输入 X = np.array(X, dtype="uint8") # 若后续CNN需要固定尺寸,需添加resize统一大小: # X = np.array([cv.resize(img, (200, 240)) for img in X], dtype="uint8") X = X.reshape(len(X), X[0].shape[0], X[0].shape[1], 1) y = np.array(y) print("Images loaded: ", len(X)) print("Labels loaded: ", len(y)) print(y[0], imagepaths[0]) # Debugging
调整说明
- 若尖端方向不是右侧,可替换尖端定位逻辑:
- 最左侧:
leftmost_point = tuple(target_contour[target_contour[:, :, 0].argmin()][0]) - 最上方:
topmost_point = tuple(target_contour[target_contour[:, :, 1].argmin()][0]) - 最下方:
bottommost_point = tuple(target_contour[target_contour[:, :, 1].argmax()][0])
- 最左侧:
- 裁剪范围可根据需求修改
crop_left和crop_right的数值,比如扩大/缩小保留区域 - 若后续模型要求固定输入尺寸,务必添加
cv.resize步骤统一图像大小
内容的提问来源于stack exchange,提问作者Mehul Kini
相关产品推荐
相关产品推荐

