【问题标题】:Extract dark contour提取深色轮廓
【发布时间】:2019-02-19 08:27:52
【问题描述】:

我想用 opencv 从图像中提取较暗的轮廓。我试过使用一个简单的阈值,例如下面(c++)

cv::threshold(gray, output, threshold, 255, THRESH_BINARY_INV);

我可以迭代阈值,比如说 50 ~ 200 然后我可以在中间得到较暗的轮廓 对于像这样具有明显区别的图像

这是阈值的结果

但是如果轮廓靠近边界,阈值就会失败,因为像素几乎相同。 比如这张图片。

我想问的是opencv中是否有任何技术可以在图像中间提取较暗的轮廓,即使轮廓到达边界并且与边界具有几乎相同的像素?

(更新)

在中间的阈值较暗轮廓与边框顶部重叠之后。 这让我无法提取前两个“SS”等字符。

【问题讨论】:

  • 你能添加一个预期的结果吗?你的问题的表述方式,我不明白你的意思是在图像中间提取较暗的轮廓
  • 即使将你得到的结果加上最后一张图片,也会更容易理解。
  • 尝试自适应阈值
  • @RickM。所以从最后一张图片来看,中间较暗的轮廓应该是“SS400-17 291330-04”。我尝试使用阈值技术,但像素与边框边缘重叠。
  • @Miki 我尝试了您的建议,但结果噪音太大。最有可能可以提取使用噪声消除的前两个字符“SS”,但其他字符变得困难。见 [链接] (i.stack.imgur.com/vVmd5.png)

标签: opencv


【解决方案1】:

我认为您可以简单地添加一个边缘保持平滑步骤来解决这个问题:

// read input image
Mat inputImg = imread("test2.tif", IMREAD_GRAYSCALE);

Mat filteredImg;
bilateralFilter(inputImg, filteredImg, 5, 60, 20);

// compute laplacian
Mat laplaceImg;
Laplacian(filteredImg, laplaceImg, CV_16S, 1);

// threshold
Mat resImg;
threshold(laplaceImg, resImg, 10, 1, THRESH_BINARY);

// write result
imwrite("res2.tif", resImg);

这将为您提供以下结果:result

问候,

【讨论】:

  • 再次感谢您。我接受了你的回答。 BilateralFilter 和 Laplacian 是解决这个问题的关键。现在我需要自动找到bilateralFilter和threshold的正确参数。
【解决方案2】:

我认为使用 laplacian 可以部分解决您的问题:

// read input image
Mat inputImg = imread("test2.tif", IMREAD_GRAYSCALE);

// compute laplacian
Mat laplaceImg;
Laplacian(inputImg, laplaceImg, CV_16S, 1);

Mat resImg;
threshold(laplaceImg, resImg, 30, 1, THRESH_BINARY);

// write result
imwrite("res2.tif", resImg);

使用此代码,您应该获得如下内容: this result

然后您可以使用最终阈值和拉普拉斯内核大小。

您可能需要在此操作后移除小工件。

问候

【讨论】:

  • 感谢您的回复。我看到了你的结果,但是在应用噪声消除后,两个字符“SS”被剪掉了一半。
猜你喜欢
  • 2015-03-10
  • 2011-05-24
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-15
  • 1970-01-01
相关资源
最近更新 更多