当前位置:   article > 正文

mask rcnn 将mask 转json数据01_pycococreatortools.binary_mask_to_polygon

pycococreatortools.binary_mask_to_polygon

目的:存在 图片及其对应的mask 文件 ,通过Python代码转化为json 数据,无需手工制作

1、首先准备好 图片和及其对应的mask  ,使用的mask为黑底白色 

  1. #!/usr/bin/env python3
  2. #把 mask和原图 集合到一个json 文件中
  3. import datetime
  4. import json
  5. import os
  6. import re
  7. import fnmatch
  8. from PIL import Image
  9. import numpy as np
  10. from pycococreatortools import pycococreatortools
  11. ROOT_DIR = 'train'
  12. IMAGE_DIR = os.path.join(ROOT_DIR, "shapes_train2018")
  13. ANNOTATION_DIR = os.path.join(ROOT_DIR, "annotations")
  14. INFO = {
  15. "description": "Example Dataset",
  16. "url": "https://github.com/waspinator/pycococreator",
  17. "version": "0.1.0",
  18. "year": 2018,
  19. "contributor": "waspinator",
  20. "date_created": datetime.datetime.utcnow().isoformat(' ')
  21. }
  22. LICENSES = [
  23. {
  24. "id": 1,
  25. "name": "Attribution-NonCommercial-ShareAlike License",
  26. "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/"
  27. }
  28. ]
  29. #适当修改类别
  30. CATEGORIES = [
  31. {
  32. 'id': 1,
  33. 'name': 'square',
  34. 'supercategory': 'shape',
  35. },
  36. {
  37. 'id': 2,
  38. 'name': 'circle',
  39. 'supercategory': 'shape',
  40. },
  41. {
  42. 'id': 3,
  43. 'name': 'triangle',
  44. 'supercategory': 'shape',
  45. },
  46. ]
  47. #返回rgb文件路径 不做修改
  48. def filter_for_jpeg(root, files):
  49. file_types = ['*.jpeg', '*.jpg']
  50. file_types = r'|'.join([fnmatch.translate(x) for x in file_types])
  51. files = [os.path.join(root, f) for f in files]
  52. files = [f for f in files if re.match(file_types, f)]
  53. return files
  54. #返回mask文件路径 不做修改
  55. def filter_for_annotations(root, files, image_filename):
  56. file_types = ['*.png']
  57. file_types = r'|'.join([fnmatch.translate(x) for x in file_types])
  58. basename_no_extension = os.path.splitext(os.path.basename(image_filename))[0]
  59. file_name_prefix = basename_no_extension + '.*'
  60. files = [os.path.join(root, f) for f in files]
  61. files = [f for f in files if re.match(file_types, f)]
  62. files = [f for f in files if re.match(file_name_prefix, os.path.splitext(os.path.basename(f))[0])]
  63. return files
  64. def main():
  65. coco_output = {
  66. "info": INFO,
  67. "licenses": LICENSES,
  68. "categories": CATEGORIES,
  69. "images": [],
  70. "annotations": []
  71. }
  72. image_id = 1
  73. segmentation_id = 1
  74. # filter for jpeg images
  75. for root, _, files in os.walk(IMAGE_DIR):
  76. image_files = filter_for_jpeg(root, files)
  77. # go through each image
  78. for image_filename in image_files:
  79. image = Image.open(image_filename)
  80. image_info = pycococreatortools.create_image_info(
  81. image_id, os.path.basename(image_filename), image.size)
  82. coco_output["images"].append(image_info)
  83. # filter for associated png annotations
  84. for root, _, files in os.walk(ANNOTATION_DIR):
  85. annotation_files = filter_for_annotations(root, files, image_filename)
  86. # go through each associated annotation
  87. for annotation_filename in annotation_files:
  88. print(annotation_filename)
  89. class_id = [x['id'] for x in CATEGORIES if x['name'] in annotation_filename][0]
  90. category_info = {'id': class_id, 'is_crowd': 'crowd' in image_filename}
  91. binary_mask = np.asarray(Image.open(annotation_filename)
  92. .convert('1')).astype(np.uint8)
  93. annotation_info = pycococreatortools.create_annotation_info(
  94. segmentation_id, image_id, category_info, binary_mask,
  95. image.size, tolerance=2)
  96. if annotation_info is not None:
  97. coco_output["annotations"].append(annotation_info)
  98. segmentation_id = segmentation_id + 1
  99. image_id = image_id + 1
  100. with open('{}/instances_shape_train2018.json'.format(ROOT_DIR), 'w') as output_json_file:
  101. json.dump(coco_output, output_json_file)
  102. if __name__ == "__main__":
  103. main()

上面代码是 多个标注数据 数据集合到一个json文件中的

{"info": {"description": "Example Dataset", "url": "https://github.com/waspinator/pycococreator", "version": "0.1.0", "year": 2018, "contributor": "waspinator", "date_created": "2021-03-13 06:54:48.550064"}, "licenses": [{"id": 1, "name": "Attribution-NonCommercial-ShareAlike License", "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/"}], "categories": [{"id": 1, "name": "square", "supercategory": "shape"}], "images": [{"id": 1, "file_name": "0.jpg", "width": 256, "height": 384, "date_captured": "2021-03-13 04:34:17.084304", "license": 1, "coco_url": "", "flickr_url": ""}, {"id": 2, "file_name": "1.jpg", "width": 256, "height": 384, "date_captured": "2021-03-13 04:34:17.084304", "license": 1, "coco_url": "", "flickr_url": ""}, {"id": 3, "file_name": "2.jpg", "width": 384, "height": 256, "date_captured": "2021-03-13 04:34:17.084304", "license": 1, "coco_url": "", "flickr_url": ""}], "annotations": [{"id": 1, "image_id": 1, "category_id": 1, "iscrowd": 0, "area": 130, "bbox": [106.0, 109.0, 31.0, 15.0], "segmentation": [[126.0, 123.5, 113.0, 121.5, 105.5, 109.0, 118.0, 120.5, 136.5, 115.0, 126.0, 123.5]], "width": 256, "height": 384}, {"id": 2, "image_id": 2, "category_id": 1, "iscrowd": 0, "area": 1734, "bbox": [51.0, 158.0, 41.0, 69.0], "segmentation": [[74.0, 226.5, 54.5, 213.0, 50.5, 194.0, 70.5, 160.0, 76.0, 157.5, 81.5, 161.0, 82.5, 171.0, 91.5, 177.0, 91.5, 185.0, 84.5, 210.0, 74.0, 226.5]], "width": 256, "height": 384}, {"id": 3, "image_id": 3, "category_id": 1, "iscrowd": 0, "area": 2444, "bbox": [233.0, 127.0, 33.0, 104.0], "segmentation": [[254.0, 230.5, 237.5, 229.0, 244.5, 220.0, 242.5, 191.0, 232.5, 175.0, 236.5, 171.0, 232.5, 166.0, 235.5, 150.0, 245.0, 126.5, 254.5, 130.0, 264.5, 149.0, 264.5, 224.0, 254.0, 230.5]], "width": 384, "height": 256}]}

2 下面的代码是 ,每对数据  对应一个json 文件(只能实现mask中 只有一个类的情况)

  1. #!/usr/bin/env python3
  2. #功能批量将mask 转单个json
  3. import datetime
  4. import json
  5. import os
  6. import io
  7. import re
  8. import fnmatch
  9. import json
  10. from PIL import Image
  11. import numpy as np
  12. from pycococreatortools import pycococreatortools
  13. from PIL import Image
  14. import base64
  15. from base64 import b64encode
  16. ROOT_DIR = 'train1'
  17. IMAGE_DIR = os.path.join(ROOT_DIR, "pic")
  18. ANNOTATION_DIR = os.path.join(ROOT_DIR, "annotations")
  19. def img_tobyte(img_pil):
  20. # 类型转换 重要代码
  21. # img_pil = Image.fromarray(roi)
  22. ENCODING='utf-8'
  23. img_byte=io.BytesIO()
  24. img_pil.save(img_byte,format='PNG')
  25. binary_str2=img_byte.getvalue()
  26. imageData = base64.b64encode(binary_str2)
  27. base64_string = imageData.decode(ENCODING)
  28. return base64_string
  29. annotation_files=os.listdir(ANNOTATION_DIR)
  30. for annotation_filename in annotation_files:
  31. coco_output = {
  32. "version": "3.16.7",
  33. "flags": {},
  34. "fillColor": [255, 0,0,128],
  35. "lineColor": [0,255,0, 128],
  36. "imagePath": {},
  37. "shapes": [],
  38. "imageData": {},
  39. "imageHeight": 512,
  40. "imageWidth": 512
  41. }
  42. print(annotation_filename)
  43. class_id = 1
  44. name = annotation_filename.split('.',3)[0]
  45. name1=name+'.jpg'
  46. coco_output["imagePath"]=name1
  47. image = Image.open(IMAGE_DIR+'/'+ name1)
  48. imageData=img_tobyte(image)
  49. coco_output["imageData"]= imageData
  50. binary_mask = np.asarray(Image.open(ANNOTATION_DIR+'/'+annotation_filename)
  51. .convert('1')).astype(np.uint8)
  52. segmentation=pycococreatortools.binary_mask_to_polygon(binary_mask, tolerance=3)
  53. list1=[]
  54. for i in range(0, len(segmentation[0]), 2):
  55. list1.append( [segmentation[0][i],segmentation[0][i+1]])
  56. seg_info = {'points': list1, "fill_color":'null' ,"line_color":'null' ,"label": "1", "shape_type": "polygon","flags": {}}
  57. coco_output["shapes"].append(seg_info)
  58. full_path='{}/'+name+'.json'
  59. with open( full_path.format(ROOT_DIR), 'w') as output_json_file:
  60. json.dump(coco_output, output_json_file)

3 需要自己改写成 自己需要的文件

  1. #!/usr/bin/env python3
  2. #功能批量将多个同类mask 转单个json
  3. #筛选多余的点集合 可能mask制作的不规范,产生多余的点,这样的话,利用点的数量,做一个限制
  4. #我这里设置的是10 可根据具体效果改动
  5. for item in segmentation:
  6. if(len(item)>10):
  7. list1=[]
  8. for i in range(0, len(item), 2):
  9. list1.append( [item[i],item[i+1]])
  10. seg_info = {'points': list1, "fill_color":'null' ,"line_color":'null' ,"label": "1", "shape_type": "polygon","flags": {}}
  11. coco_output["shapes"].append(seg_info)
  12. coco_output[ "imageHeight"]=binary_mask.shape[0]
  13. coco_output[ "imageWidth"]=binary_mask.shape[1]
  14. full_path='{}/'+name+'.json'
  15. with open( full_path.format(ROOT_DIR), 'w') as output_json_file:
  16. json.dump(coco_output, output_json_file)

完善的代码

  1. #!/usr/bin/env python3
  2. #功能批量将多个同类mask 转单个json
  3. import datetime
  4. import json
  5. import os
  6. import io
  7. import re
  8. import fnmatch
  9. import json
  10. from PIL import Image
  11. import numpy as np
  12. from pycococreatortools import pycococreatortools
  13. from PIL import Image
  14. import base64
  15. from base64 import b64encode
  16. ROOT_DIR = 'C:/Users/11549/Desktop/pycococreator-master/examples/shapes/train2/pic/'
  17. IMAGE_DIR = os.path.join(ROOT_DIR, "pic")
  18. ANNOTATION_DIR = os.path.join(ROOT_DIR, "mask")
  19. def img_tobyte(img_pil):
  20. # 类型转换 重要代码
  21. # img_pil = Image.fromarray(roi)
  22. ENCODING='utf-8'
  23. img_byte=io.BytesIO()
  24. img_pil.save(img_byte,format='PNG')
  25. binary_str2=img_byte.getvalue()
  26. imageData = base64.b64encode(binary_str2)
  27. base64_string = imageData.decode(ENCODING)
  28. return base64_string
  29. annotation_files=os.listdir(ANNOTATION_DIR)
  30. for annotation_filename in annotation_files:
  31. coco_output = {
  32. "version": "3.16.7",
  33. "flags": {},
  34. "fillColor": [255, 0,0,128],
  35. "lineColor": [0,255,0, 128],
  36. "imagePath": {},
  37. "shapes": [],
  38. "imageData": {} }
  39. print(annotation_filename)
  40. class_id = 1
  41. name = annotation_filename.split('.',3)[0]
  42. name1=name+'.jpg'
  43. coco_output["imagePath"]=name1
  44. image = Image.open(IMAGE_DIR+'/'+ name1)
  45. imageData=img_tobyte(image)
  46. coco_output["imageData"]= imageData
  47. binary_mask = np.asarray(Image.open(ANNOTATION_DIR+'/'+annotation_filename)
  48. .convert('1')).astype(np.uint8)
  49. segmentation=pycococreatortools.binary_mask_to_polygon(binary_mask, tolerance=3)
  50. #筛选多余的点集合
  51. for item in segmentation:
  52. if(len(item)>10):
  53. list1=[]
  54. for i in range(0, len(item), 2):
  55. list1.append( [item[i],item[i+1]])
  56. seg_info = {'points': list1, "fill_color":'null' ,"line_color":'null' ,"label": "1", "shape_type": "polygon","flags": {}}
  57. coco_output["shapes"].append(seg_info)
  58. coco_output[ "imageHeight"]=binary_mask.shape[0]
  59. coco_output[ "imageWidth"]=binary_mask.shape[1]
  60. full_path='{}/'+name+'.json'
  61. with open( full_path.format(ROOT_DIR), 'w') as output_json_file:
  62. json.dump(coco_output, output_json_file)

4  生成的json文件,效果如下

  1. {
  2. "version": "3.20.0",
  3. "flags": {},
  4. "shapes": [
  5. {
  6. "label": "1",
  7. "line_color": null,
  8. "fill_color": null,
  9. "points": [
  10. [
  11. 362.59375,
  12. 166.1875
  13. ],
  14. [
  15. 357.90625,
  16. 216.96875
  17. ],
  18. [
  19. 429.78125,
  20. 216.96875
  21. ],
  22. [
  23. 436.03125,
  24. 171.65625
  25. ]
  26. ],
  27. "shape_type": "polygon",
  28. "flags": {}
  29. }
  30. ],
  31. "lineColor": [
  32. 0,
  33. 255,
  34. 0,
  35. 128
  36. ],
  37. "fillColor": [
  38. 255,
  39. 0,
  40. 0,
  41. 128
  42. ],
  43. "imagePath": "3.jpg",
  44. "imageData": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAIAAgADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIW QS+trmElPmVv057GpFfU//9k=",
  45. "imageHeight": 512,
  46. "imageWidth": 512
  47. }

这样我们就有了 json数据和图片数据了,可以安装步骤生成 coco格式的数据l

5   把json数据和图片数据放在一起,利用各bat脚本 生成labelme_json 数据   如下图所示。

  1. @echo off
  2. for %%i in (*.json) do labelme_json_to_dataset "%%i"
  3. pause

6   然而 其中的label.png 文件,并不可用 需要转为8位的数据 才可以使用 

下面是批量的代码

  1. import numpy as np
  2. from PIL import Image
  3. import os
  4. YourFile_path='labelme_json/'
  5. files = os.listdir(YourFile_path)
  6. path1='cv2_mask/'
  7. for item in files:
  8. src=YourFile_path+item+'/label.png'
  9. img= Image.open(src)
  10. img = Image.fromarray(np.uint8(img))
  11. name = item.split("_")[0]
  12. name=name+'.png'
  13. img.save( path1+name)

最终生成 可以使用的数据  输入mask -rcnn中,

7 零碎的代码

  1. #针对一个box的检测程序,输出x , y, w, h 文件名
  2. #统计bbox的程序
  3. import cv2
  4. import os
  5. import operator
  6. path='mask/'
  7. def takeSecond1(elem):
  8. return list(elem)[2]*list(elem)[3]
  9. list1=[ ]
  10. filelist = os.listdir(path)
  11. for item in filelist:
  12. bgr_img = cv2.imread(path+item)
  13. gray_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY)
  14. gray_img = cv2.blur(gray_img, (5,5))
  15. th, binary = cv2.threshold(gray_img, 125, 255, cv2.THRESH_OTSU)
  16. contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
  17. bounding_boxes = [cv2.boundingRect(cnt) for cnt in contours]
  18. bounding_boxes.sort(key=takeSecond1)
  19. list1.append([item,bgr_img.shape,bounding_boxes[-1]])
  20. # cv2.drawContours(bgr_img, contours, -1, (0, 0, 255), 3)
  21. # for i in range(len(bounding_boxes)):
  22. # print(i)
  23. # cv2.imshow("name", bgr_img)
  24. # cv2.waitKey(6000)
  25. # cv2.destroyAllWindows()
  1. #coco 可视化代码
  2. from pycocotools.coco import COCO
  3. import numpy as np
  4. import skimage.io as io
  5. import matplotlib.pyplot as plt
  6. import pylab
  7. image_directory = 'train/shapes_train2018/'
  8. annotation_file = 'C:/Users/11549/Desktop/pycococreator-master/examples/shapes/train/instances_shape_train2018.json'
  9. example_coco = COCO(annotation_file)
  10. categories = example_coco.loadCats(example_coco.getCatIds())
  11. category_names = [category['name'] for category in categories]
  12. print('Custom COCO categories: \n{}\n'.format(' '.join(category_names)))
  13. category_names = set([category['supercategory'] for category in categories])
  14. print('Custom COCO supercategories: \n{}'.format(' '.join(category_names)))
  15. category_ids = example_coco.getCatIds(catNms=['square'])
  16. image_ids = example_coco.getImgIds(catIds=category_ids)
  17. image_data = example_coco.loadImgs(image_ids[np.random.randint(0, len(image_ids))])[0]
  18. image_data
  19. # load and display instance annotations
  20. image = io.imread(image_directory + image_data['file_name'])
  21. plt.imshow(image); plt.axis('off')
  22. pylab.rcParams['figure.figsize'] = (8.0, 10.0)
  23. annotation_ids = example_coco.getAnnIds(imgIds=image_data['id'], catIds=category_ids, iscrowd=None)
  24. annotations = example_coco.loadAnns(annotation_ids)
  25. example_coco.showAnns(annotations)
  1. #重命名代码
  2. import os
  3. path = 'C:/Users/11549/Desktop/pycococreator-master/examples/shapes/train1/shapes_train2018/cv2mask/'
  4. filelist = os.listdir(path)
  5. for i in range(len(filelist)):
  6. print(i)
  7. src = os.path.join(os.path.abspath(path),filelist[i])
  8. dst = os.path.join(os.path.abspath(path),str(i) + '.png')
  9. os.rename(src,dst)
  10. import os
  11. import cv2
  12. path = 'pic/'
  13. path1 = '1/'
  14. # os.access(path+'0002-01.jpg', os.F_OK)
  15. filelist = os.listdir(path)
  16. for item in filelist:
  17. src = os.path.join(os.path.abspath(path),item)
  18. img = cv2.imread(src)
  19. res=cv2.resize(img,(757,568))
  20. cv2.imwrite(path1+item, res)

 

8 相应的安装包 下载地址:https://download.csdn.net/download/weixin_44576543/15806642

 

 

last one 由于时间比较急 ,所以比较粗糙  大家不懂的可以留言评论 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/80999
推荐阅读
相关标签
  

闽ICP备14008679号