如何测量图像中每个极点的长度(以像素为单位)

Posted

技术标签:

【中文标题】如何测量图像中每个极点的长度(以像素为单位)【英文标题】:How to measure the length (in pixel) for each pole in an image 【发布时间】:2018-10-18 02:04:22 【问题描述】:

我想以像素为单位测量每个极点的高度和宽度。 但是因为杆子并不总是直立,但我需要杆子与水平地面的高度。谁能指导我如何处理这个问题?

注意:我以后可能需要得到它倾斜的角度。不确定我可以在这里问这么多问题。但如果有人可以提供帮助,我们将不胜感激。

我的图片样本在下面的链接:

【问题讨论】:

你可以使用阈值,然后是 cv::findContours 和 cv::minAreaRect 和/或 cv::boundingBox 这是否包括获取红色箭头列的高度?还是只是黑条? Mark 下面显示的 ImageMagick 结果是边界框。所以倾斜的边界框宽度大于厚度。获取黑色条纹宽度的一种方法是获取图像的 1 像素高的水平切片,然后使用连接组件测量其宽度。 只有黑条。红色箭头只是一个指示符。 我的回答解决了你的问题吗?如果是这样,请考虑接受它作为您的答案 - 通过单击计票旁边的空心对勾/复选标记。如果没有,请说出什么不起作用,以便我或其他人可以进一步帮助您。谢谢。 meta.stackexchange.com/questions/5234/… 【参考方案1】:

这应该会给你一个很好的想法:

#!/usr/local/bin/python3
import cv2

# Open image in greyscale mode
img = cv2.imread('poles.png',cv2.IMREAD_GRAYSCALE)

# Threshold image to pure black and white AND INVERT because findContours looks for WHITE objects on black background
_, thresh = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)

# Find contours
_, contours, _ = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

# Print the contours 
for c in contours:
   x,y,w,h = cv2.boundingRect(c)  
   print(x,y,w,h)

输出是这样的,其中每一行对应于图像中的一个垂直条:

841 334 134 154   <--- bar 6 is 154 pixels tall
190 148 93 340    <--- bar 2 is 340 pixels tall
502 79 93 409     <--- bar 4 is 409 pixels tall
633 55 169 433    <--- bar 5 is 433 pixels tall
1009 48 93 440    <--- bar 7 is 490 pixels tall
348 48 93 440     <--- bar 3 is 440 pixels tall
46 46 93 442      <--- bar 1 is 442 pixels tall (leftmost bar)

第一列是距图像左边缘的距离,最后一列是条形的高度(以像素为单位)。


由于您似乎不确定是要在 Python 还是 C++ 中执行此操作,您可能根本不想编写任何代码 - 在这种情况下,您可以简单地使用大多数 Linux 中包含的 ImageMagick发行版,适用于 macOS 和 Windows。

基本上,您可以通过在终端中键入以下内容来使用 “连接组件” 分析:

convert poles.png -colorspace gray -threshold 50% \
   -define connected-components:verbose=true      \
   -connected-components 8 null:

输出

Objects (id: bounding-box centroid area mean-color):
  0: 1270x488+0+0 697.8,216.0 372566 srgb(255,255,255)
  1: 93x442+46+46 92.0,266.5 41106 srgb(0,0,0)
  2: 93x440+348+48 394.0,267.5 40920 srgb(0,0,0)
  3: 93x440+1009+48 1055.0,267.5 40920 srgb(0,0,0)
  4: 169x433+633+55 717.3,271.0 40269 srgb(0,0,0)
  5: 93x409+502+79 548.0,283.0 38037 srgb(0,0,0)
  6: 93x340+190+148 236.0,317.5 31620 srgb(0,0,0)
  7: 134x154+841+334 907.4,410.5 14322 srgb(0,0,0)

这会给你一个标题行,告诉你所有字段是什么,然后是它在图像中找到的每个 blob 的一行。忽略第一个,因为那是白色背景 - 您可以从最后一个字段 rgb(255,255,255) 中看到。

所以,如果我们看最后一行,它是一个 134 像素宽和 154 像素高的斑点,从左上角的 x=841 和 y=334 开始,即它对应于第一个轮廓OpenCV 找到了。

【讨论】:

哦,谢谢!其实我用的是C++。一旦我尝试了,我会反馈。感谢您宝贵的时间回复。 在 C++ 中,我尝试这样写: for (int i = 0; i 你可以只做Rect r = boundingRect(contours[i]);看这里docs.opencv.org/2.4/doc/tutorials/imgproc/shapedescriptors/…和answers.opencv.org/question/28559/…

以上是关于如何测量图像中每个极点的长度(以像素为单位)的主要内容,如果未能解决你的问题,请参考以下文章

NSString 文本像素长度

CSS长度单位中的负长度值

如何将 NSPopUpButton 与测量单位选择连接到 NSTextField 的呈现方式?

在 Blender 脚本中测量路径长度?

绝对单位&相对单位

如何将字符串长度转换为像素单位?