目标检测:已经标注的图片缩放后,对标注数据的处理

在标注数据时,会出现数据已经标注完成,但是图片需要进行缩放,缩放后,原始标注数据不能使用,需要对图片进行重新标注,本文使用Python代码对缩放后的图片的标注数据进行等比例处理,使得标注数据满足缩放后的图片。

20230215更新:增加了思路介绍

本人思路介绍(以下为20230215新增内容):

原始图片大小是540x960,等比例压缩成416x416大小图片,原图的标签框左上角个点坐标是(592,378),宽是160,高是162,计算缩放后的图片标签框的坐标。

第一步:x1计算:原始x1值/原始图像的宽*压缩后图像的宽,592/960*416=256;原理,x1的值看成x1的点在宽上的占比,压缩后该占比不变(因为宽大于高,压缩后,宽度方向上无黑边)

第二步:y1计算:1)因图像的宽>高,所以等比例缩放后,图像的高会有黑边,两边的黑边高度是相等的(若不相等需要自行修改代码)

2)等比例压缩后,宽高的比例是不变的,通过宽高比计算出高度方向上图片压缩后的高度:416*540/960=234

3)计算上部分黑边的高度:(416-234)/2 = 91

4)因压缩后有效图片区域的高是234,而且y1值点的占比在高度方向上不会发生变化,因此压缩后y1值为:378/540*234+91 = 254(378/540是原始y1值再高度上的占比;加91是因为需要将上面的黑边高度加进去才是最终的y1值)

第三步:计算压缩后标签框的w和h

宽和高也是等比例压缩

w = 160/960*416=69

h = 162/540*234=70

最终,压缩后的标签框左上角和右下角坐标值为:

x1 = 256

y1 = 254

x2 = 256+69=325

y2 = 254+70=324

代码如下:

"""
使用说明:
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))

猜你喜欢

转载自blog.csdn.net/qq_26244715/article/details/128802055
今日推荐