什么导致椭圆的外接矩形绘制不正确?
我在画椭圆的外部矩形时遇到了问题。
有一个椭圆的外部矩形画得很好,但另一个却不对。我不知道是什么导致了这种情况。 我用文本注释文件,里面有圆心、长半轴、短半轴和旋转角度,像这样。
我还考虑了弧度和角度的问题,加入弧度考虑,但似乎还是不行。
2
507.8829 75.5720 62.6301 44.5533 -32.4339
509.4677 113.7811 99.0642 58.6944 -76.6004
我用的这段代码
def get_ellipse_param(major_radius, minor_radius, angle):
a, b = major_radius, minor_radius
sin_theta = np.sin(-angle)
cos_theta = np.cos(-angle)
A = a**2 * sin_theta**2 + b**2 * cos_theta**2
B = 2 * (a**2 - b**2) * sin_theta * cos_theta
C = a**2 * cos_theta**2 + b**2 * sin_theta**2
F = -a**2 * b**2
return A, B, C, F
def calculate_rectangle(A, B, C, F):
y = np.sqrt(4*A*F / (B**2 - 4*A*C))
y1, y2 = -np.abs(y), np.abs(y)
x = np.sqrt(4*C*F / (B**2 - 4*C*A))
x1, x2 = -np.abs(x), np.abs(x)
return (x1, y1), (x2, y2)
def get_rectangle(center_x, center_y,major_radius, minor_radius, angle):
# new add
angle = angle * math.pi / 180
A, B, C, F = get_ellipse_param(major_radius, minor_radius, -angle)
p1, p2 = calculate_rectangle(A, B, C, F)
print(p1, p2)
xmin = min(center_x + p1[0],center_x + p2[0])
xmax = max(center_x + p1[0],center_x + p2[0])
ymin = min(center_y + p1[1],center_y + p2[1])
ymax = max(center_y + p1[1],center_y + p2[1])
print(xmin, ymin, xmax, ymax)
return xmin, ymin, xmax, ymax
xml2txt.py
import os
import math
import xml.etree.ElementTree as ET
from PIL import Image
import numpy as np
# 从指定目录下读取所有的txt问价
def get_all_txt_file(path):
txt_files_path = []
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith('.txt'):
txt_files_path.append(os.path.join(root, file))
return txt_files_path
def get_ellipse_param(major_radius, minor_radius, angle):
a, b = major_radius, minor_radius
sin_theta = np.sin(-angle)
cos_theta = np.cos(-angle)
A = a**2 * sin_theta**2 + b**2 * cos_theta**2
B = 2 * (a**2 - b**2) * sin_theta * cos_theta
C = a**2 * cos_theta**2 + b**2 * sin_theta**2
F = -a**2 * b**2
return A, B, C, F
def calculate_rectangle(A, B, C, F):
'''
椭圆上下外接点的纵坐标值
'''
y = np.sqrt(4*A*F / (B**2 - 4*A*C))
y1, y2 = -np.abs(y), np.abs(y)
'''
椭圆左右外接点的横坐标值
'''
x = np.sqrt(4*C*F / (B**2 - 4*C*A))
x1, x2 = -np.abs(x), np.abs(x)
return (x1, y1), (x2, y2)
def get_rectangle(center_x, center_y,major_radius, minor_radius, angle):
A, B, C, F = get_ellipse_param(major_radius, minor_radius, -angle)
p1, p2 = calculate_rectangle(A, B, C, F)
print(p1, p2)
xmin = min(center_x + p1[0],center_x + p2[0])
xmax = max(center_x + p1[0],center_x + p2[0])
ymin = min(center_y + p1[1],center_y + p2[1])
ymax = max(center_y + p1[1],center_y + p2[1])
print(xmin, ymin, xmax, ymax)
return xmin, ymin, xmax, ymax
def generate_xml(xml_file_name,annotation_data):
annotation = ET.Element("annotation")
folder = ET.SubElement(annotation, "folder")
folder.text = annotation_data["folder"]
filename = ET.SubElement(annotation, "filename")
filename.text = annotation_data["filename"]
path = ET.SubElement(annotation, "path")
path.text = annotation_data["path"]
source = ET.SubElement(annotation, "source")
database = ET.SubElement(source, "database")
database.text = annotation_data["database"]
size = ET.SubElement(annotation, "size")
width = ET.SubElement(size, "width")
width.text = str(annotation_data["width"])
height = ET.SubElement(size, "height")
height.text = str(annotation_data["height"])
depth = ET.SubElement(size, "depth")
depth.text = str(annotation_data["depth"])
segmented = ET.SubElement(annotation, "segmented")
segmented.text = str(annotation_data["segmented"])
for obj_data in annotation_data["objects"]:
object_element = ET.SubElement(annotation, "object")
name = ET.SubElement(object_element, "name")
name.text = obj_data["name"]
pose = ET.SubElement(object_element, "pose")
pose.text = obj_data["pose"]
truncated = ET.SubElement(object_element, "truncated")
truncated.text = str(obj_data["truncated"])
difficult = ET.SubElement(object_element, "difficult")
difficult.text = str(obj_data["difficult"])
bndbox = ET.SubElement(object_element, "bndbox")
xmin = ET.SubElement(bndbox, "xmin")
xmin.text = str(obj_data["xmin"])
ymin = ET.SubElement(bndbox, "ymin")
ymin.text = str(obj_data["ymin"])
xmax = ET.SubElement(bndbox, "xmax")
xmax.text = str(obj_data["xmax"])
ymax = ET.SubElement(bndbox, "ymax")
ymax.text = str(obj_data["ymax"])
xml_tree = ET.ElementTree(annotation)
xml_tree.write(xml_file_name, encoding="utf-8", xml_declaration=True)
if __name__ == '__main__':
input_path = "gt"
input_img_path = "images"
output_path = "true"
txt_files_path = get_all_txt_file(input_path)
# print(txt_files_path)
for file in txt_files_path:
print(file + ' is processing...')
txt_content = list(open(file, 'r').readlines())
ellipse_count = int(txt_content[0])
print(ellipse_count,file)
img_path = input_img_path + "/" +file.split("\\")[-1].replace(".txt", "").replace("gt_","")
img = Image.open(img_path)
data ={}
data["folder"] = "JPEGImages"
data["filename"] = file.split("\\")[-1].split(".")[0]+".jpg"
data["path"] = img_path
data["database"] = "Unknown"
data["width"] = img.width
data["height"] = img.height
data["depth"] = len(img.getbands())
data["segmented"] = 0
data["objects"] = []
for i in range(1, ellipse_count + 1):
ellipse = txt_content[i].split()
x = float(ellipse[0])
y = float(ellipse[1])
a = float(ellipse[2])
b = float(ellipse[3])
angle = float(ellipse[4])
# tangents = get_tangents(y, x, a, b,angle)
if a<b:
temp = a
a = b
b = temp
# tangents = get_rectangle(x,y,a,b,angle)
tangents = get_rectangle(y,x,a,b,angle)
obj_data = {
"name": "ellipse",
"pose": "Unspecified",
"truncated": 0,
"difficult": 0,
"xmin": tangents[0],
"ymin": tangents[1],
"xmax": tangents[2],
"ymax": tangents[3]
}
data["objects"].append(obj_data)
print(tangents)
data["output_file"] = "annotation.xml"
img_path = output_path + "/" + file.split("\\")[-1].replace(".png.txt", ".xml").replace(".jpg.txt", ".xml")
img_path = img_path.replace("gt_", "")
generate_xml(img_path,data)
display.py
import os
import xml.etree.ElementTree
import cv2 as cv
xmlPath = "true/"
xmlFiles = [name for name in os.listdir(xmlPath) if name.endswith('.xml')]
for i in range(len(xmlFiles)):
file = xml.etree.ElementTree.parse(xmlPath + xmlFiles[i])
cnt = len(file.findall('object'))
print(cnt)
# imgPath = xmlFiles[i].replace("xml", "jpg") # prasad
imgPath = xmlFiles[i].replace("xml", "png")
img = cv.imread("images/" + imgPath)
for obj in file.findall('object'):
xMin = float(obj.find('bndbox').find('xmin').text)
yMin = float(obj.find('bndbox').find('ymin').text)
xMax = float(obj.find('bndbox').find('xmax').text)
yMax = float(obj.find('bndbox').find('ymax').text)
print(xMin, yMax, xMax, yMin)
# 通过四个参数画正方形
print(xmlFiles[i])
xMax = int(xMax)
yMin = int(yMin)
xMin = int(xMin)
yMax = int(yMax)
# 矩形左上角和右上角的坐标,绘制一个绿色矩形
ptLeftTop = (xMin, yMax)
ptRightBottom = (xMax, yMin)
point_color = (0, 255, 0)
thickness = 1
lineType = 4
cv.rectangle(img, ptLeftTop, ptRightBottom, point_color, thickness, lineType)
cv.imwrite("re/" + imgPath, img)
cv.imshow("img",img)
cv.waitKey(0)
break
0 个回答
暂无回答