【问题标题】:Using a function as a convolution kernel使用函数作为卷积核
【发布时间】:2022-01-15 10:25:12
【问题描述】:

各位程序员们好,

我目前正在做这几年advent of code。 在day 9 上,我需要找出图像中的像素是否具有相邻像素的最小值。

我首先非常直观和粗略地解决了这个问题,但是现在看了一段时间后想知道是否有一种方法可以为 opencv 的filter2D-function 或其他合适的库定义卷积核,我可以尝试将内核定义为一个函数,这样我不仅可以执行线性变换,还可以执行其他变换。

在这个具体的例子中,我正在考虑一个内核,它可以判断中间像素是否具有最低值。也许甚至有一种方法可以使用线性变换来做到这一点,但是我找不到它。

感谢任何帮助。

【问题讨论】:

  • 侵蚀/扩张,比较,完成。侵蚀/扩张是不是线性的,这就是他们可以解决这个问题的原因。没有任何线性可以解决这个问题。
  • 您是否相信我对昨天的 AOC 问题进行了完全相同的推理。最终以“粗鲁”的方式破解它
  • @ChristophRackwitz 非常感谢!不知道那些操作。一直在学习:)

标签: python opencv image-processing


【解决方案1】:

我自己找到了一个解决方案,只需使用scipy.ndimage.generic_filter

import numpy as np
from scipy.ndimage import generic_filter

# First define the footprint of the filter you are going to use:
footprint = np.array([[False, True, False],
                     [True, True, True],
                     [False, True, False]])

# Then define the filter you want to use:
def lowpoint_kernel(a):
    return 0 if a[2] < a[0] and a[2] < a[1] and a[2] < a[3] and a[2] < a[4] else 10

# Get your input here
image = ...

# Pad your image
image = np.pad(image, 1, constant_values=10)

lowpoints = generic_filter(image, lowpoint_kernel, footprint=footprint)
lowpoint_indices = lowpoints == 0

这很可能是一个非常复杂的解决方案,但也许有人会发现这很有用。 查看我的完整解决方案here

【讨论】:

    【解决方案2】:

    在 python 中使用 scipy 通用过滤器是一个好主意。 但据我所知,OpenCV 没有提供这种方式(自定义函数句柄作为过滤器)。因此,如果您想使用 OpenCV 函数来执行此操作,您可以首先应用 侵蚀形态操作 (cv::erode)(使用您想要的窗口大小和二进制掩码)以获得每个像素的最小值邻域,然后使用cv::compare 方法等将结果图像与原始图像进行比较。
    要排除最小(侵蚀)的中心像素,您可以将自定义二进制内核传递给 cv::erode,其中中心像素在生成的内核中为零。
    总而言之,你应该这样做:

    1. cv::Mat 内核 = cv::Mat::ones(3,3,CV_8UC1);
      kernel.at(1, 1)=0;
    2. cv::erode(src, dst_min, kernel);
    3. cv::compare(src, dst_min, dst, cv::CMP_EQ);

    话虽如此,这种方法的唯一限制是在 cv::erode 函数中对非零邻居计算最小操作。如果这不是你想要的效果,你可以给 src 添加一个偏差,然后减去它!

    最后但同样重要的是,如果您使用的是 cpu(而不是 gpu),我建议 cv::ParallelLoopBody 只需一次调用(内存访问)即可并行实施所有过程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 2016-12-31
      • 1970-01-01
      相关资源
      最近更新 更多