旋轉框四點座標轉成roLabelImg的角度格式

2021-10-10 15:43:36 字數 4550 閱讀 3917

甲方發過來的標籤是四點座標格式的,我們需要用rolabelimg檢查一遍和標籤,這就需要轉成角度格式,rolabelimg跟別的表示方法不一樣,是逆時針為正的,範圍是0-π。指令碼裡用到了opencv的最小外接矩形函式cv2.minarearect,以及根據長短邊來判斷角度在哪個象限。具體**和詳細注釋如下:

# *_* coding : utf-8 *_*

# 開發人員: csu·pan-_-||

# 檔名稱: four_to_theta.py

# 開發工具: pycharm

# 功能描述: 將四點座標x1,y1,x2,y2,x3,y3,x4,y4轉成旋轉框 cx,cy,w,h,angle

# 以便rolabelimg能夠識別

import os

import xml.etree.elementtree as et

import math

import numpy as np

import cv2

defedit_xml

(xml_file)

:"""

修改xml檔案

:param xml_file:xml檔案的路徑

:return:

"""tree = et.parse(xml_file)

objs = tree.findall(

'object'

)# 獲取節點

for ix, obj in

enumerate

(objs)

: cx = et.element(

"cx"

)# 建立節點

cy = et.element(

"cy"

) w = et.element(

"w")

h = et.element(

"h")

angle = et.element(

"angle"

)type

= et.element(

"type"

)print

(xml_file)

type

.text =

'robndbox'

type

)# 新增節點

obj_bnd = obj.find(

'bndbox'

) obj_bnd.tag =

'robndbox'

# 修改節點名

obj_x0 = obj_bnd.find(

'x0'

) obj_y0 = obj_bnd.find(

'y0'

) obj_x1 = obj_bnd.find(

'x1'

) obj_y1 = obj_bnd.find(

'y1'

) obj_x2 = obj_bnd.find(

'x2'

) obj_y2 = obj_bnd.find(

'y2'

) obj_x3 = obj_bnd.find(

'x3'

) obj_y3 = obj_bnd.find(

'y3'

) x0 =

float

(obj_x0.text)

# 獲取節點的值

y0 =

float

(obj_y0.text)

x1 =

float

(obj_x1.text)

y1 =

float

(obj_y1.text)

x2 =

float

(obj_x2.text)

y2 =

float

(obj_y2.text)

x3 =

float

(obj_x3.text)

y3 =

float

(obj_y3.text)

# 用opencv的最小矩形轉換成-90到0的角度

boxes = backward_convert(

[x0,y0,x1,y1,x2,y2,x3,y3]

)# 根據長短邊轉成 0 到 180

new_boxes = coordinate_present_convert(boxes)

# 轉成弧度:

new_boxes[0]

[-1]

= new_boxes[0]

[-1]

* math.pi/

180 new_boxes = new_boxes.astype(np.

str)

cx.text,cy.text,w.text,h.text,angle.text = new_boxes[0]

obj_bnd.remove(obj_x0)

# 刪除節點

obj_bnd.remove(obj_y0)

obj_bnd.remove(obj_x1)

obj_bnd.remove(obj_y1)

obj_bnd.remove(obj_x2)

obj_bnd.remove(obj_y2)

obj_bnd.remove(obj_x3)

obj_bnd.remove(obj_y3)

# 新增節點

tree.write(xml_file, method=

'xml'

, encoding=

'utf-8'

)# 更新xml檔案

defcoordinate_present_convert

(coords, shift=

true):

""" :param coords: shape [-1, 5]

:param shift: [-90, 90) --> [-180, 0)

:return: shape [-1, 5]

"""# angle range from [-90, 0) to [0,180)

w, h = coords[:,

2], coords[:,

3]remain_mask = np.greater(w, h)

convert_mask = np.logical_not(remain_mask)

.astype(np.int32)

remain_mask = remain_mask.astype(np.int32)

remain_coords = coords * np.reshape(remain_mask,[-

1,1]

) coords[:,

[2,3

]]= coords[:,

[3,2

]]coords[:,

4]+=90

convert_coords = coords * np.reshape(convert_mask,[-

1,1]

) coords_new = remain_coords + convert_coords

if shift:

if coords_new[:,

4]>=0:

coords_new[:,

4]= coords_new[:,

4]-180

return np.array(coords_new, dtype=np.float32)

defbackward_convert

(coordinate)

:"""

:param coordinate: format [x1, y1, x2, y2, x3, y3, x4, y4]

:return: format [x_c, y_c, w, h, theta, (label)]

"""boxes =

box = np.int0(coordinate)

box = box.reshape([4

,2])

rect1 = cv2.minarearect(box)

x, y, w, h, theta = rect1[0]

[0], rect1[0]

[1], rect1[1]

[0], rect1[1]

[1], rect1[2]

if theta ==0:

w, h = h, w

theta -=

90[x, y, w, h, theta]

)return np.array(boxes, dtype=np.float32)

if __name__ ==

'__main__'

:dir

=r"e:\projects\xml_four"

filelist = os.listdir(

dir)

forfile

in filelist:

edit_xml(os.path.join(

dir,

file

))

參考:coordinate_convert.py

opengl學習 四 座標系統

總述 opengl希望在每次頂點著色器執行後,我們可見的所有頂點都為標準化裝置座標 normalized device coordinate,ndc 也就是說,每個頂點的x,y,z座標都應該在 1.0到1.0之間,超出這個座標範圍的頂點都將不可見。我們通常會自己設定乙個座標的範圍,之後再在頂點著色器...

已知三點座標,求外接圓圓心座標與半徑。

已知三點座標,求外接圓圓心座標與半徑。a y2 y1 y3 y3 y1 y1 x3 x3 x1 x1 y3 y1 y2 y2 y1 y1 x2 x2 x1 x1 2.0 x3 x1 y2 y1 x2 x1 y3 y1 b x2 x1 x3 x3 x1 x1 y3 y3 y1 y1 x3 x1 x2 ...

cocos2d x 3 3rc2 座標轉換和錨點

1 opengl座標系 該座標系原點在螢幕左下角,x軸向右,y軸向上。這也就是cocos2dx中用到的座標系。2 螢幕座標系 該座標系的原點在螢幕左上角,x軸向右,y軸向下,其實和opengl座標系的差別也就是y軸的方向拉。假設遊戲場景的解析度為 500,500 其中乙個點的座標為 200,200 ...