如何使用OpenCV(Python)检测图像中的岩石?

3
我尝试在这张图片中寻找形状不同的岩石。 image
(来源:nasa.gov 边缘检测没有给我满意的结果。

enter image description here

我已经了解过grabcut,但是没有得到令人满意的结果。你有什么建议吗?

PS - 我的最终目标是用不同的颜色标记图像中的这些岩石。

更新1: 这是我用于边缘检测的代码。

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('image1.JPG',0)
edges = cv2.Canny(img,255,255)

plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])

plt.show()

更新2:我有几张类似于下面这张图片的图像,其中岩石(大型)非常清晰可见。边缘检测再次在图像上产生了不令人满意的结果。我只是想寻找可以尝试的方法。如果您建议一种方法,请添加相关链接,以便我可以更多地阅读,我是opencv的新手。
(来源:nasa.gov

我建议您发布一些示例代码,以展示您目前所做的工作。这样,其他人就可以提出修改意见了。 - Nithish
我已经更新了问题并附上了代码。 - user2744506
那真是一团糟...我会先检测/移除黑色区域,看起来它们都是岩石。然后应用一些增强动态范围和规范化照明,但至少要使用双三次插值,并确保选择背景像素,以便消除混乱的太阳斑点。然后尝试基于面积同质性的边缘检测或分割。这最后两个步骤都需要编写很多代码... - Spektre
2
你能否创建另一张手动标记过石头的图片?对我来说,哪些部分是石头,哪些不是并不是100%确定的。不要期望能够使用算法在这种类型的图像中检测到所有的石头,我认为这几乎是不可能的。也许不同种类的传感器会更好(如红外相机,立体相机,激光扫描仪等),但我不确定。 - Micka
1
不,我没有彩色图片。 - user2744506
显示剩余5条评论
2个回答

2
这些岩石是图像中比沙子更平坦的部分。你可以尝试获取文件的每一行,将其分成小段,并计算段的峭度。

峭度 是衡量段中值的频率钟形曲线的“高度”和“宽度”的指标。沙子的峭度显然比岩石低,因为它具有“较宽”的频率谱。具有高峭度的段可能属于岩石。

因此,关键是确定每个图像行必须分成的理想段长度。这并不是一个简单的任务,但也不是一个困难的任务。最小的岩石宽度的一半(但至少比沙粒宽100倍)应该能解决问题。


0
从一个二维图片来看...真的很具有挑战性。我敢打赌,使用两张带有偏移的图片作为立体图像处理会更容易。如果没有这个条件,我建议采用以下策略:
  1. 预处理以滤除噪声异常值 - 中值
  2. 也许可以使用二维带通滤波器来筛选出特定尺寸的岩石。
  3. 使用你所做的边缘检测 - 似乎已经做得非常好。
  4. 使用能够识别顶点聚类的算法。
  5. 使用凸包或Voronoi将聚类中的点或顶点合并。

话虽如此,我怀疑这个论坛是否适合寻求关于你的问题的直接编码答案,因为提供一个简单明了的答案非常困难。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接