使用OpenCV减去移位的面罩

时间:2012-03-20 17:26:22

标签: c++ windows image-processing opencv

我想这样做:

masked = image - mask

但我想“取代”mask。也就是说,垂直和水平移动它(只要它与image之间的交集不为空,这将是有效的。)

我有一些手工编码的程序集(使用MMX指令)这样做,嵌入在C ++程序中,但在进行垂直位移时它不稳定,所以我想用OpenCV代替。是否可以只调用一个OpenCV函数?

表现至关重要;使用OpenCV时,时间应至少与汇编代码的数量级相同。

编辑:这是一个例子

image(中等框架,看到男人头骨中的对比):

Image

mask(第一帧,无对比):

enter image description here

image - mask,没有流离失所。注意对比度路径是如何增强的,但是由于患者移动了一点,我们可以看到一些头部轮廓,这些轮廓是用于诊断目的的视觉噪声。

enter image description here

image - mask掩码移位约5个像素。为了尝试补偿患者运动引起的噪音,我们稍微“移动”面罩,以便去除轮廓并更好地看到对比度路径(调整亮度和对比度,这就是为什么它看起来有点暗)。

enter image description here

编辑2 :关于算法,我设法修复了它的问题。它不再崩溃,但缺点是它现在处理所有图像像素(它应该只处理那些需要减去的像素)。无论如何,如何修复旧代码不是我的问题;我的问题是,如何使用OpenCV进行此处理?我稍后会发布一些分析结果。

1 个答案:

答案 0 :(得分:2)

我知道这是在Python中,所以不是你所追求的,但是将它转换为C ++应该非常直接。它将两个图像裁剪成匹配的尺寸(几乎所有操作都需要),由图像之间的位移和它们的相对尺寸决定。这个方法应该很快,因为cv.GetSubRect不会复制任何内容,所以它只是cv.AbsDiff函数(如果你有一个实际的差异掩码,你可以使用cv.Sub它甚至更快)。此代码也将处理任何方向的位移,并且蒙版和图像可以是任何大小(蒙版可以大于图像)。指定的位移必须有重叠。可以单独查看图像之间的差异,也可以“就地”查看差异。

一个很好的图表来说明最新情况。前两个方块是示例imagemask。接下来的三个方块显示-30,0和30像素的'掩码'的水平位移,最后一个方格的位移为20,20。

enter image description here

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)