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

问题描述 投票:0回答:1

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

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

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

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

有没有办法用

OpenCV
做到这一点?

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

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

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

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

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

python opencv computer-vision blur gaussianblur
1个回答
0
投票

我将首先演示一些事情。让我们从随机噪声开始......

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

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

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

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

我们来比较一下:

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

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

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

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

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.