将yolov4预测结果保存为json文件

将yolov4预测结果保存为json文件

如果代码是用mmdetection框架写的,转化部分的代码不需要自己来写,mmdetection自带的脚本可以把预测结果转为json文件。
只需运行python tools/test.py configs/involution/faster_rcnn_red50_neck_fpn_1x_coco.py work_dirs/faster_rcnn_red50_neck_fpn_1x_coco/latest.pth --format-only --options "jsonfile_prefix=./results"即可得到预测结果文件,具体使用方法可以查阅mmdetection的官方文档。
如果没有用到mmdetection框架,可以自己简单修改一下预测部分的代码也是可以将预测结果保存为json文件的。

修改detect_image()函数

参考yolo.py文件中的detect_image()函数,定义save_json函数,返回值不再是带框的图片,而是返回存放框信息的content_json列表,所以在没有检测到物体的时候,返回值不再是原图而是一个空列表。
这里有两种生成json文件的方法,第一种是先读取测试集文件夹下所有的图片名称,然后读取官方给的测试集对应的json文件,如果找到该图片的file_name,则读取image_id,categories_id和预测框bbox以及scores的信息,保存在content_json列表中,在predict.py中调用yolo.py中写好的save_json函数,将结果保存在result.json文件中。

def save_json(self,image,file_name,path_json):
    image_shape = np.array(np.shape(image)[0:2])
        
    if self.letterbox_image:
        crop_img = np.array(letterbox_image(image, (self.model_image_size[1],self.model_image_size[0])))
    else:
        crop_img = image.convert('RGB')
        crop_img = crop_img.resize((self.model_image_size[1],self.model_image_size[0]), Image.BICUBIC)
    photo = np.array(crop_img,dtype = np.float32) / 255.0
    photo = np.transpose(photo, (2, 0, 1))
    
    images = [photo]
    
    with torch.no_grad():
        images = torch.from_numpy(np.asarray(images))
        if self.cuda:
            images = images.cuda()

        outputs = self.net(images)
        output_list = []
        for i in range(3):
            output_list.append(self.yolo_decodes[i](outputs[i]))

        
        output = torch.cat(output_list, 1)
        batch_detections = non_max_suppression(output, len(self.class_names),
                                                conf_thres=self.confidence,
                                                nms_thres=self.iou)
        
        try:
            batch_detections = batch_detections[0].cpu().numpy()
        except:
            return []
        
        top_index = batch_detections[:,4] * batch_detections[:,5] > self.confidence
        top_conf = batch_detections[top_index,4]*batch_detections[top_index,5]
        top_label = np.array(batch_detections[top_index,-1],np.int32)
        top_bboxes = np.array(batch_detections[top_index,:4])
        top_xmin, top_ymin, top_xmax, top_ymax = np.expand_dims(top_bboxes[:,0],-1),np.expand_dims(top_bboxes[:,1],-1),np.expand_dims(top_bboxes[:,2],-1),np.expand_dims(top_bboxes[:,3],-1)

        if self.letterbox_image:
            boxes = yolo_correct_boxes(top_ymin,top_xmin,top_ymax,top_xmax,np.array([self.model_image_size[0],self.model_image_size[1]]),image_shape)
        else:
            top_xmin = top_xmin / self.model_image_size[1] * image_shape[1]
            top_ymin = top_ymin / self.model_image_size[0] * image_shape[0]
            top_xmax = top_xmax / self.model_image_size[1] * image_shape[1]
            top_ymax = top_ymax / self.model_image_size[0] * image_shape[0]
            boxes = np.concatenate([top_ymin,top_xmin,top_ymax,top_xmax], axis=-1)
            
    font = ImageFont.truetype(font='model_data/simhei.ttf',size=np.floor(3e-2 * np.shape(image)[1] + 0.5).astype('int32'))

    thickness = max((np.shape(image)[0] + np.shape(image)[1]) // self.model_image_size[0], 1)
    content_json=[]
    for i, c in enumerate(top_label):
        predicted_class = self.class_names[c]
        score = top_conf[i]

        top, left, bottom, right = boxes[i]
        w=right-left
        h=bottom-top

        y = float(max(0, top))
        x = float(max(0, left))
        w = float(max(0, w))
        h = float(max(0, h))
        score = float(score)
        bbox=[x,y,w,h]

        # print(label, top, left, bottom, right)
        f = open(path_json, 'r', encoding='utf-8') 
        s = f.read()
        rest = json.loads(s)
        for i in rest['images']:
            if i['file_name']!=file_name:
                continue
            if i['file_name']==file_name:
                image_id=i['id']
                cat_id=rest['categories'][c]['id']
                content_dic = {
                    "image_id":image_id,
                    "category_id": cat_id,
                    "bbox": bbox,
                    "score": score
                }
                # print(content_dic)
                content_json.append(content_dic)   
                break
        f.close()  
    return content_json

接着修改predict.py

首先用for i in range(3)输入三张图片测试一下代码有没有问题。

from PIL import Image
import cv2 
from yolo import YOLO
import os
import json
yolo = YOLO()
content=[]
for i in range(3):
    file_name = input('Input image filename:')
    path = "./data/coco/test2017/"
    path_json = "./data/coco/annotations/instances_test2017.json"
    path_save = "./result.json"
    try:
       image = Image.open(path+file_name)
    except:
       print('Open Error! Try again!')
       continue
    else:
       content.extend(yolo.save_json(image,file_name,path_json))
       print(content)
with open(path_save, 'a') as f:
   json.dump(content, f)

没有问题后,用下面的代码将测试集里面的图片全部检测结果保存在result.json文件中。

content=[]
path = "./data/coco/test2017/"
path_json = "./data/coco/annotations/instances_test2017.json"
path_save = "./result.json"
open(path_save, 'w')
for file_name in os.listdir(path):
    image = Image.open(path+file_name)
    info = yolo.save_json(image,file_name,path_json)
    content.extend(info)
with open(path_save, 'a') as f:
    json.dump(content, f)

或者用下面的方法,先按照官方文档给出的测试集图片的信息,依次读取图片名,然后取对应的图片进行测试,这样就不用进行上面的判断了。

predict.py

from PIL import Image
import cv2 
from yolo import YOLO
import os
import json
yolo = YOLO()
path = "./data/coco/test2017/"
path_json = "./data/coco/annotations/instances_test2017.json"
path_save = "./result.json"
content=[]
f = open(path_json, 'r', encoding='utf-8') 
s = f.read()
rest = json.loads(s)
for i in rest['images']:
   file_name = i["file_name"]
   image_id = i["id"]
   image = Image.open(path+file_name)
   content.extend(yolo.save_json(image,file_name,image_id,rest['categories']))
f.close()  
with open(path_save, 'a') as f:
   json.dump(content, f)

yolo.py

def save_json(self,image,file_name,image_id,categories):
    image_shape = np.array(np.shape(image)[0:2])
        
    if self.letterbox_image:
        crop_img = np.array(letterbox_image(image, (self.model_image_size[1],self.model_image_size[0])))
    else:
        crop_img = image.convert('RGB')
        crop_img = crop_img.resize((self.model_image_size[1],self.model_image_size[0]), Image.BICUBIC)
    photo = np.array(crop_img,dtype = np.float32) / 255.0
    photo = np.transpose(photo, (2, 0, 1))
    
    images = [photo]
    
    with torch.no_grad():
        images = torch.from_numpy(np.asarray(images))
        if self.cuda:
            images = images.cuda()

        outputs = self.net(images)
        output_list = []
        for i in range(3):
            output_list.append(self.yolo_decodes[i](outputs[i]))

        
        output = torch.cat(output_list, 1)
        batch_detections = non_max_suppression(output, len(self.class_names),
                                                conf_thres=self.confidence,
                                                nms_thres=self.iou)
        
        try:
            batch_detections = batch_detections[0].cpu().numpy()
        except:
            return []
        
        top_index = batch_detections[:,4] * batch_detections[:,5] > self.confidence
        top_conf = batch_detections[top_index,4]*batch_detections[top_index,5]
        top_label = np.array(batch_detections[top_index,-1],np.int32)
        top_bboxes = np.array(batch_detections[top_index,:4])
        top_xmin, top_ymin, top_xmax, top_ymax = np.expand_dims(top_bboxes[:,0],-1),np.expand_dims(top_bboxes[:,1],-1),np.expand_dims(top_bboxes[:,2],-1),np.expand_dims(top_bboxes[:,3],-1)

        if self.letterbox_image:
            boxes = yolo_correct_boxes(top_ymin,top_xmin,top_ymax,top_xmax,np.array([self.model_image_size[0],self.model_image_size[1]]),image_shape)
        else:
            top_xmin = top_xmin / self.model_image_size[1] * image_shape[1]
            top_ymin = top_ymin / self.model_image_size[0] * image_shape[0]
            top_xmax = top_xmax / self.model_image_size[1] * image_shape[1]
            top_ymax = top_ymax / self.model_image_size[0] * image_shape[0]
            boxes = np.concatenate([top_ymin,top_xmin,top_ymax,top_xmax], axis=-1)
            
    font = ImageFont.truetype(font='model_data/simhei.ttf',size=np.floor(3e-2 * np.shape(image)[1] + 0.5).astype('int32'))

    thickness = max((np.shape(image)[0] + np.shape(image)[1]) // self.model_image_size[0], 1)
    content_json=[]
    for i, c in enumerate(top_label):
        predicted_class = self.class_names[c]
        score = top_conf[i]

        top, left, bottom, right = boxes[i]
        w=right-left
        h=bottom-top

        y = float(max(0, top))
        x = float(max(0, left))
        w = float(max(0, w))
        h = float(max(0, h))
        score = float(score)
        bbox=[x,y,w,h]

        # print(label, top, left, bottom, right)
        cat_id=categories[c]['id']
	    content_dic = {
	        "image_id":image_id,
	        "category_id": cat_id,
	        "bbox": bbox,
	        "score": score
	    }
    	content_json.append(content_dic)   
    return content_json
  • 2
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要将 YOLOv5 模型的预测结果保存json 文件,可以按照以下步骤进行操作: 1. 导入必要的库和函数 ```python import json import torch from pathlib import Path from models.experimental import attempt_load from utils.general import non_max_suppression, scale_coords from utils.datasets import LoadImages from utils.torch_utils import select_device ``` 2. 加载模型和设备 ```python weights = 'path/to/weights.pt' device = select_device('0') model = attempt_load(weights, map_location=device) img_size = model.img_size ``` 3. 加载图像并进行预测 ```python # 加载图像 dataset = LoadImages('path/to/images/', img_size=img_size) # 进行预测 results = [] for path, img, im0s, _ in dataset: img = torch.from_numpy(img).to(device) img = img.float() / 255.0 if img.ndimension() == 3: img = img.unsqueeze(0) pred = model(img, augment=False)[0] pred = non_max_suppression(pred, 0.4, 0.5) for i, det in enumerate(pred): if det is not None and len(det): det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0s.shape).round() for *xyxy, conf, cls in det: results.append({ 'image_id': Path(path).stem, 'category_id': int(cls), 'bbox': xyxy, 'score': float(conf) }) ``` 4. 将预测结果保存json 文件 ```python with open('path/to/results.json', 'w') as f: json.dump(results, f) ``` 这样,预测结果就会保存在指定的 json 文件中。注意,在保存 bbox 值时,我们使用了 scale_coords 函数将预测框的坐标从图像坐标系转换为原始图像坐标系。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天涯小才

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值