opencv 识别长方形,如何识别openCV中不完整的矩形

How would I go around identifying and extracting rectangles from an image such as the one shown below.

Note that my rectangles might be incomplete and have some missing edges and some sides might be partial lines.

Thanks !

27d038f0fd1449cbd11fe0b8b43b3418.png

解决方案

This can be solved using morphological operations such as eroding and dilating. This two operations will help creating closed rectangles.

After that you can use the tutorial from this page to detect simple shapes such as rectangles.

I implemented a quick demo which worked for the image you provided.

main.py:

import cv2

import numpy as np

from shapeDetector import ShapeDetector

import imutils

img = cv2.imread('t.png')

kernel = np.ones((5,5),np.uint8)

erosion = cv2.erode(img,kernel,iterations = 10)

dilate = cv2.dilate(erosion,kernel,iterations = 10)

The erosion thickens all the lines, so to get back to a normal width we need to dilate after eroding. I recommend to comment the dilate operation once to see how erode works and vice versa.

This operations will transform your image like this b5e82bb3180b99aa527a4a37b9417667.png

The detection algorithm I used expects white lines on black background.

Thats why we need to invert the image.

cv2.bitwise_not ( dilate, dilate )

After that, we can use the code from the tutorial.

image = dilate

resized = imutils.resize(image, width=300)

ratio = image.shape[0] / float(resized.shape[0])

# convert the resized image to grayscale, blur it slightly,

# and threshold it

gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)

blurred = cv2.GaussianBlur(gray, (5, 5), 0)

thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]

#thresh = dilate

# find contours in the thresholded image and initialize the

# shape detector

cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,

cv2.CHAIN_APPROX_SIMPLE)

cnts = cnts[0] if imutils.is_cv2() else cnts[1]

sd = ShapeDetector()

# loop over the contours

for c in cnts:

# compute the center of the contour, then detect the name of the

# shape using only the contour

M = cv2.moments(c)

cX = int((M["m10"] / M["m00"]) * ratio)

cY = int((M["m01"] / M["m00"]) * ratio)

shape = sd.detect(c)

# multiply the contour (x, y)-coordinates by the resize ratio,

# then draw the contours and the name of the shape on the image

c = c.astype("float")

c *= ratio

c = c.astype("int")

cv2.drawContours(image, [c], -1, (0, 255, 0), 2)

cv2.putText(image, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,

0.5, (255, 255, 255), 2)

# show the output image

cv2.imshow("Image", image)

cv2.waitKey(0)

shapeDetector.py:

# import the necessary packages

import cv2

class ShapeDetector:

def __init__(self):

pass

def detect(self, c):

# initialize the shape name and approximate the contour

shape = "unidentified"

peri = cv2.arcLength(c, True)

approx = cv2.approxPolyDP(c, 0.04 * peri, True)

# if the shape is a triangle, it will have 3 vertices

if len(approx) == 3:

shape = "triangle"

# if the shape has 4 vertices, it is either a square or

# a rectangle

elif len(approx) == 4:

# compute the bounding box of the contour and use the

# bounding box to compute the aspect ratio

(x, y, w, h) = cv2.boundingRect(approx)

ar = w / float(h)

# a square will have an aspect ratio that is approximately

# equal to one, otherwise, the shape is a rectangle

shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"

# if the shape is a pentagon, it will have 5 vertices

elif len(approx) == 5:

shape = "pentagon"

# otherwise, we assume the shape is a circle

else:

shape = "circle"

# return the name of the shape

return shape

Result:

fe972103cec37b640ab816736ab8584a.png

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV是一个强大的计算机视觉库,它提供了丰富的功能来处理图像和视频。在OpenCV识别长方形通常涉及到图像处理和形状检测。以下是一个基本步骤: 1. **读取和预处理图像**:首先,使用`cv2.imread()`加载图片,并可能对图像进行灰度化、平滑等预处理操作以提高检测精度。 2. **边缘检测或轮廓检测**:可以使用Canny边缘检测(`cv2.Canny()`)或轮廓检测(`cv2.findContours()`)来识别图像的边界线或形状。 3. **寻找矩形**:找到轮廓后,可以使用`cv2.boundingRect()`函数,这个函数返回每个轮廓的最小矩形包围盒。它会返回矩形的(x, y)坐标(左上角)、宽度(w)和高度(h)。 4. **过滤和验证**:根据需要,可以进一步过滤结果,例如检查矩形的尺寸是否合理(避免噪声或非常小的矩形被认为是长方形),以及矩形与图像内容的相关性。 5. **绘制结果**:最后,用`cv2.rectangle()`在原图上画出识别长方形区域。 以下是一个简单的Python示例代码片段: ```python import cv2 def detect_rectangle(image_path): # 读取图片 img = cv2.imread(image_path) # 转为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 边缘检测 edges = cv2.Canny(gray, 50, 150) # 寻找轮廓 contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 遍历轮廓并识别矩形 rectangles = [] for contour in contours: x, y, w, h = cv2.boundingRect(contour) if w > h and w > 30: # 过滤过小或不符合长方形比例的轮廓 rectangles.append(((x, y), (x+w, y+h))) # 在原图上标注识别矩形 for rect in rectangles: cv2.rectangle(img, rect, rect, (0, 255, 0), 2) # 显示结果 cv2.imshow('Rectangle Detection', img) cv2.waitKey(0) cv2.destroyAllWindows() detect_rectangle('your_image.jpg') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值