自动化识别波箱俯视图像中地板与墙壁分隔线的技术咨询
自动化识别波箱俯视图像中地板与墙壁分隔线的技术咨询
我现在需要找到一系列图像中几条特定线条的位置。这些图像是从GoPro视频导出的,镜头俯视着一个倾斜的地板(类似波箱里的沙滩)。我的最终目标(不过不是这次提问的重点)是分析图像中粒子在波浪经过前后的位置。这次提问的核心是:我要识别出分隔波箱墙壁和地板的线条,这样就能把图像中显示地板的区域转换成矩形,还能把多个相机拍摄的图像拼接起来展示整个地板。当我手动标记出这些分隔线时,变换和拼接的效果都很好,但每次实验相机都会轻微移动,所以我想找个自动化的方法来节省时间。
我手动标记出目标线条的示例图如下:
相机在不同图像间会有轻微移动,这也是我想自动化的原因。不过我知道,我要找的线条总是贯穿整个图像,从左边缘到右边缘,而且角度非常接近水平。
我试过用skimage的霍夫变换,直接在原图上用,也在边缘检测后的结果上用,但效果很差。下面是一段代码示例,还有对应的结果,参考了skimage官方的霍夫变换示例:
from skimage.transform import hough_line, hough_line_peaks from skimage.filters import scharr from skimage.color import rgb2lab import matplotlib.image as mpimg im = mpimg.read('image.png') edges = scharr(rgb2lab(im[:,:,:])[:,:,0]) # 在L通道上执行边缘检测 angles = np.linspace(0.95*np.pi/2, 1.05*np.pi/2, 100) # 只考虑很窄范围的角度 h, theta, d = hough_line(edges, angles) peaks = hough_line_peaks(h, theta, d, threshold=0.99*np.amax(h)) # 用很高的阈值,默认是0.5*max(h) plt.imshow(im) for _, angle, dist in zip(*peaks): (x0, y0) = dist * np.array([np.cos(angle), np.sin(angle)]) plt.axline((x0, y0), slope=np.tan(angle + np.pi / 2), lw=0.5, alpha=0.75, c='r')
对应的结果图:
结果识别出了一大堆错误的线条,完全不是我要找的那些。
我还试了概率霍夫变换:
from skimage.transform import probabilistic_hough_line lines = probabilistic_hough_line(edges, threshold=10, line_length=5000, theta=angles) plt.imshow(im) for l in lines: plt.plot([l[0][0], l[1][0]], [l[0][1], l[1][1]], c='r', alpha=0.75, lw=0.5)
对应的结果图:
这次看起来我要找的线条好像被识别出来了,但同时也有一大堆其他无关线条。我试过调整threshold参数,但没看到明显效果。
我知道可能没法完美自动找到目标线条,因为图像里还有其他线条,但目前的结果实在太离谱了。非常欢迎各位给出建议。
补充更新:
我发现如果先做轻微的高斯模糊,然后用Canny边缘检测器代替Scharr,效果要好很多:
from skimage.feature import canny l = rgb2lab(im[:,:,:])[:,:,0] edges = canny(gaussian(l, 3), 1, 10, 20)
对应的边缘检测结果图:
对应的霍夫变换结果图:
最新更新:这里是原始图像:
备注:内容来源于stack exchange,提问作者Tor




