OpenCV零填充
我正在使用 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,这样“插值”就能给你想要的效果。