Ao rotular dados, parecerá que os dados foram rotulados, mas a imagem precisa ser dimensionada. Após o zoom, os dados originais do rótulo não podem ser usados e a imagem precisa ser rotulada novamente. Este artigo usa código Python para processar o rótulo dados da imagem em escala em proporções iguais. , de modo que os dados do rótulo satisfaçam a imagem em escala.
20230215 Atualização: introdução de ideias adicionadas
Meus pensamentos são apresentados (o seguinte é o novo conteúdo de 20230215):
O tamanho da imagem original é 540 x 960 e é compactado em uma imagem de tamanho 416 x 416 em proporções iguais. As coordenadas do canto superior esquerdo da caixa de rótulos da imagem original são (592.378), a largura é 160 e a altura é 162. Calcule as coordenadas da caixa de rótulo da imagem ampliada.
Passo 1: Cálculo de x1: valor x1 original/largura da imagem original*largura da imagem comprimida, 592/960*416=256; em princípio, o valor de x1 é considerado como a razão entre o ponto de x1 e a largura, após a compactação a proporção permanece inalterada (porque a largura é maior que a altura, após a compactação não há borda preta na direção da largura)
Etapa 2: Cálculo de y1: 1) Como a largura da imagem é maior que a altura, haverá bordas pretas na altura da imagem após o dimensionamento proporcional e as alturas das bordas pretas em ambos os lados serão iguais (se não é igual, você mesmo precisa modificar o código)
2) Após a compactação proporcional, a proporção entre largura e altura permanece inalterada e a altura da imagem compactada na direção da altura é calculada por meio da proporção: 416*540/960=234
3) Calcule a altura da parte superior da borda preta: (416-234)/2 = 91
4) Visto que a altura da área efetiva da imagem após a compressão é 234, e a proporção dos pontos de valor y1 não mudará na direção da altura, o valor de y1 após a compressão é: 378/540*234+91 = 254 (378/ 540 é a proporção do valor y1 original para a altura; 91 é adicionado porque a altura da borda preta acima precisa ser adicionada ao valor y1 final)
Passo 3: Calcule w e h da caixa de rótulo compactada
Largura e altura também são comprimidas proporcionalmente
w = 160/960*416=69
h = 162/540*234=70
Por fim, os valores das coordenadas do canto superior esquerdo e do canto inferior direito da moldura da etiqueta compactada são:
x1 = 256
y1 = 254
x2 = 256 + 69 = 325
a2 = 254 + 70 = 324
código mostra como abaixo:
"""
使用说明:
1、目的:图像进行等比例压缩后,之前图像中标注的数据也需要进行等比例处理才能符合压缩后的图像
2、输入参数说明
-w:压缩后图片宽
-h:压缩后图片高
-img_w:原始图片宽
-img_h:原始图片高
-label_w:标签框宽,初始值为0
-label_h:标签框高,初始值为0
-xy:标签框左上角点和右下角点坐标值(x1,y1,x2,y2),或者传入左上角坐标点值(x1,y1)和标签框的宽和高
3、返回的是标签框的左上角和右下角坐标点的值
注意:计算时注意黑边区域和压缩后有效图片区域
"""
def label_handle(xy,w,h,img_w,img_h,label_w=0,label_h=0):
# 异常情况判断:
if len(xy) ==2 and label_w == 0 and label_h == 0:
raise Exception("输入不正确,若只输入左上角坐标点请输入标签的label_w和label_h,否则输入左上角和右下角坐标点")
if len(xy) == 0 :
raise Exception("输入不正确,请输入坐标点的值")
#如果输入一个点的坐标,需要宽和高
if len(xy) ==2 and label_w > 0 and label_h > 0:
x1,y1 = xy
_w= label_w
_h = label_h
#输入2个坐标点的值不会获取宽和高
if len(xy)==4:
x1,y1,x2,y2 = xy
_w = x2-x1
_h = y2-y1
#计算x1,y1,w,h在原始图像上宽高的占比,等比例压缩后,占比不会发生变化
x1_scale = x1 / img_w
y1_scale = y1 / img_h
_w_scale = _w / img_w
_h_scale = _h / img_h
#计算原始图像的宽高比,压缩后宽高比不会发生变化(指的是实际有图的地方)
#需要判断原图是宽>高还是高>宽,涉及到黑边,等比例压缩过程中,较小的边长压缩后会出现黑边
if img_w>img_h:
#因图像的宽>高,所以等比例缩放后,图像的高会有黑边,两边的黑边高度应该相等的
#压缩后的实际有效高度为
h_positive = h * img_h/img_w
# 图片上下黑边分别为
black_area_half = (h-h_positive)/2
# 左上角坐标
x1_new = x1_scale * w
#左上角y轴点坐标是:黑边高度+y值占比*有效的高度
y1_new = black_area_half+y1_scale*h_positive
# 右下角坐标:宽高也是等比例压缩,压缩后比例不变
x2_new = x1_new+_w_scale*w
y2_new = y1_new+_h_scale*h_positive
return int(x1_new),int(y1_new),int(x2_new),int(y2_new)
elif img_w<img_h:
#因图像的宽<高,所以等比例缩放后,图像的宽会有黑边,两边的黑边宽度应该相等的
#压缩后的实际有效宽度为
w_positive = w * img_w/img_h
# 图片上下黑边分别为
black_area_half = (w-w_positive)/2
# 左上角坐标
x1_new = black_area_half+x1_scale*w_positive
#左上角y轴点坐标是:黑边高度+y值占比*有效的高度
y1_new = y1_scale*h
# 右下角坐标:宽高也是等比例压缩,压缩后比例不变
x2_new = x1_new+_w_scale*w_positive
y2_new = y1_new+_h_scale*h
return int(x1_new),int(y1_new),int(x2_new),int(y2_new)
elif img_w==img_h:
#宽高相等的话直接计算就可以,不会出现黑边,不用特殊处理
x1_new = x1_scale * w
y1_new = y1_scale * h
x2_new = x1_new + _w_scale * w
y2_new = y1_new + _h_scale * h
return int(x1_new), int(y1_new), int(x2_new), int(y2_new)
if __name__ == '__main__':
print(label_handle((592,378),w=416,h=416,img_h=960,img_w=960,label_h=162,label_w=160))