目标检测xml文件提取

提取xml文件的目标名,xmin,ymin,xmax,ymax,在图上把框框出来并保存。

使用try except避免xml文件中可能存在的标注错误。

xml文件提取:
使用xml.dom.minidom.parse(xml_path)获得DOMTree。
使用DOMTree.documentElement获得DOMTree元素集合。
使用.getElementsByTagName(tagname)获得标签名是tagname的元素的列表。
通过列表索引获得列表某个元素。
通过.childNodes[0]或.firstchild获得第一个子节点。
通过.childNodes[0].nodeValue或firstchild.data获得第一个子节点的值。

画框:
cv2.rectangle(img, (xmin,ymin), (xmax,ymax),颜色,厚度)

框上写字:
cv2.putText(img, 文字内容,坐标,字体,大小,颜色,厚度)

保存图像:
cv2.imwrite(路径,图像)

'''

xml文件示例:
<annotations>
    <filename>test_00000335.jpg</filename>
    <size>
        <width>305</width>
        <height>458</height>
        <depth>3</depth>
    </size>
    <object>
        <name>face_mask</name>
        <bndbox>
            <xmin>138</xmin>
            <ymin>126</ymin>
            <xmax>207</xmax>
            <ymax>203</ymax>
        </bndbox>
    </object>
    <object>
        <name>face</name>
        <bndbox>
            <xmin>123</xmin>
            <ymin>316</ymin>
            <xmax>187</xmax>
            <ymax>379</ymax>
        </bndbox>
    </object>
</annotation>
'''


import cv2
from xml.dom.minidom import parse
import xml.dom.minidom
import os


def img_draw_bndbox(img_path, xml_path, out_path, img_draw_name):
    '''

    :param img_path: str, 原图像的地址
    :param xml_path: str, xml文件的地址
    :param out_path: 保存图像的地址
    :param img_draw_name:保存图像的名称
    :return: None
    '''
    image = cv2.imread(img_path)
    # 使用minidom解析器打开 XML 文档
    DOMTree = xml.dom.minidom.parse(xml_path)
    collection = DOMTree.documentElement
    # print(collection)

    '''
    获得左上角坐标(xmin, ymin),右下角坐标(xmax, ymax)
    x.firstchild.data:获取元素第一个子节点的数据;
    x.childNodes[0]::获取元素第一个子节点;
    x.childNodes[0].nodeValue.:也是获取元素第一个子节点值的意思
    '''
    # 示例:提取图片名称、宽、高
    filename = collection.getElementsByTagName('filename')[0].firstChild.data
    width = collection.getElementsByTagName('width')[0].firstChild.data
    height = collection.getElementsByTagName('height')[0].childNodes[0].nodeValue
    # print(filename)
    # print(width)
    # print(height)

    object_elements =collection.getElementsByTagName('object')
    for object_element in object_elements:
        # 获得类别名称
        object_name = object_element.getElementsByTagName('name')[0].firstChild.data
        # print('object name: ', object_name)
        # 获得第一个 bndbox,一个object下只有一个bndbox,第一个就是,他的下标是0
        bndbox_element = object_element.getElementsByTagName('bndbox')[0]
        xmin = bndbox_element.getElementsByTagName('xmin')[0].firstChild.data
        ymin = bndbox_element.getElementsByTagName('ymin')[0].firstChild.data
        xmax = bndbox_element.getElementsByTagName('xmax')[0].firstChild.data
        ymax = bndbox_element.getElementsByTagName('ymax')[0].firstChild.data
        # 用红框把图像中的人脸框出,红色 (0, 0, 255)。
        '''
        import cv2
        cv2.rectangle(img, (x1, y1), (x2, y2), (255,0,0), 2)
        
(xmin,ymin) -----------
           |          |
           |          |
           |          |
           ------------(xmax,ymax)
        '''
        try:
            xmin, ymin, xmax, ymax = int(xmin), int(ymin), int(xmax), int(ymax)
            image = cv2.rectangle(image, (xmin, ymin), (xmax, ymax), (255, 0, 0), 2)
            font = cv2.FONT_HERSHEY_SIMPLEX  # 定义字体
            # cv2.putText()参数依次是:图像,文字内容,坐标(左上角坐标) ,字体,大小,颜色,字体厚度
            # 用黄色字体在图像中写出类别名称,黄色 (0, 255, 255)
            image = cv2.putText(image, object_name, (xmin, ymin), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2)
        except:
            print("data invalid!")
    cv2.imwrite(os.path.join(out_path, img_draw_name), image)
    return



if __name__ ==  '__main__':
    img_path = './test_00000335.jpg'
    xml_path = './test_00000335.xml'
    out_path = './'
    img_draw_name = 'test_00000335_draw.jpg'
    img_draw_bndbox(img_path, xml_path, out_path, img_draw_name)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值