OpenCV零填充

2 投票
2 回答
6694 浏览
提问于 2025-04-16 13:43

我正在使用 cvFilter2D 来处理图像。它的 文档 上说:

当图像的某部分在边缘之外时,这个函数会从最近的在图像内的像素中推算出外部像素的值。

虽然这种推算在大多数情况下都可以,但我想通过 零填充 来处理这些外部像素值(这里有一个 1D 示例 来说明这是什么意思)。

这是我目前的做法:

def do_filter(im, filt):
    N, M = cv.GetSize(filt)
    _, _, width, height = cv.GetImageROI(im)
    padded = cv.CreateImage((width + N, height + M), im.depth, im.nChannels)
    cv.SetZero(padded)
    roi = (N/2, M/2, width, height)
    cv.SetImageROI(padded, roi)
    cv.Copy(im, padded)
    cv.ResetImageROI(padded)
    cv.Filter2D(padded, padded, filt)
    result = cv.CreateImage(cv.GetSize(im), im.depth, im.nChannels)
    cv.SetImageROI(padded, roi)
    cv.Copy(padded, result)
    return result

简单来说:

  • 创建一个填充的图像,并复制输入内容
  • 进行滤波处理
  • 去掉填充的部分

我不喜欢这样,因为我需要做很多繁琐的工作,只是在移动像素。这很慢。

有没有更好的方法在滤波时进行零填充呢?

编辑

我发现了 cvCopyMakeBorder,这个方法稍微干净一些,但仍然需要复制图像,所以还是很慢。

编辑 2

cv::filter2D 在 C++ API 中可以做到这一点。我想知道旧的 C API 是否也有类似的功能(我无法从 Python 访问 C++ API,但可以访问 C API)。

2 个回答

1

我不太确定Python是怎样的,但在C/C++中,你可以指定一个常量来处理“未定义”的像素。把这个常量设置为0,就能解决你的问题。我相信Python也有类似的功能。

2

如果你不介意你的图片外边缘那一像素的部分被去掉,你可以把它设置为0,这样“插值”就能给你想要的效果。

撰写回答