- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试测量等高线的长度:
绿线是在轮廓上计算的 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
编辑:
这是原始轮廓:
以下是要点:
[[[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/
使用 cv::Canny() 后,图像中似乎出现了一些非闭合曲线。所以我的问题是, cv::ContourArea() 将如何处理它们?先关闭曲线来计算面积还是忽略它们? 最佳答案 来自 Contou
当我尝试启动我的应用程序时,它在执行 contourArea 时意外崩溃。 这里是错误: OpenCV Error: Assertion Failed (contour.checkVector(2)
我想做的是在夜间地球的照片中找到大面积的光污染区域。我将源照片转换为灰度,然后转换为具有阈值的二值照片。 cv2.findcontours 工作正常,但当我尝试去除小轮廓时,它只会删除其中的一部分。
我是 OpenCV 的新手,有一个小问题,可能很容易解决。基本上我在做一些基本的图像处理,我试图找到 contourArea() = 0 && (contour.depth() == CV_32F |
我正在尝试测量等高线的长度: 绿线是在轮廓上计算的 HoughLineP。通过计算绿线上的欧氏距离,我得到 153.88。然而,轮廓上的 arcLength() 给出了 364.71,而它应该比 Ho
documentation for cv.contourArea 表示,如果oriented为true,则返回值将为正值或负值,具体取决于轮廓的方向: oriented: Oriented area
我正在尝试使用 OpenCV 和 Python 获取图像中的最大区域,代码如下: #Loading image: fuente=cv.LoadImage('train/fruit1.jpg') #Co
如何根据等高线区域的大小对等高线进行排序?我怎样才能得到最大/最小的? 最佳答案 您可以使用 std::sort使用自定义比较函数对象 // comparison function object bo
如果我有一个 3x3 二值图像,并且位置 (x,y) 中有一个轮廓:(0,0), (0,1), (1,0), (1,1) 我通过 findContours 方法获取轮廓。 我想得到这个轮廓的面积: 计
我尝试根据生成的船体点计算船体面积凸包()。 我关注了OpenCV Python tutorial (因为没有 Java 教程)并摆弄代码完成。 这是代码: Imgproc.findContours(
我试图在二值化图像中找到最大的轮廓。根据 this question 判断和 this tutorial你会认为这是微不足道的,我同意。当我在 the image below 上运行我的代码时但是,它
我的目标是使用 HOG 描述符识别汽车标志。我正在关注教程链接 https://gurus.pyimagesearch.com/lesson-sample-histogram-of-oriented-
当我尝试运行以下代码时: img = cv2.imread('index4.jpg',0) ret,thresh = cv2.threshold(img,127,255,0) ret,thresh =
我正在尝试使用代码阅读多项选择测试反馈中的答案,但出现以下错误消息: error: (-215:Assertion failed) npoints >= 0 && (depth == CV_32F |
我是一名优秀的程序员,十分优秀!