如何使用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
相关产品推荐
相关产品推荐

