如何使用OpenCV将图片填充到另一张图的圆形白色区域中?
用OpenCV实现将第二张图片填充到第一张图的圆形白色区域
前置准备
确保已安装opencv-python和numpy,可通过以下命令安装:
pip install opencv-python numpy
实现步骤及代码
1. 加载图片并校验
import cv2 import numpy as np # 加载两张目标图片 img_with_circle = cv2.imread("E6JLZ.png") fill_img = cv2.imread("TPdUP.jpg") # 校验图片加载状态 if img_with_circle is None or fill_img is None: raise ValueError("图片加载失败,请检查文件路径是否正确")
2. 提取圆形白色区域的掩码
通过颜色阈值提取白色区域,再用形态学操作优化掩码边缘:
# 转换为HSV空间,更易识别白色 hsv = cv2.cvtColor(img_with_circle, cv2.COLOR_BGR2HSV) # 定义白色的HSV范围(低饱和度、高亮度) lower_white = np.array([0, 0, 200]) upper_white = np.array([180, 30, 255]) # 生成初始掩码 mask = cv2.inRange(hsv, lower_white, upper_white) # 形态学操作消除噪点、平滑边缘 kernel = np.ones((5,5), np.uint8) mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
3. 定位圆形区域的中心与半径
通过轮廓检测获取圆形的关键参数:
# 查找掩码中的轮廓 contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: raise ValueError("未检测到白色圆形区域") # 取面积最大的轮廓(即目标圆形) largest_contour = max(contours, key=cv2.contourArea) # 计算最小外接圆的中心和半径 (x, y), radius = cv2.minEnclosingCircle(largest_contour) center = (int(x), int(y)) radius = int(radius)
4. 调整填充图尺寸并裁剪为圆形
让填充图适配圆形区域的大小,可选裁剪为圆形:
# 将填充图缩放到圆形直径大小 fill_size = (2*radius, 2*radius) resized_fill = cv2.resize(fill_img, fill_size, interpolation=cv2.INTER_AREA) # (可选)生成填充图的圆形掩码,只保留圆形区域 fill_mask = np.zeros(fill_size, dtype=np.uint8) cv2.circle(fill_mask, (radius, radius), radius, 255, -1) resized_fill = cv2.bitwise_and(resized_fill, resized_fill, mask=fill_mask)
5. 合成填充图到原图
将调整后的填充图替换原图的白色圆形区域:
# 计算填充图在原图中的放置坐标 x_start = center[0] - radius y_start = center[1] - radius x_end = x_start + 2*radius y_end = y_start + 2*radius # 校验坐标是否在原图范围内 if x_start <0 or y_start <0 or x_end > img_with_circle.shape[1] or y_end > img_with_circle.shape[0]: raise ValueError("圆形区域超出图片边界,请检查原图") # 提取原图中需要替换的区域 roi = img_with_circle[y_start:y_end, x_start:x_end] # 融合填充图与ROI区域 roi = cv2.bitwise_and(roi, roi, mask=cv2.bitwise_not(fill_mask)) roi = cv2.add(roi, resized_fill) # 将融合后的区域放回原图 img_with_circle[y_start:y_end, x_start:x_end] = roi
6. 查看或保存结果
# 显示结果 cv2.imshow("填充完成图", img_with_circle) cv2.waitKey(0) cv2.destroyAllWindows() # 保存结果到本地 cv2.imwrite("filled_result.png", img_with_circle)
注意事项
- 若白色区域存在噪点,可调整HSV阈值或增加轮廓面积过滤条件;
- 不需要圆形填充时,可跳过填充图的圆形掩码裁剪步骤;
- 若原图白色圆形不是规则圆形,可直接用初始掩码进行替换,无需计算外接圆。
内容的提问来源于stack exchange,提问作者chigan_6
相关产品推荐
相关产品推荐

