图像校正绘图失败,ValueError形状不匹配问题咨询
问题分析与解决建议
错误根源
- 众数提取的形状问题:
scipy.stats.mode返回的众数是数组形式(可能为二维数组),而非标量,导致计算出的skew_angle是数组类型。传递给skimage.transform.rotate时,因函数期望标量角度参数,引发形状不匹配错误。 - 子图绘制逻辑错误:将校正后的图像绘制在同一个子图
ax[0]上,不仅会覆盖原图,也不符合分图展示的需求。
修复步骤
1. 修正众数提取逻辑
在skew_angle_hough_transform函数中,将众数从数组中提取为标量值:
# 兼容新旧版本scipy的写法,直接取出标量众数 most_common_angle = mode(np.around(angles, decimals=2))[0][0]
如果使用新版本scipy(≥1.7.0),也可以用更清晰的写法:
most_common_angle = mode(np.around(angles, decimals=2), keepdims=False).mode
2. 修正子图绘制逻辑
将原图和校正后的图像分别绘制在两个子图中,避免覆盖:
ax[0].imshow(image, cmap="gray") ax[0].set_title('Original Image') ax[0].set_axis_off() # 先计算校正后的图像,再绘制到第二个子图 corrected_image = rotate(image, skew_angle_hough_transform(image), cval=1) ax[1].imshow(corrected_image, cmap="gray") ax[1].set_title('Skew-Corrected Image') ax[1].set_axis_off()
完整修复代码
import numpy as np from skimage.transform import hough_line, hough_line_peaks from skimage.transform import rotate from skimage.feature import canny from skimage.io import imread from skimage.color import rgb2gray import matplotlib.pyplot as plt from scipy.stats import mode image = rgb2gray(imread("/opt/oracle/app/Raunak/skew11.jpeg")) edges = canny(image) tested_angles = np.deg2rad(np.arange(0.1, 180.0)) h, theta, d = hough_line(edges, theta=tested_angles) fig, axes = plt.subplots(1, 2, figsize=(15, 16)) ax = axes.ravel() ax[0].imshow(image, cmap="gray") ax[0].set_title('Input image') ax[0].set_axis_off() ax[1].imshow(edges, cmap="gray") origin = np.array((0, image.shape[1])) for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0, y1 = (dist - origin * np.cos(angle)) / np.sin(angle) ax[1].plot(origin, np.array([y0, y1]).flatten(), '-r') ax[1].set_xlim(origin) ax[1].set_ylim((edges.shape[0], 0)) ax[1].set_axis_off() ax[1].set_title('Detected lines') def skew_angle_hough_transform(image): edges = canny(image) tested_angles = np.deg2rad(np.arange(0.1, 180.0)) h, theta, d = hough_line(edges, theta=tested_angles) accum, angles, dists = hough_line_peaks(h, theta, d) # 提取标量众数 most_common_angle = mode(np.around(angles, decimals=2))[0][0] skew_angle = np.rad2deg(most_common_angle - np.pi/2) return skew_angle fig, ax = plt.subplots(ncols=2, figsize=(20,20)) # 分图展示原图与校正后的图像 ax[0].imshow(image, cmap="gray") ax[0].set_title('Original Image') ax[0].set_axis_off() corrected_image = rotate(image, skew_angle_hough_transform(image), cval=1) ax[1].imshow(corrected_image, cmap="gray") ax[1].set_title('Skew-Corrected Image') ax[1].set_axis_off() plt.show()
额外优化建议
- 限制
tested_angles的范围(比如np.arange(-45, 45)),减少计算量,因为图像倾斜通常不会超过±45度。 - 添加空值判断:如果
hough_line_peaks未检测到任何线条,返回0度避免报错。
内容的提问来源于stack exchange,提问作者Raunak Raj
相关产品推荐
相关产品推荐

