python - 有没有办法在 openCV 中使用条件内核,仅在条件为真时才更改图像上的像素?

标签 python opencv computer-vision blur gaussianblur

我想使用一个基于条件表达式执行像素操作的内核。

假设我有这个灰度图像(6x6 分辨率):

enter image description here

并且我使用 3x3 像素内核,如何更改中心内核像素(中心)的值当且仅当中心像素是局部最小值或者 3x3 内核中的最大值?

例如,假设我想将中心内核像素设置为周围 8 个像素的平均值值,如下所示:

, then set it to the average value of all surrounding 8 pixels.

有没有办法用OpenCV来做到这一点?

编辑:另一个更详细的示例 GIF - 9 遍实现我的示例:

enter image description here

这是使用以下公式在 Excel 中生成的(不是相对单元格引用 - 它们显示焦点“picell”周围 3x3 的内核形状:

=IF(OR(C55=MIN(B54:D56),C55=MAX(B54:D56)),(SUM(B54:D56)-C55)/8,C55)

这里是表格的左上角,其中包含第一遍的源值(这些值控制单元格颜色):

enter image description here

该表引用另一个源表。 GIF 中的每一帧都是下一个计算出的颜色表。每个图像帧之间有 3 个公式表。以下是更多背景信息:

enter image description here

最佳答案

你问:

[...] how would I change the value of the centre kernel pixel (centre) IF AND ONLY IF the centre pixel is the local minimum or maximum within the 3x3 kernel? For example, say I wanted to set the centre kernel pixel to the average value of the surrounding 8 pixels [...]

我将首先演示一些内容。我将使用 16 x 16 的小阵列。我将放大它们,以便您可以方便地观察像素。当我谈论这些图像时,我指的是 16x16 数据,而不是本文中的可视化。

让我们从随机噪声开始,因为这是您首先呈现的。

noise = np.random.randint(0, 256, size=(16, 16), dtype=np.uint8)

noise

现在您需要了解形态学运算。腐 eclipse 和膨胀正在计算局部最小值/最大值。

local_max_values = cv.dilate(noise_img, None, iterations=1)
local_min_values = cv.erode(noise_img, None, iterations=1)

local_max_values local_min_values

那有什么用?您可以比较像素值。如果一个像素等于局部极值,那么它一定是a局部极值。它不是唯一的,因为假设两个相邻像素具有相同的低/高值。它们都是极值。

让我们比较一下:

is_min = (noise_img == local_min_values)
is_max = (noise_img == local_max_values)
is_extremum = is_min | is_max

is_min is_max is_extremum

那些是面具。它们是二进制的、 bool 值的。您可以将它们用于索引或乘法。您可以想象当您将元素乘以 0 或 1 或使用反转掩码时会发生什么。

我将演示索引,但首先我需要本地平均值。

averaged = cv.blur(noise_img, (3, 3))

averaged

现在我可以复制输入(或者我可以直接对其进行处理),然后用这些位置的平均值覆盖所有极值像素。

denoised = noise_img.copy()
denoised[is_extremum] = averaged[is_extremum]

denoised

是的,这会计算所有像素的平均值,即使您不需要它。实际上,仅计算部分平均值不会节省任何时间。

如果您在此图像和源图像之间来回切换,您将看到局部极值被删除。其他曾经处于“第二位”的像素现在已经成为极值。另一轮将逐渐平滑整个图片,直到一切都变得相当平坦。

关于python - 有没有办法在 openCV 中使用条件内核,仅在条件为真时才更改图像上的像素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77428847/

相关文章:

python - 如何将 numpy 1D 与 N 维数组相乘?

python - LaunchDaemon 处理系统关闭 - 没有 SIGTERM?

python - 无法在python中使用opencv读取图像

algorithm - 如何在图像中找到这种几何形状

machine-learning - Caffe 微调与从头开始

Python - 以 sudo 方式运行选定的代码部分

c++ - 用C++将OpenCV帧写入磁盘:单线程写入速度是否受磁盘吞吐量的限制?

python - 在 Python OpenCV 4.2.0(2020 年)中使用 SIFT(或替代方法)

opencv - OpenCV的滚球背景减除算法

python - 更改 xlsxwriter 中 add_table 工作表编写器的数字格式