繁体   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