c ++ - Subtraher fortrængt maske ved hjælp af OpenCV

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg ønsker at gøre:


masked = image - mask


Men jeg vil 'forskyde' mask. Det vil sige flytte det lodret og vandret (så længe skæringen mellem den og image ikke er tom, ville dette være gyldigt).


Jeg har nogle håndkodede samlinger (som bruger MMX-instruktioner), hvilket gør dette, indlejret i et C ++-program, men det er ustabilt ved lodret forskydning, så jeg tænkte på at bruge OpenCV i stedet. Kun det kun være muligt at foretage denne opkald en OpenCV-funktion?


Ydeevne er kritisk ved hjælp af OpenCV skal tiden være mindst i samme størrelsesorden som samlingskoden.


REDIGER : Her er et eksempel


image (medium ramme, se kontrast i fyrens kranium):


Image


mask (første ramme, ingen kontrast):


Indtast billedbeskrivelse her


image - mask uden forskydning. Bemærk hvordan kontrastbanen er forbedret, men siden patienten flyttede lidt, kan vi se nogle kranietkonturer, som er visuel støj til diagnostiske formål.


Indtast billedbeskrivelse her


image - mask, maske forskudt omkring 5 pixels ned . For at forsøge at kompensere for den støj, der indføres af patientens bevægelse, forskyder vi masken lidt for at fjerne konturerne og se bedre på kontrastbanen (lysstyrke og kontrast blev justeret, det er derfor, det ser lidt mørkere ud ).


Indtast billedbeskrivelse her


EDIT 2 : Om algoritmen lykkedes det mig at løse sine problemer. Det kolliderer ikke længere, men ulempen er, at det nu behandler alle billedpixler (det bør kun behandle dem, der skal trækkes fra.) I hvert fald, hvordan man løser den gamle kode er ikke mit spørgsmål, mit spørgsmål er, hvordan Jeg gør denne behandling ved hjælp af OpenCV? Jeg sender nogle profileringsresultater senere.

Bedste reference


Jeg ved, at dette er i Python, så ikke hvad du er efter, men at oversætte den til C ++ skal være meget ligeud. Den beskærer begge billeder til matchende størrelser (kræves til næsten alle operationer), bestemt ved forskydningen mellem billederne og deres relative størrelser. Denne metode skal være hurtig, da cv.GetSubRect ikke kopierer noget, så det er lige ned til funktionen cv.AbsDiff (hvis du har en faktisk forskel maske, kan du bruge cv.Sub som skal gøre det endnu hurtigere). Også denne kode vil håndtere forskydning i en hvilken som helst retning, og masken og billedet kan være en hvilken som helst størrelse (masken kan være større end billedet). Der skal være en overlapning for en bestemt forskydning Forskellen mellem billeder kan ses alene, eller forskellen 'i stedet'.


Et godt diagram til at illustrere hvad der foregår. De to første firkanter er eksempel image og mask. De næste tre firkanter viser en vandret forskydning af 'masken' på -30, 0 og 30 pixel, og den sidste har en forskydning på 20, 20.


Indtast billedbeskrivelse her


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)