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

本文介绍了一个Python脚本,用于根据JSON文件中的坐标信息从图像中截取矩形区域。脚本首先遍历指定目录下的子文件夹,找到每个文件夹中的图片和JSON文件,然后解析JSON文件获取坐标,最后根据坐标从图片中裁剪出子图并保存。整个过程涉及到文件路径处理、JSON解析和OpenCV库的使用。
摘要由CSDN通过智能技术生成

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

635036-20200310153230262-1483759954.png

其中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脚本如下:

importcv2importosimportjsonimportnumpy as np"""首先根据传入的主目录路径,得到里面的子文件夹路径,其中每个子文件夹里面分别保存着若干jpg图片和一个json文件"""

defget_dirs(main_dir):

list_dirs=[]for root, dirs, files inos.walk(main_dir):for dir indirs:

list_dirs.append(os.path.join(root, dir))returnlist_dirs"""每个文件夹下面包含若干张jpg图片和一个json文件,根据传入的文件夹路径,得到该文件夹下的所有的jpg文件和json文件。(包含路径)"""

defget_file(dir_path):

list_jpgs=[]for root, dirs, files inos.walk(dir_path):for file infiles: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中的列表,

然后无非就是他们的嵌套,一个一个挨着解析就好了。"""

defget_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'])returncoordinates"""根据文件夹下面的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#保证每个文件夹里面截取子图的时候命名不重复

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值