foreword
I have been doing target detection related content before, and I am familiar with using LabelImg to label detection data. However, recently trying to explore the image segmentation scene, we need to use LabelMe to label the data labels for segmentation. This article records the process.
Image Segmentation Data Label Example
Taking road segmentation as an example, the figure below is deepglobe
a set of data in the dataset, the right side is the image taken by satellite, and the left side is the image label. The image is marked in the form of Mask.
LabelMe installation
The installation is very simple, just use pip to install:
pip install labelme
data preparation
Before starting, organize the data location according to the following directory:
- annotations: an empty folder, ready to save the labeled label
- images: Place the picture and copy the picture data into it
- label.txt: This is mainly used to pre-set
label.txt
the content of the category file as follows:
__ignore__
_background_
road
The content of the front line is fixed, which is related to the post-processing script. The third line starts with the category name. I only need to divide the road here, so there is only one road category.
software use
First Anaconda Prompt
enter the root directory of the data file inside:
cd D:\Dataset\road_dataset
Then start labelme:
labelme --labels label.txt
Choose to OpenDir
import pictures:
Set label output folder:
`
Set as previously built annotations
:
Click Create Polygons
(shortcut key Ctrl+N), circle around the target point, similar to cutout in PS, connect end to end, save it.
format conversion
After marking, you can get json
the label of the format.
Next, format conversion needs to be performed according to the label to obtain the label of the image type.
The following conversion code is modified from the labelme official warehouse , mainly modifying the file loading logic and path:
#!/usr/bin/env python
from __future__ import print_function
import argparse
import glob
import os
import os.path as osp
import imgviz
import numpy as np
import labelme
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument("--input_dir", default="D:/Dataset/road_dataset/annotations", help="input annotated directory")
parser.add_argument("--output_dir", default="D:/Dataset/road_dataset", help="output dataset directory")
parser.add_argument("--labels", default="D:/Dataset/road_dataset/label.txt", help="labels file")
args = parser.parse_args()
args.noviz = False
if not osp.exists(args.output_dir):
os.makedirs(args.output_dir)
os.makedirs(osp.join(args.output_dir, "JPEGImages"))
os.makedirs(osp.join(args.output_dir, "SegmentationClass"))
os.makedirs(osp.join(args.output_dir, "SegmentationClassPNG"))
if not args.noviz:
os.makedirs(
osp.join(args.output_dir, "SegmentationClassVisualization")
)
print("Creating dataset:", args.output_dir)
class_names = []
class_name_to_id = {
}
for i, line in enumerate(open(args.labels).readlines()):
class_id = i - 1 # starts with -1
class_name = line.strip()
class_name_to_id[class_name] = class_id
if class_id == -1:
assert class_name == "__ignore__"
continue
elif class_id == 0:
assert class_name == "_background_"
class_names.append(class_name)
class_names = tuple(class_names)
print("class_names:", class_names)
out_class_names_file = osp.join(args.output_dir, "class_names.txt")
with open(out_class_names_file, "w") as f:
f.writelines("\n".join(class_names))
print("Saved class_names:", out_class_names_file)
for filename in glob.glob(osp.join(args.input_dir, "*.json")):
print("Generating dataset from:", filename)
label_file = labelme.LabelFile(filename=filename)
base = osp.splitext(osp.basename(filename))[0]
out_img_file = osp.join(args.output_dir, "JPEGImages", base + ".jpg")
out_lbl_file = osp.join(
args.output_dir, "SegmentationClass", base + ".npy"
)
out_png_file = osp.join(
args.output_dir, "SegmentationClassPNG", base + ".png"
)
if not args.noviz:
out_viz_file = osp.join(
args.output_dir,
"SegmentationClassVisualization",
base + ".jpg",
)
with open(out_img_file, "wb") as f:
f.write(label_file.imageData)
img = labelme.utils.img_data_to_arr(label_file.imageData)
lbl, _ = labelme.utils.shapes_to_label(
img_shape=img.shape,
shapes=label_file.shapes,
label_name_to_value=class_name_to_id,
)
labelme.utils.lblsave(out_png_file, lbl)
np.save(out_lbl_file, lbl)
if not args.noviz:
viz = imgviz.label2rgb(
lbl,
imgviz.rgb2gray(img),
font_size=15,
label_names=class_names,
loc="rb",
)
imgviz.io.imsave(out_viz_file, viz)
if __name__ == "__main__":
main()
After running, there will be several more folders:
- JPEGImages: raw images
- SegmentationClass: npy format label
- SegmentationClassPNG: mask image
- SegmentationClassVisualization: Overlay display of mask image and real image
- class_names.txt: all classes (including background)
label visualization
For this task, I only need a white mask image, but labelme's mask visualization does not give the relevant color interface.
So I re-rolled a mask visualization program with opencv:
import json
import cv2
import numpy as np
from tqdm import tqdm
import os
fill_color = (255, 255, 255)
root_dir = 'D:/Dataset/road_dataset'
def visualize_one(label_name):
with open(root_dir + '/annotations' + '/' + label_name + '.json', 'r') as obj:
dict = json.load(obj)
img = cv2.imread(root_dir + '/images' + '/' + label_name + '.jpg')
for label in dict['shapes']:
points = np.array(label['points'], dtype=np.int32)
black_img = np.zeros(img.shape)
cv2.polylines(black_img, [points], isClosed=True, color=fill_color, thickness=1)
cv2.fillPoly(black_img, [points], color=fill_color)
cv2.imwrite(root_dir + '/labels' + '/' + label_name + '.jpg', black_img)
if __name__ == '__main__':
os.mkdir(root_dir + '/labels')
for i in tqdm(os.listdir(os.path.join(root_dir, "annotations"))):
label_name = i[:-5]
visualize_one(label_name)
After running, you can get the corresponding label smoothly.
reference
[1] Labelme segmentation labeling software uses https://blog.csdn.net/qq_37541097/article/details/120162702