校正的过程可以分为以下几步:
1、转灰度图。
2、降噪。
3、Canny边缘检测。
4、膨胀。
5、轮廓检索。
6、从各个轮廓中选取合适的旋转角度并校正图像。
import cv2
import numpy as npdef 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("无法读取图像,请检查路径是否正确!")returnscale_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 = 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]) vecAngles.sort()midIndex = int(len(vecAngles) / 2) - 1midAngle = vecAngles[midIndex]maxAngleThreshold = midAngle + 15 if midAngle > 0 else midAngle - 15minAngleThreshold = midAngle - 15 if midAngle > 0 else midAngle + 15print("maxAngleThreshold:", maxAngleThreshold)print("minAngleThreshold:", minAngleThreshold)angleSum = 0angleCounter = 0for angle in vecAngles:print(angle)if minAngleThreshold < angle < maxAngleThreshold:angleSum += angleangleCounter += 1averageAngle = angleSum / angleCounter if angleCounter > 0 else 0print("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()