python - 轮廓的坐标点
问题描述
我需要找到轮廓的边缘坐标。我试图通过使用 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()
检测到的轮廓:
我在哪里可以找到这个?
谢谢
解决方案
您可以通过检测连接三个边的角的一个坐标来找到三个边,因为您已经有了其他六个角。
我选择解决这个问题的方法是,如果光源在盒子上方,盒子的顶面通常比侧面更亮。考虑到这一点,我们可以定义一个颜色遮罩,它可以遮盖除盒子颜色相对较亮的阴影之外的几乎所有内容。
有了顶面的轮廓,我们可以通过提取y坐标最大的坐标来找到角点。
- 导入必要的库:
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
变量的图像上定义的函数:
img = cv2.imread('box_2.jpg')
img_masked = get_masked(img)
img_processed = get_processed(img_masked)
- 从处理后的图像中获取轮廓,使用
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)
- 最后,显示图像:
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)
推荐阅读
- html - Flutter:FormatException:意外字符(在字符1处)HTML
- flutter - Flutter BoxShadow 重叠兄弟
- tensorflow - 当最小化损失时,变量 ['Variable:0'] 不存在张量流梯度
- spring-boot - Spring-Boot-Maven-Plugin 问题“无法转移”
- kubernetes - 如何在 azure devops 上运行启动 kubernetes 集群的脚本
- keycloak - View-users 权限只查看部分用户
- webpack - 如何解决 Create-React-app 项目中的块加载错误?
- python - 如何捕捉终端输出?
- c++ - 我在使用运算符重载时得到垃圾值
- c# - C# 9.0 源代码生成器 - 忽略具有特定属性的类编译