I have an image patch that I want to insert into another image at a floating point location. In fact, what I need is something like the opposite of what the opencv getRectSubPix function does.
I guess I could implement it by doing a subpixel warp of the patch into another patch and insert this other patch into the target image at an integer location. However, I don't have clear what to do with the empty fraction of the pixels in the warped patch, or how would I blend the border of the new patch with in the target image.
I rather use a library function than implement this operation myself. Does anybody know if there is any library function that can do this type of operation, in opencv or any other image processing library?
UPDATE:
I discovered that opencv warpPerspective can be used with a borderMode = BORDER_TRANSPARENT which means that the pixels in the destination image corresponding to the "outliers" in the source image are not modified by the function. So I thought I could implement this subpixel patch insertion with just a warpPerspective and an adequate transformation matrix. So I wrote this function in python to perform the operation:
def insert_patch_subpixel(im, patch, p):
"""
im: numpy array with source image.
patch: numpy array with patch to be inserted into the source image
p: tuple with the center of the position (can be float) where the patch is to be inserted.
"""
ths = patch.shape[0]/2
xpmin = p[0] - ths
ypmin = p[1] - ths
Ho = np.array([[1, 0, xpmin],
[0, 1, ypmin],
[0, 0, 1]], dtype=float)
h,w = im.shape
im2 = cv2.warpPerspective(patch, Ho, (w,h), dst=im,
flags=cv2.INTER_LINEAR,
borderMode=cv2.BORDER_TRANSPARENT)
return im2
Unfortunately, the interpolation doesn't seem to work for the outlier pixels if BORDER_TRANSPARENT is used. I tested this function with a small 10x10 image (filled with value 30) and inserting a 4x4 patch (filled with value 100) at p=(5,5) (left figure) and p=(5.5,5.5) (middle figure) and we can see in the figures below that there is no interpolation in the border. However, if I change the boderMode to BORDER_CONSTANT the interpolation works (right figure), but that also fills the destination image with 0s for the outlier values.
It's a shame that interpolation doesn't work with BORDER_TRANSPARENT. I'll suggest this as an improvement to the opencv project.