我使用的是labelme标注的json文件,简略版格式如下(主要就用了json文件中的这几个值)
{"fillColor": [255, 0, 0, 128],
"flag": {},
"imageData": "imagedata",
"shapes":
[{"points": [[236, 974], [244, 919], [268, 869], [297, 861], [341, 877], [363, 921], [371, 961], [362, 997], [304, 997], [247, 997]], "label": "pian", "line_color": "null", "fill_color": "null"}],
"lineColor": [0, 255, 0, 128],
"imagePath": "00a259c031a644101dccdcfd2e7b0509.jpg"}
create_mask_rcnn_tfrecord.py
# -*- coding: utf-8 -*-
from utils import label_map_util
import cv2
import glob
import hashlib
import io
import numpy as np
import os
import PIL.Image
import tensorflow as tf
import json
import read_pbtxt_file
flags = tf.app.flags
flags.DEFINE_string('images_dir', '/home/ai/Downloads/collection_mask_teeth/imgResize', 'Path to images directory.')
flags.DEFINE_string('annotations_json_dir', '/home/ai/Downloads/collection_mask_teeth/AnnotationJson',
'Path to annotations directory.')
flags.DEFINE_string('label_map_path', '../data/teeth_label_map.pbtxt', 'Path to label map proto.')
flags.DEFINE_string('output_path', '../All_tf_record/teeth_mask.record', 'Path to the output tfrecord.')
FLAGS = flags.FLAGS
def int64_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
def int64_list_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=value))
def bytes_feature(value):
return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
def bytes_list_feature(value):
return tf.train.Feature(bytes_list=tf.train.BytesList(value=value))
def float_list_feature(value):
return tf.train.Feature(float_list=tf.train.FloatList(value=value))
def label_id_map(path,num_classes):
label_map = label_map_util.load_labelmap(path)
# use_display_name,你的pbtxt文件中如果有可能有name和display_name,当为true使用display_name,false时使用name
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=num_classes,
use_display_name=True)
new_dict ={d['name']:d['id'] for d in categories}
return new_dict
def create_tf_example(annotation_dict, label_map_dict=None):
"""Converts image and annotations to a tf.Example proto.
Args:
annotation_dict: A dictionary containing the following keys:
['height', 'width', 'filename', 'sha256_key', 'encoded_jpg',
'format', 'xmins', 'xmaxs', 'ymins', 'ymaxs', 'masks',
'class_names'].
label_map_dict: A dictionary maping class_names to indices.
Returns:
example: The converted tf.Example.
Raises:
ValueError: If label_map_dict is None or is not containing a class_name.
"""
if annotation_dict is None:
return None
if label_map_dict is None:
raise ValueError('`label_map_dict` is None')
height = annotation_dict.get('height', None)
width = annotation_dict.get('width', None)
filename = annotation_dict.get('filename', None)
sha256_key = annotation_dict.get('sha256_key', None)
encoded_jpg = annotation_dict.get('encoded_jpg', None)
image_format = annotation_dict.get('format', None)
xmins = annotation_dict.get('xmins', None)
xmaxs = annotation_dict.get('xmaxs', None)
ymins = annotation_dict.get('ymins', None)
ymaxs = annotation_dict.get('ymaxs', None)
masks = annotation_dict.get('masks', None)
class_names = annotation_dict.get('class_names', None)
labels = []
for class_name in class_names:
label = label_map_dict.get(class_name, 'None')
if label is None:
raise ValueError('`label_map_dict` is not containing {}.'.format(
class_name))
# labels.append(label)
labels.append(label)
print('image is {},label is {},'.format(filename, class_names))
encoded_masks = []
for mask in masks:
pil_image = PIL.Image.fromarray(mask)
# pil_image = PIL.Image.fromarray(mask)
output_io = io.BytesIO()
pil_image.save(output_io, format='PNG')
encoded_masks.append(output_io.getvalue())
feature_dict = {
'image/height': int64_feature(height),
'image/width': int64_feature(width),
'image/filename': bytes_feature(filename.encode('utf8')),
'image/source_id': bytes_feature(filename.encode('utf8')),
'image/key/sha256': bytes_feature(sha256_key.encode('utf8')),
'image/encoded': bytes_feature(encoded_jpg),
'image/format': bytes_feature(image_format.encode('utf8')),
'image/object/bbox/xmin': float_list_feature(xmins),
'image/object/bbox/xmax': float_list_feature(xmaxs),
'image/object/bbox/ymin': float_list_feature(ymins),
'image/object/bbox/ymax': float_list_feature(ymaxs),
'image/object/mask': bytes_list_feature(encoded_masks),
'image/object/class/label': int64_list_feature(labels)}
example = tf.train.Example(features=tf.train.Features(
feature=feature_dict))
return example
def _get_annotation_dict(images_dir, annotation_json_path):
"""Get boundingboxes and masks.
Args:
images_dir: Path to images directory.
annotation_json_path: Path to annotated json file corresponding to
the image. The json file annotated by labelme with keys:
['lineColor', 'imageData', 'fillColor', 'imagePath', 'shapes',
'flags'].
Returns:
annotation_dict: A dictionary containing the following keys:
['height', 'width', 'filename', 'sha256_key', 'encoded_jpg',
'format', 'xmins', 'xmaxs', 'ymins', 'ymaxs', 'masks',
'class_names'].
#
# Raises:
# ValueError: If images_dir or annotation_json_path is not exist.
"""
# if not os.path.exists(images_dir):
# raise ValueError('`images_dir` is not exist.')
#
# if not os.path.exists(annotation_json_path):
# raise ValueError('`annotation_json_path` is not exist.')
if (not os.path.exists(images_dir) or
not os.path.exists(annotation_json_path)):
return None
with open(annotation_json_path, 'r') as f:
json_text = json.load(f)
shapes = json_text.get('shapes', None)
if shapes is None:
return None
image_relative_path = json_text.get('imagePath', None)
if image_relative_path is None:
return None
image_name = image_relative_path.split('/')[-1]
image_path = os.path.join(images_dir, image_name)
if not os.path.exists(image_path):
return None
# change_jpg = cv2.imread(image_path)
# image_path = cv2.imwrite()
# image_format = image_name.split('.')[-1].replace('jpg', 'jpeg')
with tf.gfile.GFile(image_path, 'rb') as fid:
encoded_jpg = fid.read()
encoded_jpg_io = io.BytesIO(encoded_jpg)
image_ = PIL.Image.open(encoded_jpg_io)
if image_.format != 'JPEG':
raise ValueError('Image format not JPEG ')
image = cv2.imread(image_path)
height = image.shape[0]
width = image.shape[1]
key = hashlib.sha256(encoded_jpg).hexdigest()
xmins = []
xmaxs = []
ymins = []
ymaxs = []
masks = []
class_names = []
hole_polygons = []
# mask = np.zeros(image.shape[:2])
for mark in shapes:
class_name = mark.get('label')
class_names.append(class_name)
# class_names.append('ltrcat_dog')
polygon = mark.get('points')
# print('polygon == ',polygon)
polygon = np.array(polygon,dtype=np.int32)
if class_name == 'hole':
hole_polygons.append(polygon)
else:
mask = np.zeros(image.shape[:2], dtype='uint8')
# mask = np.zeros(image.shape[:2])
# print('polygon======',[polygon])
cv2.fillPoly(mask, [polygon], 1)
masks.append(mask)
# Boundingbox
x = polygon[:, 0]
y = polygon[:, 1]
xmin = np.min(x)
xmax = np.max(x)
ymin = np.min(y)
ymax = np.max(y)
xmins.append(float(xmin) / width)
xmaxs.append(float(xmax) / width)
ymins.append(float(ymin) / height)
ymaxs.append(float(ymax) / height)
# Remove holes in mask
for mask in masks:
cv2.fillPoly(mask, hole_polygons, 0)
# print('masks-----list == ',masks)
annotation_dict = {'height': height,
'width': width,
'filename': image_name,
'sha256_key': key,
'encoded_jpg': encoded_jpg,
# 'format': image_format,
'format': image_path,
'xmins': xmins,
'xmaxs': xmaxs,
'ymins': ymins,
'ymaxs': ymaxs,
'masks': masks,
'class_names': class_names
# 'class_names': 'ltrcat_dog'
}
return annotation_dict
def main(_):
if not os.path.exists(FLAGS.images_dir):
raise ValueError('`images_dir` is not exist.')
if not os.path.exists(FLAGS.annotations_json_dir):
raise ValueError('`annotations_json_dir` is not exist.')
if not os.path.exists(FLAGS.label_map_path):
raise ValueError('`label_map_path` is not exist.')
label_map = label_id_map(FLAGS.label_map_path,2)
writer = tf.python_io.TFRecordWriter(FLAGS.output_path)
num_annotations_skiped = 0
annotations_json_path = os.path.join(FLAGS.annotations_json_dir, '*.json')
for i, annotation_file in enumerate(glob.glob(annotations_json_path)):
if i % 100 == 0:
print('On image %d'%i)
annotation_dict = _get_annotation_dict(
FLAGS.images_dir, annotation_file)
# print('=====masks====',annotation_dict['masks'])
if annotation_dict is None:
num_annotations_skiped += 1
continue
tf_example = create_tf_example(annotation_dict, label_map)
writer.write(tf_example.SerializeToString())
print('Successfully created TFRecord to {}.'.format(FLAGS.output_path))
if __name__ == '__main__':
tf.app.run()