Python-OpenCV之图像与位置标注的仿射变换

不管是在目标检测还是在OCR文本检测的时候,都会有数据预处理这一步。那我们在对图像进行缩放、旋转的过程中,标注的位置信息肯定也是会变化的。

1  缩放

图像利用OpenCV进行缩放,我们可以使用resize方法进行。但是标注信息呢?以按照原点进行缩放为例,原图大小的宽度和高度分别为w和h,我们可以先求出在高度和宽度上缩放的比例。这样在resize的时候可以指定fx和fy的缩放比例了。

然后针对标注点做同样的缩放比例即可,代码如下所示。

im = cv2.imread(input_images_path + image)
img = im.copy()
h, w = img.shape[:2]
# 放大或缩小比例系数
scale_width = float(scaling_width) / float(w)
scale_height = float(scaling_height) / float(h)
scaling_image = cv2.resize(img, (0, 0), fx=scale_width, fy=scale_height)
line_list = []
with open(input_gt_path + filename + '.txt', 'r') as f:
    reader = csv.reader(f)
    for line in reader:
        line_dict = {'x1': 0, 'y1': 0, 'x2': 0, 'y2': 0, 'x3': 0, 'y3': 0, 'x4': 0, 'y4': 0, 'label': ''}
        label = line[-1]
        x1, y1, x2, y2, x3, y3, x4, y4 = list(map(int, line[:8]))
        line_dict['x1'] = int(x1 * scale_width)
        line_dict['x2'] = int(x2 * scale_width)
        line_dict['x3'] = int(x3 * scale_width)
        line_dict['x4'] = int(x4 * scale_width)
        line_dict['y1'] = int(y1 * scale_height)
        line_dict['y2'] = int(y2 * scale_height)
        line_dict['y3'] = int(y3 * scale_height)
        line_dict['y4'] = int(y4 * scale_height)
        line_dict['label'] = label
        line_list.append(line_dict)
    f.close()

 

2  旋转

旋转主要是根据仿射矩阵进行仿射变换。我们可以首先根据需要的旋转角度计算出仿射矩阵。传递一个旋转角度值,进行计算。对图像旋转以及获得仿射矩阵的示例代码如下。

def rotate_image(image, degree):
    # 逆时针旋转图像degree角度(原尺寸)
    # 旋转中心为图像中心
    h, w = image.shape[:2]
    # 计算二维旋转的仿射变换矩阵
    RotateMatrix = cv2.getRotationMatrix2D((w / 2.0, h / 2.0), degree, 1)
    # print(RotateMatrix)
    # 仿射变换,背景色填充为白色
    rotate = cv2.warpAffine(image, RotateMatrix, (w, h), borderValue=(255, 255, 255))
    return rotate, RotateMatrix

返回值中的rotate是旋转后的CV图像,RotateMatrix是仿射变换矩阵(两行三列)。我们对需要旋转的点构造一个三行一列的矩阵,这样通过矩阵的乘法获得的另一个矩阵就是我们需要的旋转变换后的点的坐标。获得旋转后的点坐标的示例代码如下所示。

for line_dict in line_list:
    dict_new = {'x1': 0, 'y1': 0, 'x2': 0, 'y2': 0, 'x3': 0, 'y3': 0, 'x4': 0, 'y4': 0}
    member = np.array([[float(line_dict['x1'])], [float(line_dict['y1'])], [1]], dtype=np.float32)
    result = np.dot(RotateMatrix, member).astype(np.int)
    dict_new['x1'] = result[0][0]
    dict_new['y1'] = result[1][0]
    ...

变换之后的标注信息就可以直接拿来用了,很方便~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值