• 使用python与opencv解析xml文件 裁剪目标图像 关键点与遇到的问题


    零、任务描述:

    xml文件中只有点坐标和其中可以结对的点坐标。要求将结对点坐标形成的区域裁剪出来并进行分类组成正样本,然后对所有点坐标两两结对,剔除可以两两结对的组合,然后进行裁图行程负样本。

    本文将对过程中的关键点进行梳理,并对常见错误的解决方案进行说明。

    xml格式如下:

    -<point>
    
    <name>0</name>
    
    <x1>404</x1>
    
    <y1>70</y1>
    
    </point>
    
    
    -<port>
    
    <name>port</name>
    
    <pose>Unspecified</pose>
    
    
    -<portbox>
    
    <x1>404</x1>
    
    <y1>70</y1>
    
    <x2>395</x2>
    
    <y2>185</y2>
    
    <portType>0</portType>
    
    <portAngle>90</portAngle>
    
    </portbox>
    
    </port>

    一、环境准备:

    我这里使用的是vscode开启anaconda虚拟环境,关键库如下:

    python、opencv-python、opencv-contrib-python、PIL、numpy等

    下面是我导入语的库:

    import sys,os
    import numpy as np
    from matplotlib import pyplot as plt
    import xml.etree.ElementTree as ET
    from math import *   #实现弧度变换
    import cv2
    import math
    import PIL
    from PIL import Image
    import os.path
    import glob

    二、读取xml文件:

    关键代码如下:

    for img_file in os.listdir(img_path):    #遍历图片文件夹
        if img_file[-4:] in ['.png', '.jpg']:    #判断文件是否为图片格式
            if os.path.exists(xml_name):  #判断与图片同名的标签是否存在,因为图片不一定每张都打标
                root = ET.parse(xml_name).getroot() #利用ET读取xml文件

    三:定义旋转矩阵:

    在裁剪的过程中,需要对图像旋转:

    def rotateImage(image, angle):
      image_center = tuple(np.array([(int(x0)+int(x1))/2,(int(y0)+int(y1))/2]))
      rot_mat = cv2.getRotationMatrix2D(image_center,angle,1.0)
      result = cv2.warpAffine(image, rot_mat, image.shape[1::-1],flags=cv2.INTER_LINEAR)
      return result

    四、正负样本输出:

    在裁剪的过程中判断图像是否正常                            

    def is_valid_image(path):
      '''
      检查文件是否损坏
      '''
      try:
        bValid = True
        fileObj = open(path, 'rb') # 以二进制形式打开
        buf = fileObj.read()
        if not buf.startswith(b'xffxd8'): # 是否以xffxd8开头
          bValid = False
        elif buf[6:10] in (b'JFIF', b'Exif'): # “JFIF”的ASCII码
          if not buf.rstrip(b' ').endswith(b'xffxd9'): # 是否以xffxd9结尾
            bValid = False
        else:
          try:
            Image.open(fileObj).verify()
          except Exception as e:
            bValid = False
            print(e)
      except Exception as e:
        return False
      return bValid

    常见错误1

    错误提示:TypeError: src is not a numpy array, neither a scalar

    原因分析:使用image.open打开图像后,进行resize操作之后,不能直接使用cv2.imwrite保存图像。

    解决方式:在cv2.imwrite之前,使用np.asarray进行数据转换。例如
    obj_img2 = np.asarray(obj_img1)

    常见错误2

    错误现象:裁剪后的图像颜色不一致,偏蓝。

    原因分析:因为OpenCV是以BGR模式读入图片,如果想要正常显示图片,则需要改成RGB格式。

    解决方式:格式转换

    obj_img2=cv2.cvtColor(obj_img2,cv2.COLOR_BGR2RGB)

    常见错误3

    错误报错:OSError: cannot identify image file

    原因分析:图像格式出错。

    解决方式:使用自定义的函数 is_valid_image()函数判断图像是否正常。

    参考链接:

    Python XML 解析

    PIL及matplotlib:OSError: cannot identify image file錯誤及解決方式

    利用Python获取VOC中的xml标注文件中的目标框

    Python:批量按xml标注将目标crop剪切图片并按类保存到相应文件夹

    python利用文件夹下xml格式标签文件批量裁剪出图片中的目标(文件夹、图片名称、目标框数量无限制,逐行注释)

    解析大量xml文件坐标位置,裁剪图片

    Python读取xml文件后,裁剪标注图片,并扩容数据

    解决使用anaconda VSCODE无法import cv2问题

    Python - 深度学习系列3-图像区域标注及抠图

  • 相关阅读:
    JavaScript 类私有方法的实现
    sublime小程序插件
    显示引擎innodb状态详解
    JAVA学习资料大全
    mongo-aggregate命令详解
    PHP error_reporting
    mongo基本命令
    php56升级后php7 mcrypt_encrypt 报错
    docker 基础命令
    敏捷建模:增强沟通和理解
  • 原文地址:https://www.cnblogs.com/vincent212212/p/14461972.html
Copyright © 2020-2023  润新知