c++ - 使用 OpenCV 减去流离失所的掩码

标签 c++ windows image-processing opencv

我想做的事:

masked = image - mask

但我想“取代”掩码。也就是上下左右移动(只要和image的交集不为空,就有效)。

我有一些手工编码的程序集(使用 MMX 指令)可以执行此操作,嵌入到 C++ 程序中,但在进行垂直位移时它不稳定,所以我想到改用 OpenCV。是否可以仅调用一个 OpenCV 函数来执行此操作?

性能很关键;使用 OpenCV,时间至少应与汇编代码处于同一数量级。

编辑:这是一个例子

image(中帧,看这家伙头骨的对比度):

Image

mask(第一帧,无对比):

enter image description here

image - mask,无位移。请注意对比路径是如何增强的,但由于患者移动了一点,我们可以看到一些颅骨轮廓,这些轮廓是用于诊断目的的视觉噪声。

enter image description here

image - maskma​​sk 向下移动了大约 5 个像素。为了尝试补偿患者运动引入的噪音,我们稍微“移动”了 mask 以去除轮廓并更好地看到对比度路径(调整了亮度和对比度,这就是它看起来有点暗的原因)。

enter image description here

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

最佳答案

我知道这是用 Python 编写的,所以不是您想要的,但是将它翻译成 C++ 应该非常简单。它将两个图像裁剪到匹配大小(几乎所有操作都需要),由图像之间的位移及其相对大小决定。这个方法应该很快,因为 cv.GetSubRect 不复制任何东西,所以它只是到 cv.AbsDiff 函数(如果你有一个实际的差异掩码,你可以使用 cv.Sub 这应该会更快)。此外,此代码将处理任何方向的位移,掩码和图像可以是任何大小(掩码可以大于图像)。指定位移必须有重叠。图像之间的差异可以单独查看,也可以“就地”查看差异。

一个很好的图表来说明发生了什么。前两个方 block 是示例 imagemask。接下来的三个方 block 显示“蒙版”的水平位移为 -30、0 和 30 像素,最后一个方 block 的位移为 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)

关于c++ - 使用 OpenCV 减去流离失所的掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9791866/

相关文章:

c - 从 cmd.exe 运行时如何从 cscope-win32 启动 gvim.exe?

python - 如何将具有连接像素的形状分成二值图像中的两个部分

image-processing - scipy中的高斯滤波器

python - 我怎么能 "listen"内部主板扬声器上的声音

c++ - 当我们使用 mpi_send/receive 函数时到底发生了什么?

c++ - 在c++中为字符串添加标点符号

c++ - VS10下openmp语法错误

python - 如何在启用 visual studio 环境的情况下运行 SublimeText

image-processing - HSV 中的红色范围是多少?

c++ - 什么是 CInternetSession 的必要清理