今天遇到这样一个需求:需要针对用户输入的图片生成对应文本区域的mask,按理说这应该是一个很容易实现的问题。
初步设想
要生成对应区域的mask,首先要找到文本所在的位置,针对不同的图片,文本位置自然是不同的,所以text-detection文本探测就很必然要用到,于是就很自然的用到cv2以及easyocr,先将原图片加载进来:
def load_image(image_path):
return cv2.imread(image_path)
然后用easyocr创建一个reader对象来读取图片中的文本(也就是文本探测)而后根据所得到的文本结果生成所需要的mask即可:
image = load_image(image_path)
reader = easyocr.Reader(['en', 'ch_sim']) # Initialize EasyOCR reader
# Perform text detection and recognition
results = reader.readtext(image)
detected_text = [result[1] for result in results]
# Generate mask
text_boxes = [result[0] for result in results]
mask = generate_text_mask(image, text_boxes)
最后,将生成的mask保存即可:
# Save mask
mask_filename = "text_mask_with_replacement.png"
save_mask(mask, mask_filename)
注意,在这里面之所以命名为text_mask_with_replacemet是因为后续有在mask区域写入文字的操作 ,因为本篇重在讲mask生成,而且写入的这个操作work效果并不好,所以不再特殊提起,希望读者明晰。
进一步思考
生成到这里,打开mask一开,好家伙,黑白的mask,但是我需要的是灰白的呀!!!于是还得改,那怎么改呢?
首先,我是想文字区域是黑色,但是这得到的和我想要的完全相反,这可不行啊!诶,相反?我直接invert(反转)一下不就可以了吗,黑的变成了白的白的变成了黑的,说干就干:
image = load_image(mask_filename)
# Invert colors
inverted_image = invert_colors(image)
其中,具体函数如下:
# Invert black and white colors in the image
def invert_colors(image):
inverted_image = cv2.bitwise_not(image)
return inverted_image
这样一来,黑的变成了白的,白的变成了黑的,看看效果!还可以。
但是,项目需要的应该是灰色的mask,这黑色的mask在项目上跑,效果实在拉跨,所以我决定还是按照示例整一张灰色的mask出来,逻辑其实并不麻烦,只需要找到黑色区域,然后改成灰色的就可以了,在这里我用的是浅灰色:
image = load_image(inverted_image_filename)
# Convert black to light gray
modified_image = convert_black_to_light_gray(image)
其中,具体函数实现如下:
def convert_black_to_light_gray(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
mask = gray == 0
image[mask] = [200, 200, 200] # Light gray color
return image
工作做完了,我们来看看效果,果然和想象中的一样:
完结撒花
到此,就以自身项目实践为例子介绍了如何通过text-detection文本探测实现了文本位置探测以及对应位置mask的生成,因为实际项目中存在以文字替换图片中文字的细节,这部分并没有处理的很好,所以并没有把完整的代码放出来,最近也在尝试其他方法解决这个问题。但是如果谁需要完整的代码的话不妨评论留言,我把这部分代码私发给你。