零、任務描述:
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
四、正負樣本輸出:
在裁剪的過程中判斷圖像是否正常
常見錯誤1
錯誤提示:TypeError: src is not a numpy array, neither a scalar
原因分析:使用image.open打開圖像后,進行resize操作之后,不能直接使用cv2.imwrite保存圖像。
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()函數判斷圖像是否正常。
參考鏈接:
PIL及matplotlib:OSError: cannot identify image file錯誤及解決方式
Python:批量按xml標注將目標crop剪切圖片並按類保存到相應文件夾
python利用文件夾下xml格式標簽文件批量裁剪出圖片中的目標(文件夾、圖片名稱、目標框數量無限制,逐行注釋)