【问题标题】:How to calculate the distance between two lines?如何计算两条线之间的距离?
【发布时间】:2021-04-26 17:25:45
【问题描述】:

我一直在尝试在 Python 中计算图像中两条线之间的距离。例如,在下面给出的图像中,我想找到黄色块两端之间的垂直距离。到目前为止,我只能推导出两个像素之间的距离。

我可以编写的代码是找出红色和蓝色像素之间的距离。我想我可以改进它以使这张图片中的两点/线之间的距离,但还没有运气。

import numpy as np
from PIL import Image
import math

# Load image and ensure RGB - just in case palettised
im = Image.open("2points.png").convert("RGB")

# Make numpy array from image
npimage = np.array(im)

# Describe what a single red pixel looks like
red = np.array([255,0,0],dtype=np.uint8)

# Find [x,y] coordinates of all red pixels
reds = np.where(np.all((npimage==red),axis=-1))

print(reds)

# Describe what a single blue pixel looks like
blue=np.array([0,0,255],dtype=np.uint8)

# Find [x,y] coordinates of all blue pixels
blues=np.where(np.all((npimage==blue),axis=-1))

print(blues)

dx2 = (blues[0][0]-reds[0][0])**2          # (200-10)^2
dy2 = (blues[1][0]-reds[1][0])**2          # (300-20)^2
distance = math.sqrt(dx2 + dy2)
print(distance)

【问题讨论】:

  • 欢迎来到 Stack Overflow!请使用tour 并阅读How to Ask。请edit 发布您自己的努力来解决这个问题。后者最好在代码中,这称为minimal reproducible example。
  • 也许您可以添加第二张带注释的图像,准确显示您想要找到的内容,因为不太清楚“黄色块末端之间的垂直距离是什么意思,假设至少有 2 个或 5 个黄色块,并且您没有说明它需要垂直于什么。
  • @MarkSetchell 它只是中间的黄色大块
  • 所以你想要最大的黄色矩形的高度?
  • @MarkSetchell 是的。高度和宽度。

标签: python numpy image-processing distance


【解决方案1】:

在准备这个答案时,我意识到我对cv2.boxPoints 的暗示具有误导性。当然,我想到了cv2.boundingRect——对不起!

尽管如此,以下是完整的分步方法:

  1. 使用cv2.inRange 屏蔽所有黄色像素。注意:您的图像有 JPG 伪影,因此您在遮罩中会出现很多噪点,请参阅。输出:

  1. 使用cv2.findContours 查找遮罩中的所有轮廓。由于有许多微小的工件,这将超过 50 个。

  2. 在找到的轮廓(列表)上使用 Python 的 max 函数,使用 cv2.contourArea 作为键获得最大轮廓。

  3. 最后,使用cv2.boundingRect得到轮廓的边界矩形。那是一个元组(x, y, widht, height)。只需使用最后两个元素,即可获得所需的信息。

那是我的代码:

import cv2

# Read image with OpenCV
img = cv2.imread('path/to/your/image.ext')

# Mask yellow color (0, 255, 255) in image; Attention: OpenCV uses BGR ordering
yellow_mask = cv2.inRange(img, (0, 255, 255), (0, 255, 255))

# Find contours in yellow mask w.r.t the OpenCV version
cnts = cv2.findContours(yellow_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

# Get the largest contour
cnt = max(cnts, key=cv2.contourArea)

# Get width and height from bounding rectangle of largest contour
(x, y, w, h) = cv2.boundingRect(cnt)
print('Width:', w, '| Height:', h)

输出

Width: 518 | Height: 320

似乎合理。

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.8.5
OpenCV:        4.5.1
----------------------------------------

【讨论】:

  • 非常感谢您的回答。效果很好,我批准了你的回答 :) 快速提问,我如何更改范围以找到其他颜色,例如蓝色、红色和其他色调?
  • @UrmiBose 在cv2.inRange 调用中,放入所需颜色的相应RGB 值。注意:请仅使用 RGB 值,如果您有干净的单值颜色,例如纯绿色(0, 255, 0)。如果要检测“所有绿色”,请切换到 HSV 颜色空间并使用适当的范围,参见。 this earlier answer from me 为起点。
猜你喜欢
  • 1970-01-01
  • 2010-10-12
  • 2021-05-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-17
  • 1970-01-01
  • 2010-10-30
相关资源
最近更新 更多