从图像中测量线段的长度(以像素为单位)

2024-03-28 23:00:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有大量的图片,如下图所示。我正在尝试从透射电子显微镜图像中检测纳米颗粒,这是我使用OpenCV Python成功实现的。这张图像只是一张更大的透射电子显微镜图像左下角的一部分。我想提取“100 nm”下白色线段的长度。目前,我正在手动测量这条线的长度,我想将其自动化。我认为这可以用OpenCV Python通过轮廓来完成,但是我还有很多其他的特性,这些特性也在图像中轮廓化了。我是Python新手,我不太确定如何实现它,或者是否可以实现它。我对代码应该做什么的想法:

  1. 加载图像
  2. 找到白色的线段
  3. 返回它的长度(以像素为单位)
  4. 如果它检测到行上方的数字并返回它,那也很好

欢迎提出任何建议、指示或“从哪里开始”的意见,并表示感谢

直线段在其特征上非常独特,每个图像中只有一条直线

enter image description here


Tags: 代码图像图片像素特性手动opencv直线
2条回答

您可以对图像进行二值化以查找缩放段的轮廓:

processing

scale = cv2.imread('scalenanometer.png', cv2.IMREAD_COLOR)
scale_gray = cv2.cvtColor(scale, cv2.COLOR_BGR2GRAY)
# adjust the second value of the next line to tune the detection
ret, thresh = cv2.threshold(scale_gray, 210, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# filter noisy detection
contours = [c for c in contours if cv2.contourArea(c) > 100]
# sort from by (y, x)
contours.sort(key=lambda c: (cv2.boundingRect(c)[1], cv2.boundingRect(c)[0]))
# work on the segment
cv2.rectangle(scale, cv2.boundingRect(contours[-1]), (0,255,0), 2)
x,y,w,h = cv2.boundingRect(contours[-1])
print(x,y,w,h) # x,y: (39 152) w,h: [304 21]

如果要检测该值,可以使用tesseract ocr

一种方法是使用概率Hough线方法检测线

结果将是:

enter image description here

现在问题是检测到多条线。我们知道他们的坐标。如果我们将它们全部打印出来:

Pixel Length: 296
Pixel Length: 197
Pixel Length: 308
Pixel Length: 175
Pixel Length: 292
Pixel Length: 229
Pixel Length: 103
Pixel Length: 109

由于检测到的长度很多,可能找到其平均值是有意义的:

Average Pixel Length: 109 pixel

虽然我不知道如何将109像素转换为100nm

import cv2
import numpy as np

img = cv2.imread("4HQtp.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)
base = cv2.HoughLinesP(edges, 1, np.pi / 180, 80, minLineLength=1, maxLineGap=6)
pixel_array = []
pixel_length = 0
if base is not None:
    for line in base:
        x1, y1, x2, y2 = line[0]
        cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
        pixel_length = np.abs(x2 - x1)
        pixel_array.append(pixel_length)
        print("Pixel Length: {}".format(pixel_length))
    cv2.imshow("img", img)
    cv2.imwrite("hough_img.png", img)
    cv2.waitKey(0)
print("Average Pixel Length: {:.0f} pixel".format(np.average(pixel_array)))

相关问题 更多 >