gpt4 book ai didi

opencv - arcLength() 和 contourArea() 返回意外值

转载 作者:太空宇宙 更新时间:2023-11-03 21:18:44 25 4
gpt4 key购买 nike

我正在尝试测量等高线的长度:

enter image description here

绿线是在轮廓上计算的 HoughLineP。通过计算绿线上的欧氏距离,我得到 153.88。然而,轮廓上的 arcLength() 给出了 364.71,而它应该比 HoughLineP 长大约 1/8。为什么 arcLength() 返回的长度几乎是轮廓长度的两倍?这是我的代码:

def euclid_distance(line):
dx = line[0] - line[2]
dy = line[1] - line[3]
return math.sqrt(dx*dx + dy*dy)

_, contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contour = contours[1]
cnt_perimeter = cv2.arcLength(contour, False)

lines_p = cv2.HoughLinesP(mat_cnt, 1, np.pi/180, 30, minLineLength=10, maxLineGap=5)

line_dist = 0
for lp in lines_p:
for l in lp:
x1,y1,x2,y2 = l
cv2.line(mat_cnt,(x1,y1),(x2,y2),(0,200,0),2)
line_dist += euclid_distance(l)
print cnt_perimeter, line_dist, contour.size
--
364.710676908 153.883072493 204

编辑:

这是原始轮廓:

enter image description here

以下是要点:

[[[386, 477]], [[385, 478]], [[378, 478]], [[377, 479]], [[373, 479]], [[372, 480]], [[368, 480]], [[367, 481]], [[361, 481]], [[360, 482]], [[355, 482]], [[354, 483]], [[348, 483]], [[347, 484]], [[342, 484]], [[341, 485]], [[336, 485]], [[335, 486]], [[329, 486]], [[328, 487]], [[324, 487]], [[323, 488]], [[317, 488]], [[316, 489]], [[311, 489]], [[310, 490]], [[306, 490]], [[305, 491]], [[299, 491]], [[298, 492]], [[293, 492]], [[292, 493]], [[287, 493]], [[286, 494]], [[279, 494]], [[278, 495]], [[275, 495]], [[274, 496]], [[269, 496]], [[268, 497]], [[263, 497]], [[262, 498]], [[255, 498]], [[254, 499]], [[249, 499]], [[248, 500]], [[241, 500]], [[240, 501]], [[220, 501]], [[219, 502]], [[216, 502]], [[219, 502]], [[220, 501]], [[240, 501]], [[241, 500]], [[248, 500]], [[249, 499]], [[254, 499]], [[255, 498]], [[262, 498]], [[263, 497]], [[268, 497]], [[269, 496]], [[274, 496]], [[275, 495]], [[278, 495]], [[279, 494]], [[286, 494]], [[287, 493]], [[292, 493]], [[293, 492]], [[298, 492]], [[299, 491]], [[305, 491]], [[306, 490]], [[310, 490]], [[311, 489]], [[316, 489]], [[317, 488]], [[323, 488]], [[324, 487]], [[328, 487]], [[329, 486]], [[335, 486]], [[336, 485]], [[341, 485]], [[342, 484]], [[347, 484]], [[348, 483]], [[354, 483]], [[355, 482]], [[360, 482]], [[361, 481]], [[367, 481]], [[368, 480]], [[372, 480]], [[373, 479]], [[377, 479]], [[378, 478]], [[385, 478]], [[386, 477]], [[390, 477]]]

顺便说一句,返回的轮廓区域是 0.0 使用下面的代码:

approx = cv2.approxPolyDP(contour, 5, True)
print cv2.contourArea(approx)
---
0.0

轮廓面积怎么这么小?直线部分已经是154(HoughLineP的长度)。

最佳答案

首先让我们把这个问题做一个简单的测试:

让我们创建一条直线并计算欧氏距离和弧长。

import cv2
import numpy as np

a = np.array([(1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7)])

cv2.arcLength(a, False) # Prints 8.485281229019165
math.sqrt((7-1) * (7-1) + (7-1) * (7-1)) # prints 8.48528137423857

它们都(几乎)相等....

那么,有什么问题吗?我唯一的解释是你的点不按顺序或几乎不按顺序。

例如,让我们将上一个示例中的行中的点 (0,0) 添加到数组的末尾。

a = np.array([(1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (0,0)])
cv2.arcLength(a, False) # prints 18.38477635383606
math.sqrt((7-0) * (7-0) + (7-0) * (7-0)) # 9.899494936611665

如您所见,arcLength 增加了一倍...发生了什么事?该函数实际上在点之间做了最小的欧几里得距离......所以,如果你有一条完美的线并且顺序正确你会得到相同的结果(或非常接近),但如果一个点是乱序的,它可能会给有些不同。

一些评论:

你得到 153 欧几里德距离......然后你的线在某些部分比 1 像素粗得到 204 点(考虑每个像素至少 1)这意味着轮廓可以检测到一条线中的 2 条线您拥有的线,这意味着您将获得更多周长。

你可以尝试做 approx poly 来获得更少的点,看看发生了什么,或者如果你用 findCountours 得到轮廓,那么你可以使用 CV_CHAIN_APPROX_SIMPLE 来压缩它,看看是什么错了。

我希望这能消除您的疑虑,如果不给我留言的话。

关于opencv - arcLength() 和 contourArea() 返回意外值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48251667/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com