You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

自动化识别波箱俯视图像中地板与墙壁分隔线的技术咨询

自动化识别波箱俯视图像中地板与墙壁分隔线的技术咨询

我现在需要找到一系列图像中几条特定线条的位置。这些图像是从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)

对应的边缘检测结果图:
Canny边缘检测的结果图像

对应的霍夫变换结果图:
使用Canny后的霍夫变换结果图像

最新更新:这里是原始图像:原始图像

备注:内容来源于stack exchange,提问作者Tor

火山引擎 最新活动