我有一个从聊天平台截取的屏幕截图,想要将聊天背景更改为白色,包括参与者的个人资料图片。如果屏幕截图中未显示聊天组的名称,则此 问题 中的代码可以正常工作。图 1 是原始图像的示例,图 2 是迄今为止取得的结果:
并且我想要实现类似于图 3 的效果:
这是我在问题中使用的代码:
import cv2
import numpy as np
filename = ("/Users/user/Desktop/test2.png")
image = cv2.imread(filename)
hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # rgb to hsv color space
s_ch = hsv_img[:, :, 1] # Get the saturation channel
thesh = cv2.threshold(s_ch, 5, 255, cv2.THRESH_BINARY)[1] # Apply threshold - pixels
above 5 are going to be 255, other are zeros.
thesh = cv2.morphologyEx(thesh, cv2.MORPH_OPEN,
cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))) # Apply opening morphological
operation for removing artifacts.
cv2.floodFill(thesh, None, seedPoint=(0, 0), newVal=128, loDiff=1, upDiff=1) # Fill
the background in thesh with the value 128 (pixel in the foreground stays 0.
image[thesh == 128] = (255, 255, 255) # Set all the pixels where thesh=128 to white.
cv2.imwrite('Filtering1.jpg', image) # Save the output image.
我对此很陌生,所以我需要知道应该在代码中添加/更改什么才能实现图 3 中的结果。
提供代码的主要问题在于,它依赖于饱和度通道的阈值来创建掩码,但这对于的输入图像并不可靠,因为聊天气泡本身也有一些低饱和度的颜色。
以下是一种更好的方法,可以使用轮廓检测和洪水填充来实现目标:
import cv2
import numpy as np
# 加载图片
image = cv2.imread("your_image.jpg")
# 将图片转换为灰度
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 使用二值化处理灰度图
thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)[1]
# 查找轮廓
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
# 创建一个掩码,并将所有像素设置为黑色
mask = np.zeros_like(image)
# 迭代所有轮廓
for c in cnts:
# 计算轮廓的面积
area = cv2.contourArea(c)
# 如果面积大于某个阈值(这里设置为1000),则认为是聊天气泡
if area > 1000:
# 绘制填充的轮廓到掩码
cv2.drawContours(mask, [c], -1, (255, 255, 255), -1)
# 对掩码进行膨胀操作,以确保覆盖聊天气泡的边缘
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
mask = cv2.dilate(mask, kernel, iterations = 1)
# 将掩码转换为灰度
mask_gray = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
# 在掩码上进行洪水填充,从图片的左上角开始
h, w = image.shape[:2]
cv2.floodFill(mask_gray, None, (0, 0), 255)
# 反转掩码,以便聊天气泡区域为黑色,背景为白色
mask_inv = cv2.bitwise_not(mask_gray)
# 将原始图片中聊天气泡区域的像素设置为白色
image[mask_inv == 255] = (255, 255, 255)
# 保存结果图片
cv2.imwrite("result.jpg", image)
这段代码首先将图像转换为灰度,然后进行二值化处理。 接下来,它会找到图像中的所有轮廓。对于每个轮廓,它会计算其面积,如果面积足够大,则将其视为聊天气泡,并将其绘制到掩码上。
然后,代码会对掩码进行膨胀操作,以确保覆盖聊天气泡的边缘。 接下来,它会使用洪水填充算法将掩码外部的所有区域填充为白色。 最后,它会反转掩码,并将原始图像中对应于掩码中白色区域的像素设置为白色。
请注意,可能需要根据的输入图像调整代码中的某些参数,例如阈值和膨胀操作的内核大小。
标签:python,python-3.x,opencv,redaction From: 78772902