python遍历目录下的所有目录和文件, python解析json文件, python-opencv截取子图

做某项目的时候,需要根据json文件里面的坐标信息,从原图中截取子图,其中所有的数据都在F盘的tubiao文件夹中,该文件夹下包含几个子文件夹,其中每个子文件夹下面又分别包含若干张图片和json文件,目录如下。

其中json文件内容如下:

{
  "version": "3.7.1",
  "flags": {},
  "shapes": [
    {
      "label": "DT1",
      "line_color": null,
      "fill_color": null,
      "points": [
        [
          967,
          76
        ],
        [
          998,
          106
        ]
      ],
      "shape_type": "rectangle"
    },
    {
      "label": "DT2",
      "line_color": null,
      "fill_color": null,
      "points": [
        [
          997,
          76
        ],
        [
          1028,
          106
        ]
      ],
      "shape_type": "rectangle"
    },
    {
      "label": "DT3",
      "line_color": null,
      "fill_color": null,
      "points": [
        [
          1027,
          77
        ],
        [
          1058,
          107
        ]
      ],
      "shape_type": "rectangle"
    },
    {
      "label": "DT1",
      "line_color": null,
      "fill_color": null,
      "points": [
        [
          1123,
          80
        ],
        [
          1154,
          110
        ]
      ],
      "shape_type": "rectangle"
    },
    {
      "label": "DT2",
      "line_color": null,
      "fill_color": null,
      "points": [
        [
          1152,
          78
        ],
        [
          1183,
          108
        ]
      ],
      "shape_type": "rectangle"
    },
    {
      "label": "DT3",
      "line_color": null,
      "fill_color": null,
      "points": [
        [
          1182,
          78
        ],
        [
          1213,
          108
        ]
      ],
      "shape_type": "rectangle"
    }
  ],
  "lineColor": [
    0,
    255,
    0,
    128
  ],
  "fillColor": [
    255,
    0,
    0,
    128
  ],
  "imageHeight": 1088,
  "imageWidth": 1920
}

python脚本如下:

import cv2
import os
import json
import numpy as np

"""首先根据传入的主目录路径,得到里面的子文件夹路径,其中每个子文件夹里面分别保存着若干jpg图片和一个json文件"""
def get_dirs(main_dir):
    list_dirs = []
    for root, dirs, files in os.walk(main_dir):
        for dir in dirs:
            list_dirs.append(os.path.join(root, dir))
    return list_dirs


"""每个文件夹下面包含若干张jpg图片和一个json文件,根据传入的文件夹路径,得到该文件夹下的所有的jpg文件和json文件。(包含路径)"""
def get_file(dir_path):
    list_jpgs = []
    for root, dirs, files in os.walk(dir_path):
        for file in files:
            if file.endswith(".jpg"):  #过滤得到jpg文件,
                #print(os.path.join(root, file))
                list_jpgs.append(os.path.join(root, file))
            if file.endswith(".json"):   #过滤得到json文件
                json_path = os.path.join(root, file) #json文件只有一个,就不用列表了

    return list_jpgs, json_path #得到所有的jpg文件和json文件的列表(包含路径)

"""
    从json文件中获取到坐标信息,打开并加载完json文件之后,开始解析json内容,
    json中的object对应着python中的字典,
    json中的array对应着python中的列表,
    然后无非就是他们的嵌套,一个一个挨着解析就好了。
"""
def get_coordinate(json_path):
    coordinates = []
    with open(json_path, 'rb') as file_json:
        datas = json.load(file_json)
    #print(datas['shapes'])  #datas的shapes元素是一个列表
    for list in datas['shapes']:#逐个遍历datas['shapes']列表中的每个元素,其中每个元素又是一个字典
        #print(list['points']) #list字典中的points对应的values值就是坐标信息,而该坐标信息又是两个列表,
        coordinates.append(list['points'])
    return coordinates


"""根据文件夹下面的json文件里面的坐标信息,从文件夹下面的jpg图片截取子图"""
if __name__ == '__main__':
    main_dir = r"F:\tubiao"
    i = 0
    dirs = get_dirs(main_dir)#这一步是得到文件夹下的所有文件夹路径,其中每个文件夹下面又包含若干照片和一个json文件。
    for dir in dirs:#针对每个子文件夹里面的图片和json分别进行处理
        print(dir)
        j = 0  #每个文件夹里面的截取的子图保存时从0开始。
        list_jpgs, json_path = get_file(dir)#这一步是得到每个子文件夹里面的jpg图片路径名字和json路径名字
        coordinates = get_coordinate(json_path)#这一步是根据json文件路径得到接送里面保存的坐标信息,
        for list_jpg in list_jpgs:#对每个图片进行截图,
            for coordinate in coordinates:#根据坐标信息截图,有几个坐标信息就截几个图片
                #image = cv2.imread(list_jpg) #不能读取中文路径,用imdecode代替
                #print(list_jpg)
                image = cv2.imdecode(np.fromfile(list_jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
                #image = cv2.cvtColor(image_temp, cv2.COLOR_RGB2BGR) 这个不能加,加上之后截出来的子图保存后颜色都变了。
                x1 = int(coordinate[0][0])  #左上角的顶点X
                y1 = int(coordinate[0][1])  #左上角的顶点Y
                x2 = int(coordinate[1][0])  #右下角的顶点X
                y2 = int(coordinate[1][1])  #右下角的顶点Y

                cropImg = image[y1:y2, x1:x2]  #坐标顺序是Y1:Y2, X1:X2,Y在前,X在后。
                save_name = str(i) + "_cut" + str(j) + ".jpg" #"cut"只是自己随便加的,因为是截子图,所以加了个cut
                save_path = os.path.join(dir,save_name)
                j = j + 1
                #print(save_path)
                # cv2.imwrite(save_path, frame) #保存路径中包含中文,不能用imwrite保存,要用下一行的imencode的方法。
                ret = cv2.imencode('.jpg', cropImg)[1].tofile(save_path)  # [1]表示imencode的第二个返回值,也就是这张图片对应的内存数据
        i = i + 1#保证每个文件夹里面截取子图的时候命名不重复

猜你喜欢

转载自www.cnblogs.com/cumtchw/p/12456074.html