在4通道图像中为对象添加填充

时间:2016-03-16 18:29:18

标签: image opencv image-processing padding roi

我有一个像这样的4通道图像(.png,.tif):

enter image description here

我正在使用OpenCV,我想在花朵周围添加BORDER_REFLECT类型的填充。 copyMakeBorder没用,因为它会在图像的边缘添加填充。

如果我将图像拆分为bgr + alpha并在bgr图像上应用带有dilate选项的BORDER_REFLECT,我可以添加某些填充,但该解决方案会破坏花的所有像素。

有没有办法在二进制掩码定义的ROI上执行选择性BORDER_REFLECT填充添加?

编辑:

我期望的结果是(对不起,我很快就用GIMP绘制了它):

enter image description here

我画了两条黑线来划定旧的&填充后花的新轮廓,但当然这些线不应出现在最终结果中。填充区域(在两条黑线内)必须由花中的镜像像素组成(我将其涂成黄色以使其易于理解)。

2 个答案:

答案 0 :(得分:2)

一个简单的python脚本来调整图像大小并将原件复制到放大的图像上就可以了。

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)

结果如下

enter image description here

但这看起来并不是非常“集中”。所以我修改了代码以便在复制时检测和计算偏移量。

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)

现在看起来好多了

enter image description here

答案 1 :(得分:0)