MATLAB保存二值图像后读取数据类型变为uint8问题咨询
异常现象原因
- JPG是有损压缩格式:其二值图像存储过程中,压缩算法会对边缘做平滑、量化处理,必然会引入0和255之外的中间灰度值,你统计到的多值像素就是压缩引入的误差。
- JPG格式本身不支持存储逻辑型二值数据:所有内容默认以uint8类型编码存储,读取时自然返回uint8类型的数组,不会直接得到二值逻辑数组。
- 补充细节:
im2bw返回的是逻辑类型矩阵,直接写入JPG时MATLAB会默认将逻辑1映射为255、逻辑0映射为0再执行编码,但映射后的内容依然会被JPG压缩破坏,无法保留仅0/255的取值。
解决方案
- 方案1:更换无损图像格式存储(最推荐)
放弃使用JPG,改用PNG、BMP等无损格式存储二值图像,这类格式支持1位二值数据存储,不会引入压缩误差,读取时可直接返回逻辑类型的二值数组。存储示例代码如下:
D = '/folder-path/'; S = dir(fullfile(D,'*.jpg')); for k = 1:numel(S) F = fullfile(D,S(k).name); I = imread(F); I2 = im2bw(I); % 替换后缀为png存储,不覆盖原JPG避免数据损失 newF = strrep(F, '.jpg', '.png'); imwrite(I2, newF); end
读取PNG二值图时,直接用imread得到的就是逻辑类型二值数组,且unique返回结果仅包含0和1。
- 方案2:读取JPG后二次二值化
如果必须保留JPG格式,可在读取图像后手动做阈值分割转回二值类型,抵消压缩带来的误差影响,示例代码如下:
I = imread('目标图像.jpg'); % 以128为阈值分割,大于阈值的为1,小于的为0 bw = imbinarize(I, 128/255); % 或直接用逻辑判断:bw = I > 128;
该方案的缺陷是JPG压缩已经对原始二值图像的边缘、细节造成了不可逆破坏,二次二值化无法完全还原原始的二值图像内容。
- 方案3:JPG存储时设置最高质量
如果必须用JPG存储,可在写入时将压缩质量调至最高,尽可能降低压缩误差:
imwrite(I2, F, 'Quality', 100);
注意即使质量设为100,JPG依然属于有损压缩,仍可能出现少量中间灰度值,仅作为备选方案使用。
内容的提问来源于stack exchange,提问作者Simplicity
相关产品推荐
相关产品推荐

