我正在开发一个大项目,我们需要将 Java 项目上的 openCV 从 3.2 升级到 4.6。
使用完全相同的图像,我得到了相反的结果:
获取轮廓:
matOfPoint = contours.get(i);
MatOfPoint2f contour2f = new MatOfPoint2f(matOfPoint.toArray());
RotatedRect rotatedRect = Imgproc.minAreaRect(contour2f);
我的openCV 3.2版本的rotatedRect结果是:
{{485.0001220703125, 641.5073852539062} 793x23 * -0.5055378675460815}}
在 4.6 版本中:
{{485.0000915527344, 641.5073852539062} 23x793 * 89.49445343017578}}
为什么WIDTH、HEIGHT和ANGLES是倒置的?
此后我进行了一堆计算,我想避免对它们进行太多更改。
不同结果的原因需要一些考古学才能找到。 OpenCV 3.2 已经很老了。从那时起,OpenCV 的许多内部结构可能已经得到了改进。我认为文档没有指定角度范围或宽度和高度之间的关系。有人改变实施细节是可以接受的。
忽略从第三位或第四位小数开始的差异,这两种表示方式是 等价:
{{485.0001220703125, 641.5073852539062} 793x23 * -0.5055378675460815}}
{{485.0000915527344, 641.5073852539062} 23x793 * 89.49445343017578}}
(-0.5055) % 90 = 89.4945
90 度是四分之一圈。四分之一圈相当于交换宽度和高度。
如果您需要它们的某种规范形式,请交换大小并将角度调整为正且小于 90 度。
或者更好,因为对于角度接近 0 度的盒子来说,这可能会抖动:将角度规范化在 -45 到 +45 度之间。如果您期望主要是轴对齐的对象,那么这样做是有意义的。
伪代码/Python:
old_angle = np.linspace(-90, +90, 7)
temp = old_angle + 45
quarter_turns = temp // 90 # division and floor
new_angle = temp % 90 - 45
# array([-90., -60., -30., 0., 30., 60., 90.]) # old_angle
# array([ -1., -1., 0., 0., 0., 1., 1.]) # quarter_turns
# array([ 0., 30., -30., 0., 30., -30., 0.]) # new_angle
...
if quarter_turns % 2 != 0: # single angle, not array
height, width = width, height