miou 代码 VOC2012
生活随笔
收集整理的這篇文章主要介紹了
miou 代码 VOC2012
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
#!/usr/bin/python
# -*- coding: utf-8 -*-import numpy as np
import argparse
import json
from PIL import Image
from os.path import join
import cv2
from mmm.fullcrop import unpadding
from matplotlib import pyplot as plt
# 設標簽寬W,長H
def fast_hist(a, b, n): # a是轉化成一維數組的標簽,形狀(H×W,);b是轉化成一維數組的標簽,形狀(H×W,);n是類別數目,實數(在這里為19)'''核心代碼'''k = (a >= 0) & (a < n) # k是一個一維bool數組,形狀(H×W,);目的是找出標簽中需要計算的類別(去掉了背景) k=0或1hist = np.bincount(n * a[k].astype(int) + b[k], minlength=n ** 2)# if hist.shape!=(441,):# assert hist.shape==(441,)return np.bincount(n * a[k].astype(int) + b[k], minlength=n ** 2).reshape(n,n) # np.bincount計算了從0到n**2-1這n**2個數中每個數出現的次數,返回值形狀(n, n)def per_class_iu(hist): # 分別為每個類別(在這里是19類)計算mIoU,hist的形狀(n, n)'''核心代碼'''return np.diag(hist) / (hist.sum(1) + hist.sum(0) - np.diag(hist)) # 矩陣的對角線上的值組成的一維數組/矩陣的所有元素之和,返回值形狀(n,)# hist.sum(0)=按列相加 hist.sum(1)按行相加# def label_mapping(input, mapping):#主要是因為CityScapes標簽里面原類別太多,這樣做把其他類別轉換成算法需要的類別(共19類)和背景(標注為255)
# output = np.copy(input)#先復制一下輸入圖像
# for ind in range(len(mapping)):
# output[input == mapping[ind][0]] = mapping[ind][1]#進行類別映射,最終得到的標簽里面之后0-18這19個數加255(背景)
# return np.array(output, dtype=np.int64)#返回映射的標簽
'''compute_mIoU函數原始以CityScapes圖像分割驗證集為例來計算mIoU值的(可以根據自己數據集的不同更改類別數num_classes及類別名稱name_classes),本函數除了最主要的計算mIoU的代碼之外,還完成了一些其他操作,比如進行數據讀取,因為原文是做圖像分割遷移方面的工作,因此還進行了標簽映射的相關工作,在這里筆者都進行注釋。大家在使用的時候,可以忽略原作者的數據讀取過程,只需要注意計算mIoU的時候每張圖片分割結果與標簽要配對。主要留意mIoU指標的計算核心代碼即可。
'''def compute_mIoU(gt_dir, pred_dir, devkit_dir): # 計算mIoU的函數"""Compute IoU given the predicted colorized images and"""# with open('/home/ubuntu/DeepLab/datasets/VOCdevkit/VOC2012/ImageSets/Segmentation/info.json', 'r') as fp:# # 讀取info.json,里面記錄了類別數目,類別名稱。(我們數據集是VOC2011,相應地改了josn文件)# info = json.load(fp)# num_classes = np.int(info['classes']) # 讀取類別數目,這里是20類# print('Num classes', num_classes) # 打印一下類別數目# name_classes = np.array(info['label'], dtype=np.str) # 讀取類別名稱# # mapping = np.array(info['label2train'], dtype=np.int)#讀取標簽映射方式,詳見博客中附加的info.json文件# hist = np.zeros((num_classes, num_classes)) # hist初始化為全零,在這里的hist的形狀是[20, 20]#原代碼是有進行類別映射,所以通過json文件來存放類別數目、類別名稱、 標簽映射方式。而我們只需要讀取類別數目和類別名稱即可,可以按下面這段代碼將其寫死num_classes=21print('Num classes', num_classes)name_classes = ["background","aeroplane","bicycle","bird","boat","bottle","bus","car", "cat","chair","cow","diningtable","dog","horse","motobike","person","pottedplant","sheep","sofa","train","tvmonitor"]hist = np.zeros((num_classes, num_classes))image_path_list = join(devkit_dir, 'val.txt') # 在這里打開記錄分割圖片名稱的txtlabel_path_list = join(devkit_dir, 'val.txt') # ground truth和自己的分割結果txt一樣gt_imgs = open(label_path_list, 'r').read().splitlines() # 獲得驗證集標簽名稱列表gt_imgs = [join(gt_dir, x) for x in gt_imgs] # 獲得驗證集標簽路徑列表,方便直接讀取pred_imgs = open(image_path_list, 'r').read().splitlines() # 獲得驗證集圖像分割結果名稱列表pred_imgs = [join(pred_dir, x) for x in pred_imgs]# pred_imgs = [join(pred_dir, x.split('/')[-1]) for x in pred_imgs]#獲得驗證集圖像分割結果路徑列表,方便直接讀取for ind in range(len(gt_imgs)): # 讀取每一個(圖片-標簽)對pred = np.array(Image.open(pred_imgs[ind]+'.png')) # 讀取一張圖像分割結果,轉化成numpy數組label = np.array(Image.open(gt_imgs[ind]+'.png')) # 讀取一張對應的標簽,轉化成numpy數組# print pred.shape# print label.shape# label = label_mapping(label, mapping)#進行標簽映射(因為沒有用到全部類別,因此舍棄某些類別),可忽略if len(label.flatten()) != len(pred.flatten()):# 如果圖像分割結果與標簽的大小不一樣,這張圖片就不計算# print('Skipping: len(gt) = {:d}, len(pred) = {:d}, {:s}, {:s}'.format(len(label.flatten()),# len(pred.flatten()), gt_imgs[ind],# pred_imgs[ind]))lab_shape = label.shapepred = unpadding(lab_shape,pred)#todo : uppadding#pred = cv2.resize(pred, label.shape, interpolation=cv2.INTER_NEAREST)hist += fast_hist(label.flatten(), pred.flatten(), num_classes) # 對一張圖片計算19×19的hist矩陣,并累加# if ind > 0 and ind % 10 == 0: # 每計算10張就輸出一下目前已計算的圖片中所有類別平均的mIoU值# print('{:d} / {:d}: {:0.2f}'.format(ind, len(gt_imgs), 100 * np.mean(per_class_iu(hist))))# print(per_class_iu(hist))mIoUs = per_class_iu(hist) # 計算所有驗證集圖片的逐類別mIoU值for ind_class in range(num_classes): # 逐類別輸出一下mIoU值print('===>' + name_classes[ind_class] + ':\t' + str(round(mIoUs[ind_class] * 100, 2)))print('===> mIoU: ' + str(round(np.nanmean( mIoUs) * 100, 2))) # 在所有驗證集圖像上求所有類別平均的mIoU值,計算時忽略NaN值return mIoUs# root_dir = '/home/DATA/DATASET/VOC2012/VOC2012/'
# gt_dir = root_dir+'SegmentationClass/'
# list_dir = root_dir+'ImageSets/Segmentation/'
# #pred_dir = '/home/DATA/liutian/tmp/deep/Keras-segmentation-deeplab-v3.1-master/mmm/pred_no_white/'
# pred_dir = gt_dir
# iou = compute_mIoU(gt_dir,
# pred_dir,
# list_dir
# ) # 執行主函數 三個路徑分別為 ‘ground truth’,'自己的實驗分割結果',‘分割圖片名稱txt文件’
# print(iou)
這是直接改好的VOC2012,官方解壓目錄分級,只要你是官方文件夾直接解壓,那么都是下面這樣。代碼不用改,只需要指定自己預測圖片目錄,圖片保存格式要和官方一樣,具體保存上色代碼:https://blog.csdn.net/u013249853/article/details/94715443
PATH = '/home/DATA/DATASET/VOC2012/VOC2012' gt_dir = root_dir + 'SegmentationClass/'list_dir = root_dir + 'ImageSets/Segmentation/'pred_dir = savedir#這里是你自己圖片保存的目錄import miouresult = miou.compute_mIoU(gt_dir,savedir,list_dir)print(result)這個代碼得到的miou與deeplabv3+稍有出入,高了0.5%
可以接受
參考:https://blog.csdn.net/weixin_42188270/article/details/86632714#comments
https://blog.csdn.net/jiongnima/article/details/84750819
?
總結
以上是生活随笔為你收集整理的miou 代码 VOC2012的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python预测模型类型,多变量时间序列
- 下一篇: EXCEL工资条短信如何发送?