簡體   English   中英

使用輪廓層次結構的python opencv裁剪

[英]python opencv crop using contour hierarchy

我想從下面的圖像中刪除邊框 在此輸入圖像描述

我到目前為止嘗試使用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)

結果是這個圖像,接下來如何刪除這些框

在此輸入圖像描述

更新:

我發現該解決方案適用於白色背景,但是當我更改背景顏色邊框時,不會刪除

在此輸入圖像描述

編輯

我試過這個圖像的解決方案

在此輸入圖像描述

但結果是這樣的

在此輸入圖像描述

如何實現完全刪除邊界框。

為此,我們使用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()

結果

還有另一個可以找到圖像中的字符。 這使用輪廓中的層次結構的概念。

實現是在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以了解有關等高線輪廓的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM