近几年深度学习发展非常迅猛,深度学习用于图像识别、分割等方面效果非常好,像mask rcnn这类网络已经可以做到对象分割了(instance segmentation)。再不跟进就落伍了!!
下图直观的区分了这四种不同处理任务的效果。Instance segmentation的任务不单把cube这个物体找到了,还要分割出不同cube对象。
网上看别人的研究成果都觉得效果很好,实践起来到底怎么样了?
最近尝试下github上的Image Segmentation Keras
训练前,首先要准备数据集,需要标注大量mask图片,找了几款标注工具,只能导出json文件,下面分享下如何把json文件转化成mask 图片。
首先,使用VIA标注工具,标注物体轮廓,导出json文件。json文件里包括了图片中物体的轮廓坐标信息。
标注工具比较多,比如有名的像labelme、VIA等,而VIA是网页版的,用起来比较简单方便,而且流畅,无需安装。
导出的json文件长这样儿的:
{
"_via_settings": {...},
"_via_img_metadata": {
"1.png19539": {
"filename": "1.png",
"size": 19539,
"regions": [
{
"shape_attributes": {
"name": "polyline",
"all_points_x": [
138,
149,
265,
347,
364,
367,
362,
352,
257,
222,
162,
151,
136
],
"all_points_y": [
246,
226,
198,
208,
218,
258,
468,
489,
552,
560,
542,
524,
248
]
},
"region_attributes": {}
}
],
"file_attributes": {}
},
"2.png34896": {...},
"3.png65485": {...}
}
}
运行下面python代码,加载刚才的json文件,解析出轮廓坐标,通过opencv的pointPolygonTest方法,区分物体内还是物体外的像素点,附上不同颜色数值,如该例中,背景像素为0,物体像素为1。保存成图片。
import os
import json
import numpy as np
import skimage.draw
import cv2
IMAGE_FOLDER = "./train/"
MASK_FOLOER = "./mask/"
PATH_ANNOTATION_JSON = 'box.json'
# 加载VIA导出的json文件
annotations = json.load(open(PATH_ANNOTATION_JSON, 'r'))
imgs = annotations["_via_img_metadata"]
for imgId in imgs:
filename = imgs[imgId]['filename']
regions = imgs[imgId]['regions']
if len(regions) <= 0:
continue
# 取出第一个标注的类别,本例只标注了一个物件
polygons = regions[0]['shape_attributes']
# 图片路径
image_path = os.path.join(IMAGE_FOLDER, filename)
# 读出图片,目的是获取到宽高信息
image = cv2.imread(image_path) # image = skimage.io.imread(image_path)
height, width = image.shape[:2]
# 创建空的mask
maskImage = np.zeros((height,width), dtype=np.uint8)
countOfPoints = len(polygons['all_points_x'])
points = [None] * countOfPoints
for i in range(countOfPoints):
x = int(polygons['all_points_x'][i])
y = int(polygons['all_points_y'][i])
points[i] = (x, y)
contours = np.array(points)
# 遍历图片所有坐标
for i in range(width):
for j in range(height):
if cv2.pointPolygonTest(contours, (i, j), False) > 0:
maskImage[j,i] = 1
savePath = MASK_FOLOER + filename
# 保存mask
cv2.imwrite(savePath, maskImage)
生成图片保存在mask的文件夹里,每张mask png图片跟原图名字一样,方便后面做训练。
正常来说,导出的mask图片用肉眼看是黑色的,为了看到mask效果,把背景像素设置成0,物体像素设置成255,这样就能看到效果了。下图是行李箱mask的直观效果。