You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用scikit-image基于轮廓生成米粒最小外接矩形并计算长宽、实现旋转

你已完成米粒图像的二值化、腐蚀和轮廓提取,基于scikit-image现有接口,可通过连通域属性提取完成剩余需求,实现方案如下:

新增依赖导入

在原有导入代码中新增变换模块:

from skimage import transform

完整实现代码(替换原有主函数部分即可)

if __name__ == '__main__':
    image_name, image_objects = Detect_Images()
    thresholded_images = Adaptive_Threshold(image_objects)
    eroded_images = Erosion(thresholded_images)

    for idx, (orig_img, bin_img, img_name) in enumerate(zip(image_objects, eroded_images, image_name)):
        # 1. 连通域标记,获取每个米粒的几何属性
        label_img = measure.label(bin_img, connectivity=2)
        props = measure.regionprops(label_img)
        print(f"{img_name} 共检测到 {len(props)} 粒米粒")

        # 初始化展示画布
        fig, axes = plt.subplots(1, 3, figsize=(15, 5))
        axes[0].imshow(orig_img, cmap='gray')
        axes[0].set_title('原图')
        axes[1].imshow(bin_img, cmap='gray')
        axes[1].set_title('外接矩形标记')
        axes[2].set_title('旋转对齐后')

        rotated_grains = []

        for grain_idx, prop in enumerate(props):
            # 2. 计算米粒长宽(单位为像素)
            # *major_axis_length为最小外接椭圆长轴,对应米粒长度;minor_axis_length对应宽度
            rice_length = prop.major_axis_length
            rice_width = prop.minor_axis_length
            print(f"第{grain_idx+1}粒:长度{rice_length:.2f}px,宽度{rice_width:.2f}px,长轴倾斜角{np.degrees(prop.orientation):.2f}°")

            # 3. 绘制最小外接矩形
            center = prop.centroid
            rr, cc = draw.rectangle_perimeter(
                center=(center[0], center[1]), 
                extent=(rice_length, rice_width), 
                rotation=prop.orientation, 
                shape=bin_img.shape
            )
            axes[1].plot(cc, rr, color='red', linewidth=2)

            # 4. 裁剪米粒并旋转至竖直90度
            rotate_angle = 90 - np.degrees(prop.orientation)
            # 裁剪单个米粒区域
            minr, minc, maxr, maxc = prop.bbox
            crop_grain = bin_img[minr:maxr, minc:maxc]
            # 旋转并填充背景
            rotated = transform.rotate(crop_grain, rotate_angle, resize=True, cval=0)
            rotated_grains.append(rotated)

        # 拼接展示所有旋转后的米粒
        if rotated_grains:
            max_h = max([g.shape[0] for g in rotated_grains])
            concat_img = np.zeros((max_h, sum([g.shape[1] for g in rotated_grains])), dtype=np.float32)
            curr_col = 0
            for g in rotated_grains:
                h, w = g.shape
                concat_img[:h, curr_col:curr_col+w] = g
                curr_col += w
            axes[2].imshow(concat_img, cmap='gray')

        for ax in axes:
            ax.axis('off')
        plt.tight_layout()
        plt.show()

补充说明

如果需要对整张图像做整体旋转而非单个米粒对齐,直接计算所有米粒orientation的平均值,调用transform.rotate(原图, 90 - np.degrees(平均角度))即可完成整体对齐。

内容的提问来源于stack exchange,提问作者Ramish Siddique

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 03:39:04