簡體   English   中英

使用 cv2 提取圖像矩形

[英]image rectangle extraction with cv2

我在一張圖像上工作,我從中提取了邊緣,並在垂直和水平線上進行了形態學閉合。

我想只保留這張圖片中間的矩形:

![1]

我對如何做到這一點有點想法。 你能幫助我嗎?

您可以使用擴張關閉矩形中的間隙,然后尋找內部也有輪廓的最大輪廓。

矩形是最大的輪廓,但是找到最大的輪廓接縫太具體了。
為了概括解決方案,我建議尋找其中包含另一個輪廓的最大輪廓。
假設是矩形以其“子輪廓”來區分。

尋找孫子:
輪廓層次結構有點難以理解......
我們需要處理一個空輪廓由兩個輪廓組成的事實——外輪廓和內輪廓(內輪廓是外輪廓的子輪廓)。
我們需要尋找有孫子的輪廓,而不是尋找有孩子的輪廓。

您可以使用以下階段:

  • 使用“擴張”形態學操作來關閉矩形線條之間的間隙。
  • 查找輪廓和層次結構,使用 RETR_TREE 在輪廓內創建輪廓樹。
  • 按區域對輪廓(和層次結構)進行排序 - 按降序排序,以便最大的排在第一位。
  • 搜索具有孫輪廓的面積最大的輪廓。

這是一個代碼示例:

import numpy as np
import cv2

img = cv2.imread('rect_img.png', cv2.IMREAD_GRAYSCALE)  # Read input image as Grayscale
img = img[10:-10, 10:-10]  # Crop the margins
thresh = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU)[1]  # Convert to binary (the input image is not binary).

# Use "dilate" morphological operation for closing the gaps between the lines of the rectangle
thresh = cv2.dilate(thresh, np.ones((3,3)))

# Find contours and hierarchy, use RETR_TREE for creating a tree of contours within contours
cnts, hiers = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2:]  # [-2:] indexing takes return value before last (due to OpenCV compatibility issues).

hiers = hiers[0]  # Remove redundant dimensions of hierarchy

# Merge two lists to list of pairs (before sorting), cnts_hiers is [(c,h), (c,h), (c,h), ...]
# https://stackoverflow.com/questions/2407398/how-to-merge-lists-into-a-list-of-tuples
cnts_hiers = zip(cnts, hiers)

# Sort contours (and hierarchy) by area - the largest comes first.
cnts_hiers = sorted(cnts_hiers, key=lambda c: cv2.contourArea(c[0]), reverse=True)

# Iterate the sorted contours (and hierarchy):
# Look for contour with largest area that have a grandchild contour
# Note: we are looking for a grandchild because each empty contour has an inner contour and an outer contour.
for c_h in cnts_hiers:
    c = c_h[0]  # The first index of c_h is the contour
    h = c_h[1]  # The second index of c_h is the hierarchy of the contour

    # https://docs.opencv.org/master/d9/d8b/tutorial_py_contours_hierarchy.html
    # OpenCV represents hierarchy as an array of four values : [Next, Previous, First_Child, Parent]
    # If there is no child or parent, that field is taken as -1

    # Check if contour has at least one child contour, and than check if the child has a child (look for grandchild)
    if h[2] >= 0:
        child_idx = h[2]  # Get the index of the child (the child is the "inner contour").
        child_hier = hiers[child_idx]  # Get the hierarchy that applies the index of the child.

        # Check if the child has a child (look for grandchild)
        if child_hier[2] >= 0:
            best_cnt = c  # The best candidate contour was found.
            break  # Break the loop


img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)  # Convert to BGR before drawing the contour.

# Mark best_cnt with green line
cv2.drawContours(img, [best_cnt], 0, (0, 255, 0), 2)

cv2.imshow('img', img)  # Show result for testing
cv2.waitKey()
cv2.destroyAllWindows()

結果:
在此處輸入圖像描述


裁剪矩形:

rect = cv2.minAreaRect(best_cnt)  # Find rectangle with minimum area
box = cv2.boxPoints(rect)
box = np.int0(box) # convert all coordinates floating point values to int
(topy, topx) = (np.min(box[:,1]), np.min(box[:,0]))  # https://stackoverflow.com/questions/28759253/how-to-crop-the-internal-area-of-a-contour
(bottomy, bottomx) = (np.max(box[:,1]), np.max(box[:,0]))
rect = img[topy:bottomy+1, topx:bottomx+1, :]

結果:
在此處輸入圖像描述

暫無
暫無

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

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