msarahan | 5 Mar 01:49 2010
Picon

cv.AbsDiff problem - python/opencv 2.0

Hi all,

I'm stumped on a problem with AbsDiff.  I'm trying to use the difference between two images as a metric for
image registration.

In the code below, I take an image, transform it (which changes the image size), and then pad the reference
image to match that size.  All images going into the AbsDiff are signed 16-bit IPL images, to prevent
rounding to 0.

the output of all the images involved is:
img.depth, img.nChannels, img.width, img.height
-2147483632 1 512 512

Seemingly identical, but it won't recognize them as such.

OpenCV Error: Assertion failed (src1.size() == dst.size() && src1.type() == dst.type()) in cvAbsDiff,
file /home/msarahan/Downloads/OpenCV-2.0.0/src/cxcore/cxarithm.cpp, line 1622

Note: this code works fine if the reference is the same size as the other image.  It produces this error when
the reference is smaller that the other image.

You should be able to change refImageFile and exptImageFile to two images on your computer to test this.

Any suggestions will be much appreciated.
Thanks,
Mike

-----------------------------------------------------------------
import cv
#from transforms import affine,pad
import numpy as np

refImageFile='ref-sim.png'
exptImageFile='affExpt.tif'

#The following 2 functions are included here to make this example self-contained.

def affine(img,a,b,c,d,e,f, shift=False):
    """
    Applies an affine warp to an input image.
    Input: OpenCV image object, affine matrix values (6).
    Output: OpenCV image object.
    More info on affine transformations here:
    http://www.gnome.org/~mathieu/libart/libart-affine-transformation-matrices.html
    """
    affineWarpMatrix=cv.CreateMat(2,3,cv.CV_32FC1)
    cv.Set2D(affineWarpMatrix,0,0,a)
    cv.Set2D(affineWarpMatrix,0,1,b)
    cv.Set2D(affineWarpMatrix,0,2,c)
    cv.Set2D(affineWarpMatrix,1,0,d)
    cv.Set2D(affineWarpMatrix,1,1,e)
    cv.Set2D(affineWarpMatrix,1,2,f)

    # This section adjusts the frame to fit the whole image.  It's necessary when
    # large adjustments are being made.  It's also slow, and bogs down the affine
    # optimizer, which is why it's not used for the fine-tuning.
    if shift:   
        npWarp=np.mat([a,b,c,d,e,f,0,0,1]).reshape((3,3))
        # This stuff is for applying the translation/resize to keep the distorted 
        # image in the frame.
        upperLeft = npWarp*np.mat([0,0,1]).reshape((3,1))
        upperRight = npWarp*np.mat([img.width,0,1]).reshape((3,1))
        lowerLeft = npWarp*np.mat([0,img.height,1]).reshape((3,1))
        lowerRight = npWarp*np.mat([img.width,img.height,1]).reshape((3,1))
        transformedCorners = np.hstack((upperLeft, upperRight, lowerLeft, lowerRight))
        xshift,yshift=transformedCorners[0].min(),transformedCorners[1].min()
        cv.Set2D(affineWarpMatrix,0,2,(c-xshift))
        cv.Set2D(affineWarpMatrix,1,2,(f-yshift))
        imgWidth = int(transformedCorners[0].max()-transformedCorners[0].min())
        imgHeight = int(transformedCorners[1].max()-transformedCorners[1].min())
        # end translation adjustment section...
        outputImg = cv.CreateImage((imgWidth,imgHeight),
                                img.depth, img.nChannels)
    else:
        outputImg = cv.CloneImage(img)
    cv.WarpAffine(img,outputImg, affineWarpMatrix, 10,0)
    # 10 here is cubic interpolation (2) plus constant value fill 
    # of outlier pixels (8)
    # Other options: 
    # Interpolation: area (3), linear (1), nearest neighbor (0)
    # Edge treatment: Constant value fill (8)
    # Whatever you choose, you should put the sum of the two things you choose
    #   as the last argument here.
    return outputImg

def pad(origImage,finalSize):
    pad_img=cv.CreateImage(finalSize,origImage.depth,origImage.nChannels)
    pad_offset=(div2(finalSize[0]-origImage.width),div2(finalSize[1]-origImage.height))
    # 0 is IPL_BORDER_CONSTANT
    cv.CopyMakeBorder(origImage, pad_img, pad_offset, 0, 0)  
    return pad_img

#---------------------------------------------------------------------
# This attempts to find the difference between 2 images after an affine 
# transformation.  I use it to register images.

refImageFile='ref-sim.png'
exptImageFile='affExpt.tif'
origref= cv.LoadImage(refImageFile,0)
ref = cv.CloneImage(origref)
cv.Smooth(origref,ref,cv.CV_MEDIAN,5)
ref_bg=cv.CloneImage(origref)
cv.Sub(origref,ref,ref_bg)
cv.EqualizeHist(ref_bg, ref)
#cv.SetImageROI(ref, (20, 20, ref.width-40, ref.height-40))
#refCrop=cv.CreateImage((ref.width-40,ref.height-40),ref.depth,ref.nChannels)
#cv.Copy(ref,refCrop)
#cv.ResetImageROI(ref)
origimg = cv.LoadImage(exptImageFile,0)
img = cv.CloneImage(origimg)
cv.Smooth(origimg,img,cv.CV_MEDIAN,5)
img_bg = cv.CloneImage(origimg)
cv.Sub(origimg,img,img_bg)
cv.EqualizeHist(img_bg, img)
ref16=cv.CreateImage((ref.width,ref.height),cv.IPL_DEPTH_16S,1)
cv.ConvertScale(ref,ref16)

a = 1
b = 0
c = 0
d = 0
e = 1
f = 0

affImg = affine(img,a,b,c,d,e,f)
affImg16=cv.CreateImage((affImg.width,affImg.height),cv.IPL_DEPTH_16S,1)
cv.ConvertScale(affImg,affImg16)
ref16r=cv.CloneImage(ref16)
if ref16r.width < affImg16.width:
    ref16r=pad(ref16,(affImg16.width,affImg16.height))
    cv.SaveImage('bigref.png', ref16r)

else:
    affImg16=pad(affImg16,(ref16r.width,ref16r.height))
    cv.SaveImage('bigexpt.png',affImg16)

diffImg=cv.CreateImage((affImg16.width,affImg16.height),cv.IPL_DEPTH_16S,1)
cv.AbsDiff(affImg16,ref16,diffImg)
print cv.Sum(diffImg)[0]

------------------------------------

Change settings: http://www.yahoogroups.com/mygroups, select
   Get Emails (get all posts)
   Daily Digest (one summary email per day)
   Read on the web (read posts on the web only)Or Unsubscribe by mailing OpenCV-unsubscribe <at> yahoogroups.com

Gmane