甲方發過來的標籤是四點座標格式的,我們需要用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 ...