去除被白色像素包围的像素 OpenCV

3

我有一张黑白图像,上面有很多噪点。我想把完全被白色像素包围的黑色像素去掉。我尝试使用Filter2d进行操作,但是没有成功。


1
“删除像素”是什么意思?您希望将这些黑色像素变为白色吗?此外,您显然在提出两个不同的问题:第一个是“删除”像素,第二个是保留三个最大的片段。请将您的问题拆分为两个不同的StackOverflow问题。 - Oliver W.
是的,我想把黑色像素变成白色。 - Asmastas Maz
你可以使用OpenCV中的find blobs函数,并且将那些太小和黑色的blob去除。请参考https://docs.opencv.org/3.4/d0/d7a/classcv_1_1SimpleBlobDetector.html和https://www.learnopencv.com/blob-detection-using-opencv-python-c/。 - fmw42
3个回答

3

我会再次使用卷积(Convolution)1

>>> import numpy as np
>>> from scipy.signal import convolve2d
>>> 
>>> kernel = np.ones((3,3))
>>> kernel[1,1] = 0
>>> print(kernel)
[[ 1.  1.  1.]
 [ 1.  0.  1.]
 [ 1.  1.  1.]]
>>> # Create a decent test array that shows the features
... test = np.array(
...     [[0,1,1,0,1,1],
...      [1,1,1,1,1,0],
...      [1,0,1,1,0,1],
...      [1,1,1,0,0,0],
...      [1,1,1,0,1,0],
...      [1,1,1,0,0,0]])
>>> 
>>> mask = convolve2d(test, kernel, mode='same', fillvalue=1)
>>> print(mask)
[[ 8.  7.  7.  8.  6.  7.]
 [ 6.  6.  6.  6.  5.  7.]
 [ 7.  8.  6.  5.  4.  4.]
 [ 7.  7.  5.  5.  3.  5.]
 [ 8.  8.  5.  4.  0.  4.]
 [ 8.  8.  6.  6.  4.  6.]]
>>> result = test.copy()
>>> result[np.logical_and(mask==8, test==0)] = 1
>>> print(result)
[[1 1 1 1 1 1]
 [1 1 1 1 1 0]
 [1 1 1 1 0 1]
 [1 1 1 0 0 0]
 [1 1 1 0 1 0]
 [1 1 1 0 0 0]]

正如您所看到的,result数组已经将所有完全被白色(以1表示)包围的“黑色”像素(这里用0表示)在8个方向上进行了更改,即使在角落和边缘也是如此。
编辑:如果您有“pepper”噪声,即由白色像素包围的小组黑色像素而不仅仅是单个像素,则Hugo Rune的答案更好。对于单个像素,即我解释您的问题的方式,以上内容将正常工作。
注脚:
1:实际上,您需要进行相关性计算,但在这种情况下,它是相同的,因为内核是对称的。

2

4年后,我遇到了一个类似的任务,需要去除单像素噪声。

OpenCV的 Camera Calibration 模块中的 filterspeckles 函数非常适用于这个任务。

代码:

import cv2
import numpy as np

data = np.array([[1, 1, 1, 1, 1, 1],
                 [1, 1, 1, 1, 1, 0],
                 [1, 0, 0, 0, 0, 1],
                 [1, 0, 1, 0, 0, 0],
                 [1, 0, 1, 0, 1, 0],
                 [1, 0, 0, 0, 0, 0]]).astype(np.uint8)

print('Input')
print(data)
cv2.filterSpeckles(data, 0, 1, 1)[0]

print('Output')
print(data)

"最初的回答":控制台:
Input
[[1 1 1 1 1 1]
 [1 1 1 1 1 0]
 [1 0 0 0 0 1]
 [1 0 1 0 0 0]
 [1 0 1 0 1 0]
 [1 0 0 0 0 0]]
Output
[[1 1 1 1 1 1]
 [1 1 1 1 1 0]
 [1 0 0 0 0 0]
 [1 0 1 0 0 0]
 [1 0 1 0 0 0]
 [1 0 0 0 0 0]]

2
你有两种选择:
执行 形态学闭运算

enter image description here

这将删除所有单个黑色像素,但也会删除一些其他形状,例如一像素宽的黑线或尖锐的黑色角落。
这是消除“胡椒噪声”的标准方法,即嘈杂的单个黑色像素。
另一种方式,只会移除孤立的黑色像素:
- 反转图像 - 使用 findContours 找到反转图像中的所有连通组件 - 选择所有具有面积为1的找到的轮廓,并在原始图像中将它们涂成白色
但如果两个随机的黑色像素恰好相邻,则此方法不起作用。因此也许需要覆盖所有大小为2或3的区域。

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