之前实现了目标检测和图像分类任务的可视化脚本,本章将最后一个分割任务的可视化脚本实现
效果展示如下:
代码会在当前目录保存展示好的图片,从左到右依次为,原图、mask图、mask覆盖在原图的掩膜图
关于目标检测的可视化:
VOC:关于目标检测任务中,XML(voc格式)标注文件的可视化
YOLO :关于目标检测任务中,YOLO(txt格式)标注文件的可视化
图像分类:图像分类任务的可视化脚本,生成类别json字典文件
因为分割的数据格式问题,图像如何显示问题,可能会出现一些问题。
代码使用了好几种不同的分割数据集测试均可实现,可以保证大部分数据的可视化
具体的问题,在后文介绍
数据摆放如下所示
图像放在images目录下,对应的GT图像放在masks文件下,这里的文件名是保持对应的,否则后续代码需要更改
show脚本放在data相同的路径
这里传入的root是images目录,这样random可以随机取出一张图片。根据目录的索引,自动找到图片对应的GT图像。
注:如果文件名不相同的话,需要自己在后面replace更换
这里的opacity 是掩膜的程度,0-1直接越小,效果越好
这里运用的就是数字图像处理的内容,可以参考:数字图像处理
使用 PIL 打开图片,可以避免一些不必要的错误。cv的格式太严格了,不管是数据类型啊,还是通道,或者最后的np展示都需要相同的维度。而分割的GT一般都是8bit,本人调试很久,还是PIL打开方便
至于draw_image 函数,就是数字图像处理的绘制边框内容,因为matplotlib展示的时候会自动填色,这样可视化的效果更好,所以用matplotlib展示
这里用绿色绘制边框,红色掩膜填充
opacity = 0.5
opacity = 0.1
opacity = 0.9
代码:
import cv2
import numpy as np
import os
import random
from PIL import Image
import matplotlib.pyplot as plt
# 将mask绘制在原图
def draw_image(im,ms,brg,opacity):
image_mask = im.copy()
contours, _ = cv2.findContours(ms, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # 查找轮廓
image_mask = cv2.drawContours(image_mask, contours, -1, (0, 255, 0), 2) # 绘制边界
image_mask = cv2.fillPoly(image_mask, contours, color=brg) # 填充
img_bgr = cv2.addWeighted(im, opacity, image_mask, 1 - opacity, 0)
return im,ms,img_bgr[:,:,::-1]
def main(imagePath,labelPath,bgr,opacity):
image = np.array(Image.open(imagePath).convert('RGB'))
label = np.array(Image.open(labelPath).convert('L'))
a,b,c = draw_image(image,label,bgr,opacity)
plt.figure(figsize=(12,8))
for index,i in enumerate((a,b,c)):
plt.subplot(1,3,index+1)
plt.imshow(i)
plt.savefig('./result.png')
# plt.show()
if __name__ == '__main__':
root = './data/images'
images_path = [os.path.join(root,i) for i in os.listdir(root)]
r = random.randint(0,len(images_path)-1)
img_path = images_path[r] # 随机取出一张图片
mask_path = img_path.replace('images','masks')
# opacity 越小,掩膜效果越深
main(imagePath=img_path, labelPath=mask_path,bgr=(0,0,255),opacity=0.5)