python
复制代码
import cv2
import numpy as np
def resize_image(image, scale_factor):
"""调整图像大小"""
return cv2.resize(
image, None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_AREA
)
def main():
# 读取图像
src = cv2.imread("images/c3.jpg")
if src is None:
print("无法读取图像,请检查路径是否正确!")
return
# 调整图像大小以便展示
scale_factor = 0.5 # 缩放比例
src_resized = resize_image(src, scale_factor)
cv2.imshow("src", src_resized)
# 转灰度图
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
gray_resized = resize_image(gray, scale_factor)
cv2.imshow("gray", gray_resized)
# 高斯模糊降噪
blur = cv2.GaussianBlur(gray, (5, 5), 1.0)
blur_resized = resize_image(blur, scale_factor)
cv2.imshow("gaussianBlur", blur_resized)
# Canny边缘检测
canny = cv2.Canny(blur, 20, 100)
canny_resized = resize_image(canny, scale_factor)
cv2.imshow("canny", canny_resized)
# 膨胀两次,让文字连到一块
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (4, 2))
expand = cv2.dilate(canny, kernel, iterations=2)
expand_resized = resize_image(expand, scale_factor)
cv2.imshow("dialate", expand_resized)
# 检索轮廓
contours, _ = cv2.findContours(expand, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# 对各个轮廓的旋转角度进行排序
vecAngles = []
for contour in contours:
rr = cv2.minAreaRect(contour)
vecAngles.append(rr[2]) # RotatedRect.angle
vecAngles.sort()
# 以中间值为基准,取相差20%以内的角度的平均值作为结果
midIndex = int(len(vecAngles) / 2) - 1
midAngle = vecAngles[midIndex]
maxAngleThreshold = midAngle + 15 if midAngle > 0 else midAngle - 15
minAngleThreshold = midAngle - 15 if midAngle > 0 else midAngle + 15
print("maxAngleThreshold:", maxAngleThreshold)
print("minAngleThreshold:", minAngleThreshold)
angleSum = 0
angleCounter = 0
for angle in vecAngles:
print(angle)
if minAngleThreshold < angle < maxAngleThreshold:
angleSum += angle
angleCounter += 1
averageAngle = angleSum / angleCounter if angleCounter > 0 else 0
print("averageAngle:", averageAngle)
print("midAngle:", midAngle)
# 旋转图像
(h, w) = src.shape[:2]
center = (w // 2, h // 2)
rotateM = cv2.getRotationMatrix2D(center, averageAngle, 1.0)
result = cv2.warpAffine(
src,
rotateM,
(w, h),
flags=cv2.INTER_LINEAR,
borderMode=cv2.BORDER_CONSTANT,
borderValue=(255, 255, 255),
)
result_resized = resize_image(result, scale_factor)
cv2.imshow("result", result_resized)
# 保存最终结果
output_path = "result.jpg"
cv2.imwrite(output_path, result)
print(f"最终结果已保存到:{output_path}")
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
main()