使用python OpenCV计算叶脉叶密度

2024-05-15 23:35:50 发布

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

我是一名植物生物学家,花了太多时间使用ImageJ进行重复的图像计算。我的具体问题是找到静脉的长度,然后计算密度(注意图像有一个刻度)

enter image description here

我了解python,我正在研究OpenCV,我认为这个库可以完成这项工作。但不幸的是,我对计算机视觉技术,特别是OpenCV的了解很差。我来这里是为了寻求关于我应该使用什么方法来实现我的目标的建议

编辑:密度计算为每叶面积的总叶脉长度。参考图片如下 enter image description here


Tags: 方法图像目标静脉计算机时间视觉opencv
2条回答
我不知道你到底是怎么计算密度的,或者你认为是静脉的。但是在Python/OpenCV中有一个概念

基本上,一个阈值的图像与大津自动阈值。然后选择性地使用形态学删除可能不是静脉一部分的小黑色区域。然后反转颜色,使纹理为白色,并计算图像中黑色像素的数量。然后,密度将是计数除以图像中的像素总数

输入:

enter image description here

import cv2
import numpy as np

img = cv2.imread("veins.jpg")
ht, wd = img.shape[:2]

# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# create a binary thresholded image
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]

# apply morphology to remove small black spots
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7,7))
morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# invert so veins are white
veins = 255 - morph

# count non-zero pixels
count = np.count_nonzero(veins)

# compute density
density = count / (ht * wd)

# print density
print("density :", density)

# the density also should be just the graylevel average (mean) of the binary veins image divided by 255, so
density2 = np.mean(veins)/255

# print density2
print("density2:", density2)

# save result
cv2.imwrite("veins_binary.jpg", morph)

# show results
cv2.imshow("thresh", thresh)
cv2.imshow("morph", morph)
cv2.waitKey(0)
cv2.destroyAllWindows()

阈值化和形态学清理图像:

enter image description here

密度结果:

density : 0.41110921223958335
density2: 0.4111092122395833

这是一个包含Python/OpenCV/Skimage中的骨架化的版本

输入:

enter image description here

import cv2
import numpy as np
import skimage.morphology

img = cv2.imread("veins.jpg")
ht, wd = img.shape[:2]

# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# create a binary thresholded image
thresh = cv2.threshold(gray, 0, 1, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]

# apply morphology to remove small black spots
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# invert so veins are white
veins = 1 - morph

# apply skeletonization
skeleton = skimage.morphology.skeletonize(veins)

# count non-zero pixels
count = np.count_nonzero(skeleton)

# compute density
density = count / (ht * wd)

# print density
print("density :", density)

# the density also should be just the graylevel average (mean) of the binary veins image divided by 255, so
density2 = np.mean(skeleton)

# print density2
print("density2:", density2)

# save result
cv2.imwrite("veins_skeleton.jpg", (255*skeleton).clip(0,255).astype(np.uint8))

# show results
cv2.imshow("thresh", (255*thresh).clip(0,255).astype(np.uint8))
cv2.imshow("morph", (255*morph).clip(0,255).astype(np.uint8))
cv2.imshow("skeleton", (255*skeleton).clip(0,255).astype(np.uint8))
cv2.waitKey(0)
cv2.destroyAllWindows()

骨架图像:

enter image description here

密度:

density : 0.032196451822916666
density2: 0.032196451822916666

相关问题 更多 >