到目前为止我尝试过使用OpenCV获取边缘 代码:
def autocrop(image, threshold=0):
"""Crops any edges below or equal to threshold
Crops blank image to 1x1.
Returns cropped image.
"""
if len(image.shape) == 3:
flatImage = np.max(image, 2)
else:
flatImage = image
assert len(flatImage.shape) == 2
rows = np.where(np.max(flatImage, 0) > threshold)[0]
if rows.size:
cols = np.where(np.max(flatImage, 1) > threshold)[0]
image = image[cols[0]: cols[-1] + 1, rows[0]: rows[-1] + 1]
else:
image = image[:1, :1]
return image
no_border = autocrop(new_image)
cv2.imwrite('no_border.png',no_border)
结果是这个图像,接下来如何删除那些框
更新:
我发现该解决方案适用于白色背景,但是当我更改背景时,颜色边框不会被删除
被修改
我已尝试过此图片的解决方案
但结果是这样的
如何完全删除边界框。
答案 0 :(得分:5)
为此,我们使用floodFill
函数。
import cv2
import numpy as np
if __name__ == '__main__':
# read image and convert to gray
img = cv2.imread('image.png',cv2.IMREAD_UNCHANGED)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold the gray image to binarize, and negate it
_,binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
binary = cv2.bitwise_not(binary)
# find external contours of all shapes
_,contours,_ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# create a mask for floodfill function, see documentation
h,w,_ = img.shape
mask = np.zeros((h+2,w+2), np.uint8)
# determine which contour belongs to a square or rectangle
for cnt in contours:
poly = cv2.approxPolyDP(cnt, 0.02*cv2.arcLength(cnt,True),True)
if len(poly) == 4:
# if the contour has 4 vertices then floodfill that contour with black color
cnt = np.vstack(cnt).squeeze()
_,binary,_,_ = cv2.floodFill(binary, mask, tuple(cnt[0]), 0)
# convert image back to original color
binary = cv2.bitwise_not(binary)
cv2.imshow('Image', binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
答案 1 :(得分:2)
还有另一个可以找到图像中的字符。这在轮廓中使用层次结构的概念。
实现在python中:
path = r'C:\Desktop\Stack'
filename = '2.png'
img = cv2.imread(os.path.join(path, filename), 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
_, contours2, hierarchy2 = cv2.findContours(binary, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
请注意,cv2.findContours()
函数在RETR_CCOMP
参数中传递,以根据不同的层次结构级别存储轮廓。当一个轮廓位于另一个轮廓内时,层次结构非常有用,从而实现了父子关系。 RETR_CCOMP
有助于确定这种关系。
img2 = img.copy()
l = []
for h in hierarchy2[0]:
if h[0] > -1 and h[2] > -1:
l.append(h[2])
在上面的代码段中,我将所有有孩子的轮廓传递到列表l
中。使用l
我在下面的代码段中绘制了这些轮廓。
for cnt in l:
if cnt > 0:
cv2.drawContours(img2, [contours2[cnt]], 0, (0,255,0), 2)
cv2.imshow('img2', img2)
查看DOCUMENTATION HERE以了解有关轮廓中层次结构的更多信息。