OpenCV - 在 Python 中估算框尺寸

OpenCV - Estimating Box dimensions in Python

这是我的 的延续。我现在有这样一张图片

这里检测到了角点。现在我正在尝试估计较大盒子的尺寸,而较小的黑盒子尺寸是已知的。

谁能指导我估算盒子尺寸的最佳方法是什么?我可以用简单的欧氏距离来做,但我不知道这是否是正确的方法。或者即使它是正确的方法,那么从元组列表(坐标)中我如何找到像 A-B 或 A-D 或 G-H 而不是像 A-C 或 A-F 的距离?

必须保留顺序才能获得正确的尺寸。另外,我这里有两个框,所以当我创建角坐标列表时,它应该包含 A-J 的所有坐标,但我不知道哪个坐标属于哪个框。那么我如何为两个不同的盒子保留它,因为我想 运行 此代码以获得更多相似的图像。

注意:此图像中的角点不是单个点,而是一组点,因此我将角点集聚类并平均它们以获得每个角点的单个 (x,y) 坐标。

我已尽力解释我的问题。会非常高兴得到一些答案:) 谢谢。

一般来说你不能,因为任何重建都是按比例进行的。

基本上,给定一个校准的相机和 6 个 2D 点 (6x2=12),你想要找到 6 个 3D 点 + 比例 = 6x3+1=19。方程式不足。

为此,您必须做出一些假设并将其代入方程式。

表格示例:

  1. 盒子的边相互垂直(也就是说每2个相邻的点至少共享一个坐标值)
  2. 您需要假设您知道底部点的高度,即它们与您的校准框在同一平面上(这将为您提供可见底部点的 Z)。

希望这些约束足以给你更少的未知方程,你可以求解线性方程组。

为了

How can I find distances like A-B or A-D or G-H but not like A-C or A-F

部分

这是一个快速代码,对于有很多角的图像效率不高,但对于您的情况来说没问题。这个想法是从你在另一个问题中得到的扩张边缘图像开始的(只有大盒子,但这个想法对于也有小盒子的图像是一样的)

然后,对于每一种可能的角组合,您都可以查看它们之间假想线上的几个点,然后检查这些点是否确实落在图像中的一条实线上。

import cv2
import numpy as np

#getting intermediate points on the line between point1 and point2
#for example, calling this function with (p1,p2,3) will return the point
#on the line between p1 and p2, at 1/3 distance from p2
def get_intermediate_point(p1,p2,ratio):
    return [p1[0]+(p2[0]-p1[0])/ratio,p1[1]+(p2[1]-p1[1])/ratio]

#open dilated edge images
img=cv2.imread(dilated_edges,0)

#corners you got from your segmentation and other question
corners=[[29,94],[102,21],[184,52],[183,547],[101,576],[27,509]]
nb_corners=len(corners)

#intermediate points between corners you are going to test
ratios=[2,4,6,8] #in this example, the middle point, the quarter point, etc
nb_ratios=len(ratios)

#list which will contain all connected corners
connected_corners=[]

#double loop for going through all possible corners
for i in range(nb_corners-1):
    for j in range(i+1,nb_corners):
        cpt=0
        c1=corners[i]; c2=corners[j]

        #testing every intermediate points between the selected corners
        for ratio in ratios:
            p=get_intermediate_point(c1,c2,ratio)

            #checking if these points fall on a white pixel in the image
            if img[p[0],p[1]]==255:
                cpt+=1

        #if enough of the intermediate points fall on a white pixel
        if cpt>=int(nb_ratios*0.75):
            #then we assume that the 2 corners are indeed connected by a line
            connected_corners.append([i,j])

print(connected_corners)