我正在从ImageJ转到用于对显示粒子(无论是在长凳上还是在倒下)的图像进行图像处理的图像处理,并试图编写我的第一个代码,用于1)打开粒子图像,2)应用阈值和降噪来获得二值图像,3)应用分水岭来分离重叠的粒子,以及4)测量检测到的区域以获得关于粒子大小分布的信息(例如,面积、周长、轴).
我现在正在处理附加的图像,让事情变得简单.它是一串直径从0.5毫米到1毫米的颗粒放在长椅上.
现在,我用Python编写了这段代码,它使用OpenCV和skImage函数的混合来创建和打磨二进制图像,应用分水岭(上面的例子不需要,但对于future -我将高速拍摄坠落的粒子-它将非常有用),并测量识别出的细胞.
编辑:附上了第二张图片,我有同样的问题,但针对较小的颗粒(0.250-0.50毫米,但分水岭很重要)‘
Smaller particles where I need watershed个
EDIT2:显示导致该问题的主要处理过程的较短代码.
import cv2
import numpy as np
import pandas as pd
import os
from skimage.segmentation import watershed, clear_border
from skimage import measure, color, io, morphology
# Define the folder path containing the images
image = "C:/..."
# Set scale pixels/mm (either based on ImageJ or by reference image, or calculations)
px_per_mm = 222
mm_per_px = 1 / px_per_mm
img = cv2.imread(image)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#Threshold and remove noise
thresholded_img = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
kernel = np.ones((5, 5),np.uint8)
image = cv2.morphologyEx(thresholded_img, cv2.MORPH_OPEN, kernel)
image = clear_border(image)
# Prepare for Watershed
sure_bg = cv2.dilate(image,kernel, iterations=4)
dist_transform = cv2.distanceTransform(image, cv2.DIST_L2, 0)
ret2, sure_fg = cv2.threshold(dist_transform, 0.4 * dist_transform.max(), 255, 0)
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)
ret3, markers = cv2.connectedComponents(sure_fg, connectivity=8)
markers = markers + 10
markers[unknown == 255] = 0
# Now we are ready for watershed filling.
markers = cv2.watershed(img, markers)
#Measure properties
label_image = measure.label(markers,background=255, connectivity=None)
props = measure.regionprops_table(label_image, image,
properties=['label', 'Area'])
# Scale properties from pixels to mm
props['Area'] = props['Area'] * mm_per_px ** 2
# Remove the image frame that is usually identified as a region
max_area_threshold = 700
props_df = pd.DataFrame(props)
filtered_props = props_df[props_df['Area'] <= max_area_threshold]
# Convert the filtered properties to a DataFrame
particle_analysis = pd.DataFrame(filtered_props)
现在,当前代码给出了粒子区域的分布:
这在很大程度上是正确的,但显示了0.0-0.5箱中的许多区域,一旦消除了噪声和小颗粒,这些区域就不会出现在图像中. 使用ImageJ,我会得到类似的结果,但没有巨大的初始bin: ImageJ results个
如果我判断二值图像、分水岭等,一切似乎都很好,所以不知道为什么要检测到如此小的区域.它发生在我用来测试代码的所有图像上.
我们非常欢迎在识别问题方面的任何帮助!非常感谢!
我根据OpenCV和SkImage上的教程编写了代码,并测试了几种阈值处理、降噪、形态操作和改变区域测量函数的参数,试图在分析中仅检测真实的颗粒.然而,我总是得到初始绑定,显然区域的特征是非常小的区域