簡體   English   中英

Python OpenCv 多個矩形的交集

[英]Python OpenCv intersection of multiple rectangles

我目前正在開展一個項目來識別圖像中的文本部分。 我在它們周圍畫了矩形,如下所示:

在此處輸入圖像描述

然后將它們切成每個矩形以對它們做更多的事情。 像這樣: 在此處輸入圖像描述

在此處輸入圖像描述

我不想要的是,如圖 2 所示,讓一個矩形的一部分成為另一個矩形的一部分,例如。 pic3 是 pic2 的一部分。 這意味着這些部分應該被剪掉或變成白色,我不知道該怎么做。 對於這些矩形的繪制,我使用以下代碼部分:

image = cv2.imread(Photopath)
CopyImg = np.copy(image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, ((1, 1)), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Create rectangular structuring element and dilate
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (6, 9))
dilate = cv2.dilate(thresh, kernel, iterations=4)

# Find contours and draw rectangle
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
    paragraph = CopyImg[y:y+h,x:x+w]

    cv2.imwrite(outpath, paragraph)
    

我想我需要以某種方式將它們相交並從一個矩形中切出與所有其他觸摸它的坐標的矩形?

這是未處理的圖像: 在此處輸入圖像描述

這是一種可能的方法。 首先,我將嘗試檢測每個文本塊 塊(或邊界框)是否重疊並不重要。 在獲取圖像上所有 blob 的所有邊界框后,我將檢測邊界框重疊 如果邊界框與其他邊界框重疊,這意味着相同的文本塊將在兩個或多個圖像之間共享。 我將裁剪該部分並用白色矩形填充重疊區域,這樣內容只會顯示在一張圖像上。

這些是重要的步驟:

  1. 使用形態來獲得漂亮的文本塊。

  2. 檢測這些塊上的輪廓並將這些輪廓轉換為邊界框

  3. 遍歷所有邊界框並:

    • 裁剪每個邊界框

    • 檢查可能的重疊 如果發現重疊(或相交),請使用邊界框信息在該區域上繪制一個白色矩形。

這是代碼,首先我們需要得到那些漂亮的文本塊:

import numpy as np
import cv2

# image path
path = "C:/opencvImages/"
fileName = "sheet05.png"

# Reading an image in default mode:
inputImage = cv2.imread(path + fileName)

# Some deep copies of the input mat:
inputCopy = inputImage.copy()
cleanInputCopy = inputCopy.copy()

# Grayscale conversion:
grayscaleImage = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)

# Thresholding:
threshValue, binaryImage = cv2.threshold(grayscaleImage, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
binaryImage = 255 - binaryImage

很標准的東西。 只需read圖像,將其轉換為grayscale並通過Otsu獲得二進制圖像。 您會注意到我創建了一些輸入的深層副本 這些主要用於可視化結果,因為我最初繪制了找到的每個bounding box和每個重疊區域。

應用一些非常強烈的形態來獲得最好的文本塊。 我在這里應用擴張 + 侵蝕,每個操作有 10 次迭代:

# Dilate and Erode with a big Structuring Element:
kernelSize = 5
structuringElement = cv2.getStructuringElement(cv2.MORPH_RECT, (kernelSize, kernelSize))
iterations = 10
dilatedImage = cv2.morphologyEx(binaryImage, cv2.MORPH_DILATE, structuringElement, None, None, iterations,
                                cv2.BORDER_REFLECT101)
erodedImage = cv2.morphologyEx(dilatedImage, cv2.MORPH_ERODE, structuringElement, None, None, iterations,
                               cv2.BORDER_REFLECT101)

最后一個片段為您提供此圖像:

現在,獲取該圖像的外輪廓並計算邊界框:

# Find the big contours/blobs on the filtered image:
contours, hierarchy = cv2.findContours(erodedImage, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)

contours_poly = [None] * len(contours)
boundRect = []

# Alright, just look for the outer bounding boxes:
for i, c in enumerate(contours):
    if hierarchy[0][i][3] == -1:
        contours_poly[i] = cv2.approxPolyDP(c, 3, True)
        boundRect.append(cv2.boundingRect(contours_poly[i]))

現在,重要的部分來了。 我們將遍歷每個bounding box 裁剪圖像,並檢查最近用於裁剪圖像的邊界bounding box是否在另一個bounding box (重疊)。 如果是這種情況,只需在該區域內繪制一個大的白色矩形並繼續進行新的裁剪:

# Loop thru all bounding boxes:
for i in range(len(boundRect)):

    # Get current boundRect:
    sourceRect = boundRect[i]

    # Crop the roi:
    croppedImg = cleanInputCopy[sourceRect[1]:sourceRect[1] + sourceRect[3],
                 sourceRect[0]:sourceRect[0] + sourceRect[2]]

    # Check against other bounded rects:
    for j in range(len(boundRect)):

        # Get target boundRect:
        targetRect = boundRect[j]

        # Check for intersections:
        if i != j:

            foundIntersect, overlappedRect = checkIntersection(sourceRect, targetRect)

            if foundIntersect:

                # Found some overlapped rects, draw white rectangle at this location:
                cv2.rectangle(cleanInputCopy, (int(overlappedRect[0]), int(overlappedRect[1])),
                              (int(overlappedRect[0] + overlappedRect[2]), int(overlappedRect[1] + overlappedRect[3])),
                              (255, 255, 2550), -1)

    cv2.rectangle(inputCopy, (int(boundRect[i][0]), int(boundRect[i][1])),
                  (int(boundRect[i][0] + boundRect[i][2]), int(boundRect[i][1] + boundRect[i][3])), color, 5)

這些是為每個二進制 blob 檢測到的邊界框:

該代碼檢測重疊區域並在交叉點上繪制一個白色矩形,這樣它將不再顯示在以下裁剪上:

這些是作物(請注意,這些是單獨的圖像):

現在,檢測邊界框交叉點的助手 function 是這樣的:

# Check for boxA and boxB intersection
def checkIntersection(boxA, boxB):
    
    x = max(boxA[0], boxB[0])
    y = max(boxA[1], boxB[1])
    w = min(boxA[0] + boxA[2], boxB[0] + boxB[2]) - x
    h = min(boxA[1] + boxA[3], boxB[1] + boxB[3]) - y

    foundIntersect = True
    if w < 0 or h < 0:
        foundIntersect = False

    return(foundIntersect, [x, y, w, h])

這非常簡單。 它只是獲取兩個邊界矩形的坐標並計算相交區域。 如果widthheight小於零,則沒有交集。

暫無
暫無

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

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