0%

Python中的图片矫正

1. 基于OpenCV对图片进行矫正

1.1 Introduction

最近在处理一部分数据集, 感觉今后还有可能用到相关的技术, 因此,便将其记录下来以备翻阅.

The Image[1]

The Image

限于本人任务, 仅留取需要矫正的部分

1.2 Core technology

主要是应用到了OpenCV的两个透视变换相关函数(仿射变换无法解决透视问题)

1
2
T = cv2.getPerspectiveTransform(pt1, pt2)
new_image = cv2.warpPerspective(im,T,(new_W,new_Y))

本文所有的代码均是基于 Python 3.6.2 以及 OpenCV 3.2.0+ 的语法

1.2.1 获取透视变换矩阵

getPerspectiveTransform(pt1, pt2)函数要求传入的是变换前的点坐标(pt1), 以及对应的变换后的点坐标(pt2); 考虑到是透视变换因此需要提供四个点以求解透视变换矩阵.

pt1为例, 其为一个2维浮点数数组(本文所用的为numpy.array), 第一维度索引为点, 第二维度索引为对应点的具体坐标(x, y).

1
pt1 = np.float32([[x1,y1],[x2,y2],[x3,y3],[x4,y4]])

1.2.2 变换

warpPerspective函数要求传入的分别是原始图片,变换矩阵,新图片大小(W,H)

1.2.3 例子

图 1所示中的"星座KTV"对应的四点坐标(左上,右上,右下,左下)为

1
837,706,1815,1150,1849,1538,781,1189
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import cv2
import numpy as np

im = cv2.imread('image_303.jpg')
# areas in source img
pt1 = np.float32([[837,706],[1815,1150],[1849,1538],[781,1189]])
# fix the new image size as (x, y)
x = 1123
y = 486
# points in new image
pt2 = np.float32([[0,0],[x,0],[x,y],[0,y]])
# get the transform matrix
T = cv2.getPerspectiveTransform(pt1, pt2)
# transform
new_img = cv2.warpPerspective(im,T,(x,y))
# Show the new image.
cv2.imshow('newImage',new_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

1.3 拓展

若是考虑批量处理此类图片,可以对新图片的宽高做出自动设置, 原理就是基于所矫正区域在原始图片中的位置做出近似调整.

初始想法就是直接左右两点x求个差,取绝对值,上下y求个差取绝对值, 怕有所偏颇的话,分别求两次或以上(组合问题),取最大值

但是这种做法很容易出现问题,就是第一个点(一般在左上)和第二个点(一般在右上)的位置可能会发生变化, 如: 第一个点在左下, 第二个点在左上, 但是整体上看, 第二个点的x坐标还是比第一个点的x坐标值大, 如图 3所示. 更有甚者, 可能会出现宽度或高度为0的情况.

The Image

为了解决以上问题,可以采用欧氏距离进行估计.

1
2
3
4
5
def euclidean_distance(pt1, pt2):
return np.sqrt(np.sum((pt1 - pt2)**2))

x = int(max(euclidean_distance(pt1[0],pt1[1]), euclidean_distance(pt1[3],pt1[2])))
y = int(max(euclidean_distance(pt1[0],pt1[3]), euclidean_distance(pt1[2],pt1[1])))

  1. http://mclab.eic.hust.edu.cn/icdar2017chinese/ ↩︎

您的支持将鼓励我继续创作!