Add padding to object in 4-channel image

耗尽温柔 提交于 2019-12-05 07:26:48

问题


I have a 4-channel image (.png, .tif) like this one:

I am using OpenCV, and I would like to add padding of type BORDER_REFLECT around the flower. copyMakeBorder is not useful, since it adds padding to the edges of the image.

I can add certain padding if I split the image in bgr + alpha and apply dilate with BORDER_REFLECT option on the bgr image, but that solution spoils all the pixels of the flower.

Is there any way to perform a selective BORDER_REFLECT padding addition on a ROI defined by a binary mask?

EDIT:

The result I expect is something like (sorry I painted it very quickly with GIMP) :

I painted two black lines to delimit the old & new contour of the flower after the padding, but of course those lines should not appear in the final result. The padding region (inside the two black lines) must be composed by mirrored pixels from the flower (I painted it yellow to make it understandable).


回答1:


A simple python script to resize the image and copy the original over the enlarged one will do the trick.

import cv2

img = cv2.imread('border_reflect.png', cv2.IMREAD_UNCHANGED)

pad = 20
sh = img.shape
sh_pad = (sh[0]+pad, sh[1]+pad)
imgpad = cv2.resize(img, sh_pad)

imgpad[20:20+sh[0], 20:20+sh[1], :][img[:,:,3]==255] = img[img[:,:,3]==255]
cv2.imwrite("padded_image.png", imgpad)

Here is the result

But that doesn't look very 'centered'. So I modified the code to detect and account for the offsets while copying.

import cv2

img = cv2.imread('border_reflect.png', cv2.IMREAD_UNCHANGED)

pad = 20
sh = img.shape
sh_pad = (sh[0]+pad, sh[1]+pad)
imgpad = cv2.resize(img, sh_pad)

def get_roi(img):
    cimg = img[:,:,3].copy()

    contours,hierarchy = cv2.findContours(cimg,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

    #Remove the tiny pixel noises that get detected as contours
    contours = [cnt for cnt in contours if cv2.contourArea(cnt) > 10]

    x,y,w,h = cv2.boundingRect(cnt)
    roi=img[y:y+h,x:x+w]
    return roi

roi = get_roi(img)
roi2 = get_roi(imgpad)

sh = roi.shape
sh2 = roi2.shape

o = ((sh2[0]-sh[0])/2, (sh2[1]-sh[1])/2)

roi2[o[0]:o[0]+sh[0], o[1]:o[1]+sh[1], :][roi[:,:,3]==255] = roi[roi[:,:,3]==255]
cv2.imwrite("padded_image.png", imgpad)

Looks much better now




回答2:


The issue has been already addressed and solved here:

http://answers.opencv.org/question/90229/add-padding-to-object-in-4-channel-image/



来源:https://stackoverflow.com/questions/36044061/add-padding-to-object-in-4-channel-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!