Python OpenCV仅放大图像指定对象及外扩边界实现方法
Python实现目标边界外扩+红边绘制方案
核心逻辑是不改动整图尺寸,单独提取原有黄色边界对应的目标轮廓,对轮廓做坐标偏移实现外扩,再直接在原图画布上绘制红边,完全避开整图缩放的问题。
实现步骤
- 提取黄色边界轮廓:将图像转HSV颜色空间,通过黄色阈值分割生成黄边掩码,从掩码中提取最外层的目标轮廓,过滤掉小噪点轮廓。
- 轮廓外扩20像素:根据目标形状选择对应外扩方式:矩形目标直接对外接矩形的四边各向外偏移20像素,同时做边界截断防止坐标超出图像范围;不规则多边形目标则基于轮廓形心,将每个轮廓点沿形心到点的射线方向外推20像素,保证所有边角均匀外扩。
- 绘制红色边界:直接在原图上用OpenCV的绘图函数绘制外扩后的轮廓,线宽设置略大于原有黄边,颜色选BGR通道的纯红色(0,0,255),全程不修改原图分辨率。
- 轮廓预处理优化:如果提取到的黄边掩码有断裂、缺口,先使用形态学闭运算补全闭合轮廓,避免外扩后形状错位。
核心实现代码
import cv2 import numpy as np # 读取输入图像 img = cv2.imread("your_input_img.png") img_h, img_w = img.shape[:2] hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 黄色HSV阈值,可根据实际黄边的明暗微调 yellow_lower = np.array([18, 80, 80]) yellow_upper = np.array([42, 255, 255]) yellow_mask = cv2.inRange(hsv_img, yellow_lower, yellow_upper) # 可选:形态学闭运算补全黄边断裂 kernel = np.ones((5,5), np.uint8) yellow_mask = cv2.morphologyEx(yellow_mask, cv2.MORPH_CLOSE, kernel) # 提取黄边对应的外轮廓 contours, _ = cv2.findContours(yellow_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 取面积最大的轮廓作为目标轮廓,过滤小黄点噪点 target_contour = max(contours, key=cv2.contourArea) # --- 矩形目标外扩+绘红边 --- x, y, rect_w, rect_h = cv2.boundingRect(target_contour) # 各边外扩20像素,做边界防越界截断 x1 = max(0, x - 20) y1 = max(0, y - 20) x2 = min(img_w, x + rect_w + 20) y2 = min(img_h, y + rect_h + 20) # 绘制3像素宽的红边 cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), thickness=3) # --- 不规则多边形目标外扩+绘红边(和上面的矩形方案二选一即可)--- # # 计算轮廓形心 # M = cv2.moments(target_contour) # cx = int(M["m10"] / M["m00"]) # cy = int(M["m01"] / M["m00"]) # expanded_points = [] # for p in target_contour: # px, py = p[0] # # 计算点到形心的方向向量 # dx, dy = px - cx, py - cy # point_dist = np.sqrt(dx**2 + dy**2) # # 沿方向外推20像素 # new_px = int(px + (dx / point_dist) * 20) # new_py = int(py + (dy / point_dist) * 20) # # 坐标越界截断 # new_px = max(0, min(img_w - 1, new_px)) # new_py = max(0, min(img_h - 1, new_py)) # expanded_points.append([[new_px, new_py]]) # expanded_contour = np.array(expanded_points, dtype=np.int32) # # 绘制3像素宽的红边 # cv2.drawContours(img, [expanded_contour], -1, (0, 0, 255), thickness=3) # 保存输出图像,尺寸和输入图完全一致 cv2.imwrite("output_result.png", img)
提示:如果不需要保留原有黄色边界,可以在提取黄边轮廓后,先把原黄边位置的像素用邻域背景填充,再绘制红边即可。
内容的提问来源于stack exchange,提问作者Abbas Khan
相关产品推荐
相关产品推荐

