如何在MATLAB中仅保留图像中的杯子为白色,其余部分为黑色?
问题分析与解决方法
你的核心问题是imbinarize默认的Otsu自动阈值没能区分杯子和保温瓶,导致二者都被识别为亮区域;另外你后续的循环处理完全无效——因为imbinarize输出的是二值图像,元素值只有0(黑)和1(白,逻辑型时为true/false),根本不存在127-255之间的数值,这部分代码等于没执行。
下面给你几种可行的实现方案:
方案1:手动指定阈值分割
如果杯子的灰度明显高于保温瓶和背景,先通过查看杯子区域的灰度值确定阈值,再手动分割:
close all I = imread('Original-min-min.JPG'); gray = rgb2gray(I); % 手动设置阈值(可通过imtool(gray)点击杯子区域查看具体灰度值,调整阈值) threshold = 200; BW = gray > threshold; % 灰度大于阈值的设为白(1),其余为黑(0) figure imshowpair(gray, BW, 'montage') figure imshow(BW)
方案2:基于RGB颜色通道分割(适用于杯子为纯白色、与保温瓶颜色有差异的场景)
如果杯子是纯白色,保温瓶颜色偏暗或有其他色调,直接在RGB通道提取高亮度交集区域:
close all I = imread('Original-min-min.JPG'); % 提取RGB三通道,取三通道均为高亮度的区域(纯白色区域特征) R = I(:,:,1); G = I(:,:,2); B = I(:,:,3); BW = (R > 220) & (G > 220) & (B > 220); figure imshowpair(I, BW, 'montage') figure imshow(BW)
方案3:连通区域分析(适用于自动阈值后杯子为独立连通块的场景)
如果自动阈值能选中杯子+保温瓶,但二者是独立的连通区域,可通过提取目标连通块实现:
close all I = imread('Original-min-min.JPG'); gray = rgb2gray(I); % 二值化+去除小噪声 BW = imbinarize(gray); BW = bwareaopen(BW, 500); % 去掉面积小于500的噪声区域,数值根据图像调整 % 获取所有连通区域的属性 stats = regionprops(BW, 'Area'); % 按区域面积排序(假设杯子是第二大区域,最大区域可能是背景/保温瓶) areas = [stats.Area]; [sortedAreas, idx] = sort(areas, 'descend'); cupIdx = idx(2); % 创建仅保留杯子区域的二值图 BW_cup = false(size(BW)); BW_cup(BW) = ismember(labelmatrix(BW), cupIdx); figure imshowpair(gray, BW_cup, 'montage') figure imshow(BW_cup)
内容的提问来源于stack exchange,提问作者Fahaad Munir
相关产品推荐
相关产品推荐

