我想做的事:
masked = image - mask
但我想“取代”掩码
。也就是上下左右移动(只要和image
的交集不为空,就有效)。
我有一些手工编码的程序集(使用 MMX 指令)可以执行此操作,嵌入到 C++ 程序中,但在进行垂直位移时它不稳定,所以我想到改用 OpenCV。是否可以仅调用一个 OpenCV 函数来执行此操作?
性能很关键;使用 OpenCV,时间至少应与汇编代码处于同一数量级。
编辑:这是一个例子
image
(中帧,看这家伙头骨的对比度):
mask
(第一帧,无对比):
image - mask
,无位移。请注意对比路径是如何增强的,但由于患者移动了一点,我们可以看到一些颅骨轮廓,这些轮廓是用于诊断目的的视觉噪声。
image - mask
,mask 向下移动了大约 5 个像素。为了尝试补偿患者运动引入的噪音,我们稍微“移动”了 mask 以去除轮廓并更好地看到对比度路径(调整了亮度和对比度,这就是它看起来有点暗的原因)。
编辑 2:关于算法,我设法解决了它的问题。它不再崩溃,但缺点是它现在处理所有图像像素(它应该只处理那些需要减去的像素)。无论如何,如何修复旧代码不是我的问题;我的问题是,如何使用 OpenCV 进行此处理?我稍后会发布一些分析结果。
最佳答案
我知道这是用 Python 编写的,所以不是您想要的,但是将它翻译成 C++ 应该非常简单。它将两个图像裁剪到匹配大小(几乎所有操作都需要),由图像之间的位移及其相对大小决定。这个方法应该很快,因为 cv.GetSubRect
不复制任何东西,所以它只是到 cv.AbsDiff
函数(如果你有一个实际的差异掩码,你可以使用 cv.Sub
这应该会更快)。此外,此代码将处理任何方向的位移,掩码和图像可以是任何大小(掩码可以大于图像)。指定位移必须有重叠。图像之间的差异可以单独查看,也可以“就地”查看差异。
一个很好的图表来说明发生了什么。前两个方 block 是示例 image
和 mask
。接下来的三个方 block 显示“蒙版”的水平位移为 -30、0 和 30 像素,最后一个方 block 的位移为 20、20。
import cv
image = cv.LoadImageM("image.png")
mask = cv.LoadImageM("mask.png")
image = cv.LoadImageM("image2.png")
mask = cv.LoadImageM("small_mask.png")
image_width, image_height = cv.GetSize(image)
mask_width, mask_height = cv.GetSize(mask)
#displacements here:
horiz_disp = 20
vert_disp = 20
image_horiz = mask_horiz = image_vert = mask_vert = 0
if vert_disp < 0:
mask_vert = abs(vert_disp)
sub_height = min(mask_height + vert_disp, image_height)
else:
sub_height = min(mask_height, image_height - vert_disp)
image_vert = vert_disp
if horiz_disp < 0:
mask_horiz = abs(horiz_disp)
sub_width = min(mask_width + horiz_disp, image_width)
else:
sub_width = min(mask_width, image_width - horiz_disp)
image_horiz = horiz_disp
#cv.GetSubRect returns a rectangular part of an image, without copying any data. - fast.
mask_sub = cv.GetSubRect(mask, (mask_horiz, mask_vert, sub_width, sub_height))
image_sub = cv.GetSubRect(image, (image_horiz, image_vert, sub_width, sub_height))
#Subtracts the mask overlap region from the image overlap region, puts it in image_sub
cv.AbsDiff(image_sub, mask_sub, image_sub)
# Shows diff only:
cv.ShowImage('image_sub', image_sub)
# Shows image with diff section
cv.ShowImage('image', image)
cv.WaitKey(0)
关于c++ - 使用 OpenCV 减去流离失所的掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9791866/