向 4 通道图像中的对象添加填充
Add padding to object in 4-channel image
我有一张像这样的 4 通道图像(.png、.tif):
我正在使用 OpenCV,我想在花朵周围添加 BORDER_REFLECT
类型的填充。 copyMakeBorder
没有用,因为它会向图像的边缘添加填充。
如果我在 bgr + alpha 中拆分图像并在 bgr 图像上应用 dilate
和 BORDER_REFLECT
选项,我可以添加某些填充,但该解决方案破坏了花的所有像素。
有什么方法可以对二进制掩码定义的 ROI 执行选择性 BORDER_REFLECT
填充添加?
编辑:
我期望的结果是这样的(抱歉我用 GIMP 画得很快):
我画了两条黑线来分隔填充后的花的新旧轮廓,但当然这些线不应该出现在最终结果中。填充区域(两条黑线内)必须由花朵的镜像像素组成(我将其涂成黄色以使其易于理解)。
一个简单的 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)
这是结果
但这看起来不太像 'centered'。所以我修改了代码以在复制时检测和说明偏移量。
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)
现在看起来好多了
问题已在此处解决:
http://answers.opencv.org/question/90229/add-padding-to-object-in-4-channel-image/
我有一张像这样的 4 通道图像(.png、.tif):
我正在使用 OpenCV,我想在花朵周围添加 BORDER_REFLECT
类型的填充。 copyMakeBorder
没有用,因为它会向图像的边缘添加填充。
如果我在 bgr + alpha 中拆分图像并在 bgr 图像上应用 dilate
和 BORDER_REFLECT
选项,我可以添加某些填充,但该解决方案破坏了花的所有像素。
有什么方法可以对二进制掩码定义的 ROI 执行选择性 BORDER_REFLECT
填充添加?
编辑:
我期望的结果是这样的(抱歉我用 GIMP 画得很快):
我画了两条黑线来分隔填充后的花的新旧轮廓,但当然这些线不应该出现在最终结果中。填充区域(两条黑线内)必须由花朵的镜像像素组成(我将其涂成黄色以使其易于理解)。
一个简单的 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)
这是结果
但这看起来不太像 'centered'。所以我修改了代码以在复制时检测和说明偏移量。
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)
现在看起来好多了
问题已在此处解决:
http://answers.opencv.org/question/90229/add-padding-to-object-in-4-channel-image/