问题
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