去除被白色像素OpenCV包围的像素
Removing pixels surrounded by white pixels OpenCV
我有一张黑白图像,其中有很多噪点。我只想删除完全被白色像素包围的黑色像素。我尝试使用 Filter2d 这样做,但我无法实现。
你有两种可能:
这将移除所有单个黑色像素,但它也会移除一些其他形状,例如 one-pixel-thick 黑线或尖锐的黑角
这是移除 "pepper-noise" 嘈杂的单个黑色像素的标准方法。
另一种方法,它将只删除孤立的黑色像素:
- 反转图像
- 使用findContours求倒置图像中的所有连通分量
- select全部找到面积为1的轮廓,并在原图中涂成白色
但是,如果两个随机的黑色像素碰巧是邻居,这将不起作用,因此可能会在所有大小为 2 或 3 的区域上绘制。
我会(再次)使用卷积 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
数组已经改变了所有 "black" 个像素(此处用值 0 表示),这些像素在所有 8 个边上都被白色(用一个表示)完全包围,甚至在角落和边缘。
编辑:Hugo Rune 的回答更好,但如果你有 "pepper" 噪音,这意味着你会有小的 组 黑色像素被白色像素包围而不仅仅是 单个像素 。对于单个像素,这就是我解释你的问题的方式,上面的方法可以正常工作。
脚注:
1:实际上你需要一个correlation
,但在这种情况下是一样的,因为内核是对称的。
4 年后,我 运行 进行了一项类似的任务来清除单个像素噪声。
OpenCV 的 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]]
我有一张黑白图像,其中有很多噪点。我只想删除完全被白色像素包围的黑色像素。我尝试使用 Filter2d 这样做,但我无法实现。
你有两种可能:
这将移除所有单个黑色像素,但它也会移除一些其他形状,例如 one-pixel-thick 黑线或尖锐的黑角
这是移除 "pepper-noise" 嘈杂的单个黑色像素的标准方法。
另一种方法,它将只删除孤立的黑色像素:
- 反转图像
- 使用findContours求倒置图像中的所有连通分量
- select全部找到面积为1的轮廓,并在原图中涂成白色
但是,如果两个随机的黑色像素碰巧是邻居,这将不起作用,因此可能会在所有大小为 2 或 3 的区域上绘制。
我会(再次)使用卷积 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
数组已经改变了所有 "black" 个像素(此处用值 0 表示),这些像素在所有 8 个边上都被白色(用一个表示)完全包围,甚至在角落和边缘。
编辑:Hugo Rune 的回答更好,但如果你有 "pepper" 噪音,这意味着你会有小的 组 黑色像素被白色像素包围而不仅仅是 单个像素 。对于单个像素,这就是我解释你的问题的方式,上面的方法可以正常工作。
脚注:
1:实际上你需要一个correlation
,但在这种情况下是一样的,因为内核是对称的。
4 年后,我 运行 进行了一项类似的任务来清除单个像素噪声。
OpenCV 的 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]]