今天遇到这样一个需求:需要针对用户输入的图片生成对应文本区域的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 recognitionresults = reader.readtext(image)detected_text = [result[1] for result in results]# Generate masktext_boxes = [result[0] for result in results]mask = generate_text_mask(image, text_boxes)
最后,将生成的mask保存即可:
# Save maskmask_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 colorsinverted_image = invert_colors(image)其中,具体函数如下:# Invert black and white colors in the imagedef 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 graymodified_image = convert_black_to_light_gray(image)其中,具体函数实现如下:def convert_black_to_light_gray(image):gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)mask = gray == 0image[mask] = [200, 200, 200] # Light gray colorreturn image
工作做完了,我们来看看效果,果然和想象中的一样:
完结撒花
到此,就以自身项目实践为例子介绍了如何通过text-detection文本探测实现了文本位置探测以及对应位置mask的生成,因为实际项目中存在以文字替换图片中文字的细节,这部分并没有处理的很好,所以并没有把完整的代码放出来,最近也在尝试其他方法解决这个问题。但是如果谁需要完整的代码的话不妨评论留言,我把这部分代码私发给你。