【问题标题】:Find contour of rectangle in object在对象中查找矩形的轮廓
【发布时间】:2019-02-03 21:58:51
【问题描述】:

我想找到物体内部矩形照片的轮廓。我尝试过使用 OpenCV 的角点检测功能,但无济于事。我还尝试使用findContours 查找所有轮廓,并过滤掉多于(或少于)4 个边缘的轮廓,但这也没有任何结果。

我在这里有一个sample scan

【问题讨论】:

  • 请编辑您的代码的最小完整可验证示例,将问题显示为您的问题 - 请参阅 https:www.stackoverflow.com/help/mcve
  • 给定输入图像的样本输出是什么?

标签: python opencv


【解决方案1】:

我有一个解决方案给你,但它涉及很多步骤。此外,它可能无法很好地概括。不过,它确实对您的形象非常有用。

首先制作灰度和阈值,然后使用 findContours 创建纸张区域的蒙版。该蒙版被反转并与原始图像组合,使黑边变白。在生成的图像上创建一个新的灰度和阈值,然后将其反转,以便 findContours 可以找到照片的暗像素。围绕最大轮廓的旋转框被选中,这就是您要寻找的区域。

我添加了一些额外的东西,你可能不需要,但可能会很方便:将透视扭曲应用于盒子,所以你想要的区域被制作成一个直的矩形。

发生了很多事情,因此我建议您花一些时间查看中间步骤,以了解会发生什么。

结果:

代码:

import numpy as np 
import cv2
# load image
image = cv2.imread('photo.jpg')
# resize to easily view on screen, remove for final processing
image = cv2.resize(image,None,fx=0.2, fy=0.2, interpolation = cv2.INTER_CUBIC)

### remove outer black edge
# create grayscale
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# perform threshold
retr , mask = cv2.threshold(gray_image, 190, 255, cv2.THRESH_BINARY)
# remove noise
kernel =  np.ones((5,5),np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
# create emtpy mask
mask_2 = np.zeros(image.shape[:3], dtype=image.dtype)
# find contours
ret, contours, hier = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# draw the found shapes (white, filled in ) on the empty mask
for cnt in contours:
    cv2.drawContours(mask_2, [cnt], 0, (255,255,255), -1)

# invert mask and combine with original image - this makes the black outer edge white
mask_inv_2 = cv2.bitwise_not(mask_2)
tmp = cv2.bitwise_or(image, mask_inv_2)

### Select photo - not inner edge
# create grayscale
gray_image2 = cv2.cvtColor(tmp, cv2.COLOR_BGR2GRAY)
# perform threshold
retr, mask3 = cv2.threshold(gray_image2, 190, 255, cv2.THRESH_BINARY)
# remove noise
maskX = cv2.morphologyEx(mask3, cv2.MORPH_CLOSE, kernel)
# invert mask, so photo area can be found with findcontours
maskX = cv2.bitwise_not(maskX)
# findcontours
ret, contours2, hier = cv2.findContours(maskX, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# select the largest contour
largest_area = 0
for cnt in contours2:
    if cv2.contourArea(cnt) > largest_area:
        cont = cnt
        largest_area = cv2.contourArea(cnt)

# find the rectangle (and the cornerpoints of that rectangle) that surrounds the contours / photo
rect = cv2.minAreaRect(cont)
box = cv2.boxPoints(rect)
box = np.int0(box)
print(rect)

#### Warp image to square
# assign cornerpoints of the region of interest
pts1 = np.float32([box[1],box[0],box[2],box[3]])
# provide new coordinates of cornerpoints
pts2 = np.float32([[0,0],[0,450],[630,0],[630,450]])

# determine and apply transformationmatrix
M = cv2.getPerspectiveTransform(pts1,pts2)
result = cv2.warpPerspective(image,M,(630,450))

#draw rectangle on original image
cv2.drawContours(image, [box], 0, (255,0,0), 2)

#show image
cv2.imshow("Result", result)
cv2.imshow("Image", image)

cv2.waitKey(0)
cv2.destroyAllWindows()

【讨论】:

    猜你喜欢
    • 2021-06-08
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多