使用函数作为卷积核



各位程序员好,

我目前正在做这几年的代码问世。第9天,我需要找出图像中的像素是否具有相邻像素中最小的值。

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

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

感谢您的帮助。

我自己发现了一个简单使用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

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

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

  1. cv::Mat kernel=cv::Mat::ones(3,3,cv_8UC1(
    kernel.at(1,1(=0
  2. cv::侵蚀(src、dst_min、kernel(
  3. cv::compare(src,dst_min,dst,cv::CMP_EQ(

已经说过,这种方法的唯一限制是在cv::侵蚀函数中的非零邻居上计算最小运算。如果这不是你的欲望效果,你可以在src中添加一个偏置,然后减去它!

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

最新更新