目標檢測中Bounding Box的詳細解讀與XML文件解析

 

目錄

1.bounding box的形式1---xml文件

2.bounding box的形式1---txt文件

3.實現對XML文件bounding box矩形框座標的獲取

4.兩Bounding_Box的IOU的計算



微信公衆號:小白CV
關注可瞭解更多CV,ML,DL領域基礎/最新知識;
如果你覺得小白CV對您有幫助,歡迎點贊/收藏/轉發


1.bounding box的形式1---xml文件

xml

xml文件中矩形框座標的獲取比較簡單。
1.xml文件可採用標註軟件labelImg進行生成
2.xml中記錄了被標註圖像信息和標註的信息

(1)labelImg的安裝(着重說Ubuntu下的一個安裝,別的版本可參照上面說到的labelImg博客)

 

現在就可以Terminal下打開看看了,點擊Open打開一張帶標記圖片,如圖

 

 

根據上面的英文,也都該知道怎麼用,其中有些省事省力的工作,就是:

 

  1. 先給待label圖片做好命名,放在同一文件夾;

  2. 然後設定OpenDir和待保存.xml文件夾下ChangeSaveDir;

  3. 如果是一個類別,可使用Use Default label,這樣提高標註效率。

 

 

從圖片中來,再到圖片中去,我們來找一下對應關係

 


2.bounding box的形式1---txt文件

內容按行存儲,依次是label,x_center,y_center,x_relative,y_relative

直觀換算後是這樣的矩形框


3.實現對XML文件bounding box矩形框座標的獲取

__author__ = "lingjun"
# E-mail: [email protected]
# 微信公衆號:小白CV

# -*- coding:utf8 -*-
import os
import xml.etree.ElementTree as ET
import cv2
import numpy as np

def main(input_path):
    Sum_Bndbox_Area = 0
    all_N=0
    xml_N=0
    bndbox_N = 0

    for f_1 in os.listdir(input_path):
        target_path=os.path.join(input_path, f_1)

        for f_2 in os.listdir(target_path):
            if f_2 == "label":
                doc_path = os.path.join(target_path, f_2)
                #print(doc_path)

                for (path, dirs, files) in os.walk(doc_path):
                    for filename in files:
                        all_N += 1

                        # if filename.split('_')[1]=="classes.txt":
                        #     print(filename)
                            # classestxt_file_path = os.path.join(doc_path, filename)
                            # os.remove(classestxt_file_path)

                        xmin_list = []
                        ymin_list = []
                        xmax_list = []
                        ymax_list = []

                        suffix_name = filename.split('.')[1]
                        # print(suffix_name)
                        if suffix_name == 'xml':
                            xml_file_path = os.path.join(doc_path, filename)
                            xml_N += 1
                            #print(xml_file_path)
                            # 處理對應的xml文件
                            tree = ET.parse(xml_file_path)
                            root = tree.getroot()

                            # for name in root.iter('object'):
                            #     label_name = name.find('name').text
                            for size in root.iter('size'):
                                width = int(size.find('width').text)
                                height = int(size.find('height').text)
                                #print("width:%.f  height:%.f" % (width, height))

                            for box in root.iter('bndbox'):
                                xmin = int(box.find('xmin').text)
                                xmin_list.append(xmin)
                                ymin = int(box.find('ymin').text)
                                ymin_list.append(ymin)
                                xmax = int(box.find('xmax').text)
                                xmax_list.append(xmax)
                                ymax = int(box.find('ymax').text)
                                ymax_list.append(ymax)
                                #print("xmin:%.f  ymin:%.f xmax:%.f  ymax:%.f"%(xmin,ymin,xmax,ymax))

                                #one_bndbox_area = (ymax-ymin)*(xmax-xmin)

                                bndbox_N += 1
                                #Sum_Bndbox_Area += one_bndbox_area
                            #creat_label_image(xmin_list, ymin_list, xmax_list, ymax_list, 512, 512, filename)
                        else:
                            xml_file_path = os.path.join(doc_path, filename)
                            #print(xml_file_path)

                            xmin_list = []
                            ymin_list = []
                            xmax_list = []
                            ymax_list = []
                            with open(xml_file_path, "r") as f:
                                for line in f.readlines():
                                    line = line.strip('\n')  # 去掉列表中每一個元素的換行符
                                    #print(line.split(" ")[0])

                                    x_center = int(float(line.split(" ")[1])*512)
                                    y_center = int(float(line.split(" ")[2])*512)
                                    x_shift = int(float(line.split(" ")[3])*256)
                                    y_shift = int(float(line.split(" ")[4])*256)

                                    xmin=x_center-x_shift
                                    xmax=x_center+x_shift
                                    ymin=y_center-y_shift
                                    ymax=y_center+y_shift
                                    xmin_list.append(xmin)
                                    ymin_list.append(ymin)
                                    xmax_list.append(xmax)
                                    ymax_list.append(ymax)
                            print("xmin_list[0]=",xmin_list[0])

                            creat_label_image( xmin_list, ymin_list, xmax_list, ymax_list,512, 512,filename)
                            #draw_rectangle_test(xmin_list, ymin_list, xmax_list, ymax_list, filename, xml_file_path)

    Average_Bndbox_Area = Sum_Bndbox_Area/bndbox_N

    print("all_N=",all_N)
    print("xml_N=",xml_N)
    print("bndbox_N=",bndbox_N)
    print("Average_Bndbox_Area=",Average_Bndbox_Area)

4.兩Bounding_Box的IOU的計算

 


import numpy as np
# ############################################################
# # IOU
# ############################################################
def two_Box_iou(list_a, list_b):
    """Compute the iou of two boxes.
    """
    # 獲取矩形框交集對應的頂點座標(intersection)
    xmin1, ymin1, xmax1, ymax1 = int(list_a[0]),int(list_a[1]), int(list_a[2]), int(list_a[3])
    xmin2, ymin2, xmax2, ymax2 = int(list_b[0]),int(list_b[1]), int(list_b[2]), int(list_b[3])

    xx1 = np.max([xmin1, xmin2])
    yy1 = np.max([ymin1, ymin2])
    xx2 = np.min([xmax1, xmax2])
    yy2 = np.min([ymax1, ymax2])

    # 計算兩個矩形框面積
    area1 = (xmax1 - xmin1 + 1) * (ymax1 - ymin1 + 1)
    area2 = (xmax2 - xmin2 + 1) * (ymax2 - ymin2 + 1)

    # 計算交集面積
    inter_area = (np.max([0, xx2 - xx1])) * (np.max([0, yy2 - yy1]))
    # 計算交併比
    iou = inter_area / (area1 + area2 - inter_area + 1e-6)
    return iou
#
list_a = [321,296,387,342]
list_b = [328,313,359,332]
rst_IOU = two_Box_iou(list_a, list_b)
print(rst_IOU)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章