首页 > 解决方案 > 轮廓的坐标点

问题描述

我需要找到轮廓的边缘坐标。我试图通过使用 cv2.boundingRect 来弄清楚,但没有成功,因为它在 2D 中显示(我还没有尝试图像扭曲..)。我需要知道轮廓的 3D 坐标。

我的代码:

import cv2
# import numpy as np

while True:

    image = cv2.imread('box_2.jpg')

    img_dimension = image.shape

    print("Original image dimension : ", img_dimension)

    # Convert the image from colour to gray as 1st step to remove colour related noises...
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # Blur the image..
    blurred = cv2.GaussianBlur(gray, (9, 9), 0)
    # Perform Adaptive Threshold..
    threshold = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 15, 2)
    # Find Edge..
    edged = cv2.Canny(gray, 255, 512)
    # Dilate..
    # edged = cv2.dilate(edged, None)
    # Find Contours
    contours, hierarchy = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    cv2.b
    max_area = 0
    max_index = -1
    index = -1

    for i in contours:
        area = cv2.contourArea(i)
        index = index + 1
        if area > max_area:
            max_area = area
            max_index = index

    cv2.imshow('Canny Edges After Contouring', edged)
    print("Number of Contours found = " + str(len(contours)))
    print("Area :{}".format(area))

    cv2.drawContours(image, contours, max_index, (0, 255, 0), 2)
    cv2.imshow('Contours', image)

    k = cv2.waitKey(1)

    if k == 27:
        break

cv2.destroyAllWindows()

检测到的轮廓:

在此处输入图像描述

我在哪里可以找到这个?

谢谢

标签: pythonopencv

解决方案


您可以通过检测连接三个边的角的一个坐标来找到三个边,因为您已经有了其他六个角。

我选择解决这个问题的方法是,如果光源在盒子上方,盒子的顶面通常比侧面更亮。考虑到这一点,我们可以定义一个颜色遮罩,它可以遮盖除盒子颜色相对较亮的阴影之外的几乎所有内容。

有了顶面的轮廓,我们可以通过提取y坐标最大的坐标来找到角点。

  1. 导入必要的库:
import cv2
import numpy as np
  1. 定义一个接收图像的函数,并返回除盒子顶面外几乎所有遮罩的图像:
def get_masked(img):
    lower = np.array([90, 0, 40])
    upper = np.array([135, 255, 255])
    img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(img_hsv, lower, upper)
    return cv2.bitwise_and(img, img, mask=mask)
  1. 定义一个函数,该函数将接收蒙版图像,并对其进行处理以消除噪声和检测到的边缘:
def get_processed(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img_blur = cv2.GaussianBlur(img_gray, (5, 5), 1)
    return cv2.Canny(img_blur, 50, 50)
  1. 定义一个函数,该函数将返回具有最大面积的边缘图像的轮廓:
def get_contour(img):
    contours, hierarchies = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    return max(contours, key=cv2.contourArea)
  1. 利用我们在读入img变量的图像上定义的函数:
img = cv2.imread('box_2.jpg')
img_masked = get_masked(img)
img_processed = get_processed(img_masked)
  1. 从处理后的图像中获取轮廓,使用np.argmax方法提取y坐标最大的坐标,绘制到原图上:
cnt = get_contour(img_processed)
corner = cnt[np.argmax(cnt, 0)].squeeze()[1]
cv2.circle(img, tuple(corner), 4, (0, 255, 0), -1)
  1. 最后,显示图像:
cv2.imshow('Image', img)
cv2.waitKey(0)

输出:

在此处输入图像描述

共:

import cv2
import numpy as np

def get_masked(img):
    lower = np.array([90, 0, 40])
    upper = np.array([135, 255, 255])
    img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(img_hsv, lower, upper)
    return cv2.bitwise_and(img, img, mask=mask)

def get_processed(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img_blur = cv2.GaussianBlur(img_gray, (5, 5), 1)
    return cv2.Canny(img_blur, 50, 50)

def get_contour(img):
    contours, hierarchies = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    return max(contours, key=cv2.contourArea)

img = cv2.imread('box_2.jpg')
img_masked = get_masked(img)
img_processed = get_processed(img_masked)

cnt = get_contour(img_processed)
corner = cnt[np.argmax(cnt, 0)].squeeze()[1]
cv2.circle(img, tuple(corner), 4, (0, 255, 0), -1)

cv2.imshow('Image', img)
cv2.waitKey(0)

推荐阅读