且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

从精巧边缘获取边界并删除图像背景

更新时间:2023-12-05 18:11:52

如果我理解正确,则希望删除背景并提取对象.除了使用Canny,还有另一种方法.由于您没有提供原始图像,因此我对您的图像进行了屏幕截图以用作输入.通常,有几种方法来获取用于边界提取的二进制图像.它们包括常规阈值,大津的阈值,自适应阈值和Canny边缘检测.在这种情况下,大津可能是***的,因为有背景噪音


首先我们将图像转换为灰度,然后执行Otsu的阈值以获得二进制图像

有不需要的部分,因此要移除它们,我们执行变形打开以分离关节

现在,关节已分离,我们找到轮廓并使用轮廓区域进行过滤.我们提取代表所需对象的最大轮廓,然后将该轮廓绘制到蒙版上

我们快到了,但是有瑕疵,所以我们变形以填补孔洞

接下来,我们按位排列-并带有原始图像

最后要获得所需的结果,我们将蒙版上所有黑色像素的颜色都变为白色

在这里,您可以使用Numpy切片来提取ROI,但我不确定您要做什么.我会留给你

  import cv2将numpy导入为np图片= cv2.imread("1.png")原始= image.copy()遮罩= np.zeros(image.shape,dtype = np.uint8)灰色= cv2.cvtColor(图像,cv2.COLOR_BGR2GRAY)阈值= cv2.threshold(灰色,0,255,cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]内核= cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))开头= cv2.morphologyEx(阈值,cv2.MORPH_OPEN,内核,迭代次数= 3)cnts = cv2.findContours(正在打开,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)如果len(cnts)== 2,则cnts = cnts [0]否则,cnts [1]cnts =排序(cnts,key = cv2.contourArea,reverse = True)对于C中的cnts:cv2.drawContours(mask,[c],-1,(255,255,255),-1)休息close = cv2.morphologyEx(mask,cv2.MORPH_CLOSE,内核,迭代次数= 4)关闭= cv2.cvtColor(关闭,cv2.COLOR_BGR2GRAY)结果= cv2.bitwise_and(原始,原始,掩码=关闭)result [close == 0] =(255,255,255)cv2.imshow('结果',结果)cv2.waitKey() 

I'm trying to remove the background of an image that im trying to train a neural network with. I've had little luck using the method described here (How do I remove the background from this kind of image?), but I have been able to use the Canny Edge Detector to get a semi-good "boundary" of the object in my image. Heres my code I'm running

import cv2 as cv, sys, numpy as np, PIL.Image, matplotlib.pylab as plt

# read command-line arguments
filename = '/Users/colew/Desktop/Good_Cups_Frames/frame_IMG_2057.MOV_0.jpg'

img = cv.imread(filename,0)
edges = cv.Canny(img,25,200)
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.savefig("pic")
plt.show()

and the resulting image(s) we get are

So what I'm looking for exactly is a way for me to get the boundaries of the canny edges and then from there, crop the original image around these boundaries. Thanks!

If I understand correctly, you want to remove the background and extract the object. Instead of using Canny, here's an alternative approach. Since you didn't provide an original image, I screenshotted your image to use as input. In general, there are several ways to obtain a binary image for boundary extraction. They include regular thresholding, Otsu's thresholding, Adaptive thresholding, and Canny edge detection. In this case, Otsu's is probably the best since there is background noise


First we convert the image to grayscale then perform Otsu's threshold to obtain a binary image

There are unwanted sections so to remove them, we perform a morph open to separate the joints

Now that the joints are separated, we find contours and filter using contour area. We extract the largest contour which represents the desired object then draw this contour onto a mask

We're almost there but there are imperfections so we morph close to fill the holes

Next we bitwise-and with the original image

Finally to get the desired result, we color in all black pixels on the mask to white

From here you could use Numpy slicing to extract the ROI but I'm not completely sure what you were trying to do. I'll leave that up to you

import cv2
import numpy as np

image = cv2.imread("1.png")
original = image.copy()
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=3)

cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
for c in cnts:
    cv2.drawContours(mask, [c], -1, (255,255,255), -1)
    break

close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=4)
close = cv2.cvtColor(close, cv2.COLOR_BGR2GRAY)
result = cv2.bitwise_and(original, original, mask=close)
result[close==0] = (255,255,255)

cv2.imshow('result', result)
cv2.waitKey()