问题描述
我正在尝试使用OpenCV从图像中删除黑色背景,但无法删除像素以仅捕获没有黑色背景的主要图像.这是我正在使用的代码以及原始输入图像.
将numpy导入为np导入cv2从matplotlib导入pyplot作为pltimg = cv2.imread('C:\\ Users \\ mdl518 \\ Desktop \\ input.png')遮罩= np.zeros(img.shape [:2],np.uint8)bgdModel = np.zeros((1,65),np.float64)fgdModel = np.zeros((1,65),np.float64)rect =(0,0,1035,932)#图像宽度/高度重新格式化为(x,y,width,height)cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)mask2 = np.where(((mask == 2)|(mask == 0),0,1).astype('uint8')img = img * mask2 [:,:,np.newaxis]plt.imshow(img)plt.savefig('C:\\ Users \\ mdl518 \\ Desktop \\ output.png')
我实际上是在重新格式化此处概述的代码(
import cv2将numpy导入为np导入skimage.exposure#加载图片img = cv2.imread('aerial_image.jpg')#转换为灰色灰色= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)# 临界点thresh = cv2.threshold(灰色,11,255,cv2.THRESH_BINARY)[1]#应用形态学清洁小斑点内核= cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))morph = cv2.morphologyEx(阈值,cv2.MORPH_OPEN,内核,borderType = cv2.BORDER_CONSTANT,borderValue = 0)内核= cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))形态= cv2.morphologyEx(形态,cv2.MORPH_CLOSE,内核,borderType = cv2.BORDER_CONSTANT,borderValue = 0)内核= cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))变形= cv2.morphologyEx(变形,cv2.MORPH_ERODE,内核,borderType = cv2.BORDER_CONSTANT,borderValue = 0)#获取外部轮廓等高线= cv2.findContours(morph,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)轮廓=轮廓[0]如果len(contours)== 2,则轮廓[1]big_contour = max(轮廓,键= cv2.contourArea)#在黑色背景上绘制白色填充轮廓作为mas等高线= np.zeros_like(灰色)cv2.drawContours(轮廓,[big_contour],0,255,-1)#模糊扩张图像blur = cv2.GaussianBlur(轮廓,(5,5),sigmaX = 0,sigmaY = 0,borderType = cv2.BORDER_DEFAULT)#拉伸至255->255和127.5->0遮罩= skimage.exposure.rescale_intensity(模糊,in_range =(127.5,255),out_range =(0,255))#将遮罩放入输入的Alpha通道结果= cv2.cvtColor(img,cv2.COLOR_BGR2BGRA)result [:,:,3] =遮罩#保存输出cv2.imwrite('aerial_image_thresh.png',脱粒)cv2.imwrite('aerial_image_morph.png',变形)cv2.imwrite('aerial_image_contour.png',轮廓)cv2.imwrite('aerial_image_mask.png',遮罩)cv2.imwrite('aerial_image_antialiased.png',结果)#显示各种图像以查看步骤cv2.imshow('thresh',thresh)cv2.imshow('变体',变体)cv2.imshow('轮廓',轮廓)cv2.imshow('遮罩',遮罩)cv2.imshow('结果',结果)cv2.waitKey(0)cv2.destroyAllWindows()
阈值图像:
形态学清洁图像:
轮廓图片:
蒙版图像:
具有透明背景的结果:
I am trying to remove the black background from an image using OpenCV, but I am unable to remove the pixels to capture just the main imagery without the black background. Here is the code I am using, along with the original input image.
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,65),np.float64)
rect = (0,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),0,1).astype('uint8')
img = img*mask2[:,:,np.newaxis]
plt.imshow(img)
plt.savefig('C:\\Users\\mdl518\\Desktop\\output.png')
I am essentially re-formatting the code outlined here (https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_grabcut/py_grabcut.html) that illustrates forefront extraction using OpenCV. However, I am still unable to crop the surrounding background pixels from the input image while preserving the integrity of the image itself in the output image. Is there an easier way to go about this? I also tried to crop/remove the background using cv2.thresholding and contours but still couldn't figure it out. Any assistance is most appreciated!
Here is one approach to make your background transparent in Python/OpenCV.
- Read the input
- Convert to gray
- Threshold
- Apply morphology to clean extraneous spots
- Get external contours
- Find the largest contour
- Draw the contour as white filled on a black background as a mask
- Antialias the mask
- Put that into the alpha channel of the input image
- Save the result
Input:
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,3))
morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel, borderType=cv2.BORDER_CONSTANT, borderValue=0)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
morph = cv2.morphologyEx(morph, cv2.MORPH_ERODE, kernel, borderType=cv2.BORDER_CONSTANT, 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], 0, 255, -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()
Threshold image:
Morphology cleaned image:
Contour image:
Mask image:
Result with transparent background:
这篇关于从图像中删除背景-Python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!