Вычтите смещенную маску, используя OpenCV - PullRequest
1 голос
/ 20 марта 2012

Я хочу сделать:

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

EDIT 2 : По поводу алгоритма мне удалось исправить его проблемы. Он больше не падает, но недостатком является то, что теперь он обрабатывает все пиксели изображения (он должен обрабатывать только те, которые должны быть вычтены). В любом случае, как исправить старый код, это не мой вопрос; мой вопрос, как мне сделать эту обработку с использованием OpenCV? Я опубликую некоторые результаты профилирования позже.

1 Ответ

2 голосов
/ 21 марта 2012

Я знаю, что это на Python, поэтому не то, что вам нужно, но перевод его на C ++ должен быть очень простым.Он обрезает оба изображения до соответствующих размеров (требуется почти для всех операций), определяемых смещением между изображениями и их относительными размерами.Этот метод должен быть быстрым, так как cv.GetSubRect ничего не копирует, так что его просто до функции cv.AbsDiff (если у вас есть действительная маска различий, вы можете использовать cv.Sub, что должно сделать ее еще быстрее).Также этот код будет обрабатывать смещение в любом направлении, и маска и изображение могут быть любого размера (маска может быть больше, чем изображение).Должно быть перекрытие для указанного смещения.Разницу между изображениями можно просматривать отдельно или разницу «на месте».

Хорошая диаграмма, иллюстрирующая происходящее.Первые два квадрата являются примерами image и mask.Следующие три квадрата показывают горизонтальное смещение «маски» -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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...