-45°到45°旋转图片矫正
原图
旋转后
调用一下correct_skew
方法即可
import cv2
import numpy as np
from scipy.ndimage import interpolation as inter
def determine_score(arr, angle):
data = inter.rotate(arr, angle, reshape=False, order=0)
histogram = np.sum(data, axis=1, dtype=float)
score = np.sum((histogram[1:] - histogram[:-1]) ** 2, dtype=float)
return histogram, score
def resizeOpenCvImage(image, width=None, height=None, inter=cv2.INTER_AREA):
"""
重置大小
:param width:
:param height:
:param inter:
:return:
"""
if width is None and height is None:
return image
if width is not None and height is not None:
return cv2.resize(image, (width, height), interpolation=inter)
(h, w) = image.shape[:2]
if width is None:
r = height / float(h)
dim = (int(w * r), height)
else:
r = width / float(w)
dim = (width, int(h * r))
resized = cv2.resize(image, dim, interpolation=inter)
return resized
def roughEstimation(smallImg):
"""
粗略估计
:param smallImg:
:param delta:
:param limit:
:return:
"""
gray = cv2.cvtColor(smallImg, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
scores = []
delta = 1
limit = 45
angles = np.arange(-limit, limit + delta, delta)
for angle in angles:
histogram, score = determine_score(thresh, angle)
scores.append(score)
return angles[scores.index(max(scores))]
def fineEstimation(smallImg, roughAngle):
"""
精确计算
:param smallImg:
:param delta:
:param limit:
:return:
"""
gray = cv2.cvtColor(smallImg, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
scores = []
delta = 0.1
angles = np.arange(roughAngle - 1, roughAngle + 1, delta)
for angle in angles:
histogram, score = determine_score(thresh, angle)
scores.append(score)
return angles[scores.index(max(scores))]
def correct_skew(sourceImage):
"""
角度矫正
:param sourceImage:
:param delta:
:param limit:
:return:
"""
smallImg = resizeOpenCvImage(sourceImage, 400)
roughAngle = roughEstimation(smallImg)
best_angle = fineEstimation(smallImg, roughAngle)
(h, w) = sourceImage.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, best_angle, 1.0)
corrected = cv2.warpAffine(sourceImage, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
print(best_angle)
return corrected
if __name__ == "__main__":
img = cv2.imread(r"D:\data\scan\027.jpg")
result = correct_skew(img)
cv2.imshow("result", result)
cv2.waitKey(0)