二进制图像中小Blob计数及面积周长测量的Python方案咨询
用Python测量二进制图像中Blob的面积、周长等参数
嘿,刚好我之前处理过类似的场景!你说的轮廓法其实也能拿到部分参数,但确实不如专门的区域分析工具来得全面。下面给你两种靠谱的实现方案,都是Python生态里常用的:
方案一:用scikit-image的regionprops(推荐,省心高效)
regionprops简直是处理这类Blob分析的利器,它能直接给你算出面积、周长、中心坐标、外接矩形一堆参数,而且对小Blob的处理也很稳定。
完整代码示例
import cv2 import numpy as np from skimage.measure import regionprops, label # 1. 读取并预处理图像(如果还没二值化的话) img_path = "your_image_path.png" img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) # 二值化(如果输入不是二进制图像,调整阈值适应你的场景) _, binary_img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # 2. 标记每个独立的Blob(给每个Blob分配唯一的标签) labeled_img = label(binary_img) # 3. 提取每个Blob的属性 blob_props = regionprops(labeled_img) # 4. 遍历输出参数 print(f"总共检测到 {len(blob_props)} 个Blob") for idx, prop in enumerate(blob_props, 1): print(f"\nBlob {idx}:") print(f" 面积: {prop.area} 像素") print(f" 周长: {prop.perimeter:.2f} 像素") print(f" 中心坐标: ({prop.centroid[0]:.2f}, {prop.centroid[1]:.2f})") print(f" 外接矩形: 左上角({prop.bbox[0]}, {prop.bbox[1]}), 右下角({prop.bbox[2]}, {prop.bbox[3]})") print(f" 等效直径: {prop.equivalent_diameter:.2f} 像素")
说明
label()函数会把每个连通的Blob标记成不同的数值,这样regionprops能区分每个独立区域- 你能拿到的参数远不止上面这些,比如
eccentricity(偏心率)、solidity(坚实度)等,直接查regionprops的文档就行
方案二:用OpenCV原生方法(适合不想额外装库的场景)
如果不想用scikit-image,OpenCV本身也能通过轮廓+矩来计算这些参数,只是步骤多一点:
完整代码示例
import cv2 import numpy as np img_path = "your_image_path.png" img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) _, binary_img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # 查找所有轮廓 contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) print(f"总共检测到 {len(contours)} 个Blob") for idx, cnt in enumerate(contours, 1): print(f"\nBlob {idx}:") # 面积 area = cv2.contourArea(cnt) print(f" 面积: {area:.2f} 像素") # 周长(第二个参数True表示闭合轮廓) perimeter = cv2.arcLength(cnt, True) print(f" 周长: {perimeter:.2f} 像素") # 中心坐标(通过矩计算) M = cv2.moments(cnt) if M["m00"] != 0: cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) print(f" 中心坐标: ({cX}, {cY})") else: print(f" 中心坐标: 无法计算(面积为0)") # 外接矩形 x, y, w, h = cv2.boundingRect(cnt) print(f" 外接矩形: 左上角({x}, {y}), 宽{w}, 高{h}")
说明
cv2.findContours()用RETR_EXTERNAL只找最外层轮廓,避免嵌套轮廓干扰cv2.CHAIN_APPROX_SIMPLE会压缩轮廓点,减少计算量,适合小Blob- 矩
moments还能计算更多形状特征,比如主轴方向等,需要的话可以深入研究
注意事项
- 如果你输入的已经是二进制图像,那可以跳过二值化步骤,直接用输入图像
- 对于非常小的Blob,建议先做个小的形态学操作(比如
cv2.morphologyEx开运算)去掉噪声,避免误检测
内容的提问来源于stack exchange,提问作者disputator1991




