从图像中删除背景-Python

问题描述

我正在尝试使用OpenCV从图像中删除黑色背景,但无法删除像素以仅捕获没有黑色背景的主要图像。这是我正在使用的代码以及原始输入图像。

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('C:\\Users\\mdl518\\Desktop\\input.png')
mask = np.zeros(img.shape[:2],np.uint8)

bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,np.float64)

rect = (0,1035,932)  # image width/height re-formatted as (x,y,width,height)
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)

mask2 = np.where((mask==2)|(mask==0),1).astype('uint8')
img = img*mask2[:,:,np.newaxis]

plt.imshow(img)
plt.savefig('C:\\Users\\mdl518\\Desktop\\output.png')

Input Image

我实际上是在重新格式化此处概述的代码(https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_grabcut/py_grabcut.html),该代码说明了使用OpenCV进行最前沿的提取。但是,在保留输出图像中图像本身的完整性的同时,我仍然无法从输入图像中裁剪周围的背景像素。有没有更简单的方法可以做到这一点?我还尝试使用cv2.thresholding和轮廓来裁剪/删除背景,但仍然无法弄清楚。非常感谢您的协助!

解决方法

这是在Python / OpenCV中使背景透明的一种方法。

  • 阅读输入内容
  • 转换为灰色
  • 阈值
  • 应用形态学清洁异物
  • 获取外部轮廓
  • 找到最大的轮廓
  • 将轮廓绘制为白色,并在黑色背景上填充遮罩
  • 抗锯齿面具
  • 将其放入输入图像的Alpha通道中
  • 保存结果

输入:

enter image description here

import cv2
import numpy as np
import skimage.exposure

# load image
img = cv2.imread('aerial_image.jpg')

# convert to gray
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# threshold
thresh = cv2.threshold(gray,11,255,cv2.THRESH_BINARY)[1]

# apply morphology to clean small spots
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
morph = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel,borderType=cv2.BORDER_CONSTANT,borderValue=0)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,3))
morph = cv2.morphologyEx(morph,cv2.MORPH_CLOSE,cv2.MORPH_ERODE,borderValue=0)

# get external contour
contours = cv2.findContours(morph,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours,key=cv2.contourArea)

# draw white filled contour on black background as mas
contour = np.zeros_like(gray)
cv2.drawContours(contour,[big_contour],-1)

# blur dilate image
blur = cv2.GaussianBlur(contour,(5,5),sigmaX=0,sigmaY=0,borderType = cv2.BORDER_DEFAULT)

# stretch so that 255 -> 255 and 127.5 -> 0
mask = skimage.exposure.rescale_intensity(blur,in_range=(127.5,255),out_range=(0,255))

# put mask into alpha channel of input
result = cv2.cvtColor(img,cv2.COLOR_BGR2BGRA)
result[:,:,3] = mask

# save output
cv2.imwrite('aerial_image_thresh.png',thresh)
cv2.imwrite('aerial_image_morph.png',morph)
cv2.imwrite('aerial_image_contour.png',contour)
cv2.imwrite('aerial_image_mask.png',mask)
cv2.imwrite('aerial_image_antialiased.png',result)


# Display various images to see the steps
cv2.imshow('thresh',thresh)
cv2.imshow('morph',morph)
cv2.imshow('contour',contour)
cv2.imshow('mask',mask)
cv2.imshow('result',result)

cv2.waitKey(0)
cv2.destroyAllWindows()

阈值图像:

enter image description here

形态学清洁图像:

enter image description here

轮廓图片:

enter image description here

蒙版图像:

enter image description here

具有透明背景的结果:

enter image description here

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...