You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

二进制图像中小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

火山引擎 最新活动