使用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'\xff\xd8'): # 是否以\xff\xd8開頭
      bValid = False
    elif buf[6:10] in (b'JFIF', b'Exif'): # “JFIF”的ASCII碼
      if not buf.rstrip(b'\0\r\n').endswith(b'\xff\xd9'): # 是否以\xff\xd9結尾
        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-圖像區域標注及摳圖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM