一,简介
本项目旨在开发一个基于OpenCV的图像处理工具,实现根据颜色从图片中自动抠图的功能。通过该项目,用户可以轻松指定一种颜色,系统将自动识别并提取该颜色的所有像素,生成新的图像。
二,实现方案
本方案基于OpenCV的图像处理,通过指定颜色范围,从输入图像中自动识别并提取该颜色的所有像素,生成新的图像。首先,通过颜色空间转换和掩码生成,实现颜色识别;然后,通过形态学操作修正掩码;最后抠出图像中对应掩码的区域。
三、算法实现步骤
3.1 cv2.inRange()选择抠出的颜色
将图像转化为hsv颜色空间,按照上表中的数值进行颜色选择,本次选择的颜色为红色,使用的函数为cv2.inRange(),
cv2.inRange 是 OpenCV 中的一个函数,用于生成一个掩码,该掩码包含在指定范围内的所有像素。
函数介绍:
src: 输入的图像,可以是灰度图或彩色图。
lowerb: 表示颜色范围的最低边界。它是一个数组,包含三个值:蓝色通道的下限、绿色通道的下限和红色通道的下限。
upperb: 表示颜色范围的最高边界。它也是一个数组,包含三个值:蓝色通道的上限、绿色通道的上限和红色通道的上限。
cv2.inRange 函数返回一个与 src 图像大小相同的掩码图像。在这个掩码图像中,像素值在 lowerb 和 upperb 范围内的像素会被设置为255(白色),表示这些像素属于指定的颜色范围;而其他像素则被设置为0(黑色),表示这些像素不属于指定的颜色范围。
使用方法:
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 生成检测红色区域的掩码
lower_red = np.array([0, 43, 46])
upper_red = np.array([10, 255, 255])
mask1 = cv2.inRange(hsv, lower_red, upper_red)
lower_red = np.array([156, 43, 46])
upper_red = np.array([180, 255, 255])
mask2 = cv2.inRange(hsv, lower_red, upper_red)
mask1 = mask1 + mask2
3.2 处理颜色蒙版:
在图像处理中,为了提高颜色识别的准确性和鲁棒性,我们通常会采用以下步骤:
- 执行形态学开运算:通过先腐蚀再膨胀的方式,去除掩码中的小噪声点和细小的白色区域。
- 执行膨胀操作:增加掩码中白色区域的面积,填充前景对象中的小孔或间隙。
- 执行取反操作:将掩码中的白色区域变为黑色,黑色区域变为白色,有助于将背景区域与前景区域区分开来。
通过这些步骤,原始的颜色识别掩码被细化和改善,使得后续的图像处理步骤更加准确和有效。
实现方法:
mask1 = cv2.morphologyEx(mask1, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8), iterations=2)
mask1 = cv2.dilate(mask1, np.ones((3, 3), np.uint8), iterations=1)
mask2 = cv2.bitwise_not(mask1)
3.3 取出图片中蒙版对应区域
代码:
res1 = cv2.bitwise_and(img, img, mask=mask1)
res2 = cv2.bitwise_and(img, img, mask=mask2)
四,整体代码
import cv2
import numpy as np
# 指定图像路径
image_path = r"F:\OIP-C.jfif"
# 加载图像
img = cv2.imread(image_path)
# 检查图像是否加载成功
if img is None:
print("Error: Image cannot be loaded. Please check the path.")
exit()
# 将颜色空间从BGR转换为HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 生成检测红色区域的掩码
lower_red = np.array([0, 43, 46])
upper_red = np.array([10, 255, 255])
mask1 = cv2.inRange(hsv, lower_red, upper_red)
lower_red = np.array([156, 43, 46])
upper_red = np.array([180, 255, 255])
mask2 = cv2.inRange(hsv, lower_red, upper_red)
mask1 = mask1 + mask2
# 细化检测到的红色区域对应的掩码
mask1 = cv2.morphologyEx(mask1, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8), iterations=2)
mask1 = cv2.dilate(mask1, np.ones((3, 3), np.uint8), iterations=1)
mask2 = cv2.bitwise_not(mask1)
# 生成最终输出
res1 = cv2.bitwise_and(img, img, mask=mask1)
res2 = cv2.bitwise_and(img, img, mask=mask2)
# 显示融合后的图像
cv2.imshow('roi', res1)
cv2.imshow('background', res2)
# 等待按键
cv2.waitKey(0)
# 销毁所有窗口
cv2.destroyAllWindows()
五,效果:
原图:
前景和背景: