找到旋转矩形的中点

Finding the midpoint of the rotated rectangle

我想找到旋转矩形的中点。旋转后的矩形坐标如下

[[317, 80], [183, 291], [479, 150], [378, 387]]

我得到以下代码来判断

cx = (coord[0][0] + coord[2][0])//2
cy = (coord[0][1] + coord[1][1])//2

不幸的是,该中心与实际中心不符。如何找到上述坐标的准确中心?

矩形的质心是任一对角线的中点。您对两个坐标计算使用了不同的点对。另请注意,由于某种原因,这些点 而不是 通常的相邻顺序。对角线是点 1 和 2、0 和 3。使用任一对,例如:

# Variables to make the computations easier to read
pt1 = 1
pt2 = 2
x = 0
y = 1
cx = (coord[pt1][x] + coord[pt2][x])//2
cy = (coord[pt1][y] + coord[pt2][y])//2

更好的是,研究一些简单的形状模块。其中大部分都有一个简单的 midpoint 方法。

您可以使用 cv2.minAreaRect 找到旋转矩形的中点(质心)。函数returns以下信息:

(centroid, (width, height), angle) = cv2.minAreaRect(cnts)

这是一个简单的例子。输入图像:

质心以绿色突出显示的结果

坐标

(157.6988067626953, 132.07565307617188)

代码

import cv2
import numpy as np

# Load image, grayscale, Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Find contours and find centroid information on rotated rectangle
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
centroid, dimensions, angle = cv2.minAreaRect(cnts[0])
cv2.circle(image, (int(centroid[0]), int(centroid[1])), 5, (36,255,12), -1)

print(centroid)

cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()

有几个问题。

1.) 点的排序不正确,您的公式无法正常工作。我想它们应该这样排序:(点应该这样排序,在列表中相邻的两个点和列表中的最后一个和第一个条目之间有一条矩形线)

points = [[183, 291], [378, 387], [479, 150], [317, 80]]

2.) 你的公式有误。 (我想公式应该是找到一条线的中点,或者在这种情况下是点 0 和点 2 之间对角线的中点)。

应该是

cx = (coord[idx1][0] + coord[idx2][0]) / 2
cy = (coord[idx1][1] + coord[idx2][1]) / 2

where idx1, idx2 are either 0,2 or 1,3

对于一个矩形cx,无论你使用idx1=0,idx2=2还是idx1=1,idx2=3,cy都是一样的

3.) 此公式(对角线的中点)仅确定矩形的质心。你得到的是一个四边形,它几乎但不完全是一个矩形,所以这个公式根本不适用。

尝试使用 idx1、idx2 = 0、2 和 idx1、idx2 = 1、3 计算 cx、cy 你看,你会得到不同的结果。因此你没有矩形。

您发布的坐标可能有错别字,或者计算矩形的公式有误,或者您的问题实际上是为了计算四边形的质心,这是不同的。 在这种情况下,建议修改问题的标题

您可以在此处找到多边形的公式https://en.wikipedia.org/wiki/Centroid#Of_a_polygon

伙计,我不确定我是不是跟着你,但是如果你想计算一个矩形的质心,它是这样的。假设您有以下与原点对齐的矩形。质心显示为绿色。

质心计算如下:

Cx = 0.5 * w
Cy = 0.5 * h

然后您可以应用线性变换。在这个例子中,一个旋转矩阵,给出为:

R = [ cos ϴ, -sin ϴ
      sin ϴ,  cos ϴ ]

矩形现在从原始坐标系旋转。那就是角度 ϴ:

质心方程变为:

Cx’ = cx cos ϴ - cy sin ϴ
Cy’ = cx sin ϴ + cy cos ϴ

转换回原坐标系,我们有:

Cx’’ = x + cx cos ϴ - cy sin ϴ
Cy’’ = y + cx sin ϴ + cy cos ϴ

函数应该是这样的(伪代码):

Tuple computeRotatedCentroid( x, y, width, height, theta ) {
    cx = 0.5 * width;
    cy = 0.5 * height;

    thetaRadians = degreesToRadians(theta);

    cosTheta = cos( thetaRadians );
    sinTheta = sin( thetaRadians );

    finalCx = x + cx * cosTheta - cy * sinTheta;
    finalCy = y + cx * sinTheta + cy * cosTheta;

    return makeTuple( finalCx, finalCy );
}