【问题标题】:Matlab: Check all images in a directory for grayscale?Matlab:检查目录中的所有图像是否为灰度?
【发布时间】:2011-10-06 00:11:27
【问题描述】:

我想检查当前目录中的所有 jpg 图像是否为灰度或包含彩色像素...我试过了:

figdirectory = pwd;
fullpath = sprintf('%s/*.jpg', figdirectory);
d = dir(fullpath);

% Loop
pages = [];
for i = 1:length(d)
    f = d(i).name;
    fname_input = sprintf('%s/%s', figdirectory, f);

    A = imread(fname_input); 
    B = rgb2gray(A);

    if(A-B == 0)
        hascolor = 0;
    else
        hascolor = 1;
    end
    pages = [pages; hascolor];        
end 

但这给了我关于 A 和 B 的矩阵维度的错误。为什么 A 有第三个维度? 谢谢!

【问题讨论】:

    标签: matlab image-processing colors


    【解决方案1】:

    这样做:

    0) 假设您的输入纯粹是“图像”而不是“体积”。

    1) [r c d] = 大小(im);

    2) 如果 d 大于 1,则为彩色图像

    3) 否则,它必须是灰度图像。

    编辑: 您可以再添加一个条件来可靠地区分灰度 img 和彩色图像。假设你的彩色图像有 3 个通道,

    如果 d 等于 3,则检查所有 3 个通道是否都相等

    im(:,:,1)==im(:,:,2) && im(:,:,1)==im(:,:,3) 然后你有一个灰度图像否则颜色img

    【讨论】:

    • 谢谢。我将代码修改为A = imread(fname_input); [r c e] = size(A); if(e > 1) hascolor = 1; else hascolor = 0; end,但它不起作用:灰度图像也被识别为彩色:(
    • 是书籍页面的彩色扫描吗?因此被识别为彩色图像。
    • @col heather,颜色 img 的另一个定义是每个 r g b 通道中的每个像素都是相同的。请参阅我的答案的补充部分
    【解决方案2】:

    这是一个基于 IMFINFO 的简单解决方案:

    %# some test images shipped with the Image Processing Toolbox
    fNames = {
        'circles.png'   %# binary
        'shadow.tif'    %# indexed color
        'coins.png'     %# gray
        'peppers.png'   %# RGB
    };
    
    isGrayscale = false(size(fNames));
    for i=1:numel(fNames)
        imgInfo = imfinfo(fNames{i});
        if strcmp(imgInfo.ColorType,'truecolor')
            isGrayscale(i) = false;
        elseif strcmp(imgInfo.ColorType,'grayscale')
            isGrayscale(i) = true;
        elseif strcmp(imgInfo.ColorType,'indexed')
                %# indexed images colormap (the three channels should be all same)
            isGrayscale(i) = all(all( diff(imgInfo.Colormap,[],2)==0 ,2),1);
        end
    end
    

    您案例的第一部分可以是:

    dirName = 'C:\path\to\myimages';
    files = dir( fullfile(dirName,'*.jpg') );
    fNames = {files.name}';
    

    编辑:

    @Adrian:关于你发的图片,就保存的图片格式而言,是彩色图片。现在所有 R/G/B 通道都相同的事实只是一个特例......

    无论如何,如果您希望能够检测到此类情况,请将上述代码的'truecolor' 部分更改为:

    #% ...
    if strcmp(imgInfo.ColorType,'truecolor')
        img = imread(fNames{i});
        isGrayscale(i) = isequal(img(:,:,1),img(:,:,2),img(:,:,3));
    elseif strcmp(imgInfo.ColorType,'grayscale')
    #% ...
    

    【讨论】:

    • 您是否在问题附加的示例图像上尝试过这个?这似乎是书籍页面的彩色扫描或图片。虽然页面是黑白的,但扫描的图像实际上注册为真彩色 [原文如此] 图像。
    • @Adrian:看我上面的回复
    • 澄清一下,提供的图像是由 Col 添加的,而不是我自己。虽然我接受您的代码在处理不同的图像类型方面可能更健壮,但是如果目录中的所有图像都是来自书籍和真彩色 [原文如此] 的扫描图像,那么我仍然更喜欢我的 hsv 解决方案,因为我认为它提供了更清洁和更具可读性代码,问候
    • 首先,如果已知所有图像都是一种,那么问题就不存在了!其次,您说您的代码更具可读性,但您并没有处理所有情况:如果图像被索引,您必须加载颜色图,转换为完整的 RGB,然后继续您的解决方案。最后,我的“真彩色”案例(加载图像并检查R==G==B)的版本比转换为HSV然后检查S是否全为零要快得多。根据定义,饱和度是从C=max(R,G,B)-min(R,G,B) 计算出来的,如果是C==0,那么是S=0。因此,通过简单地检查所有通道是否相等,我们避免了很多额外的工作......
    【解决方案3】:

    您可以使用IMFINFO 执行此任务,这样您就不必将图像加载到内存中。

    figdirectory = pwd;
    fullpath = sprintf('%s/*.jpg', figdirectory);
    d = dir(fullpath);
    
    nImages = length(d);
    
    %# imageType is a cell array with either 'grayscale', 'truecolor', or 'indexed', 
    %# depending on the kind of image you have. 
    
    imageType = cell(nImages,1);
    
    for iImg = 1:nImages
    info = imfinfo(d(iImg).name);
    imageType{iImg} = info.ColorType;
    end
    
    %# isGrayscale is true for grayscale images, false otherwise 
    %# (though note that there might be mapped images that map to a grayscale colormap).
    isGrayscale = cellfun(@(x)strcmp(x,'grayscale'),imageType);
    

    编辑

    %# the indexed images have to be loaded in order for you to check 
    %# for grayscale maps
    
    indexedIdx = find(cellfun(@(x)strcmp(x,'indexed'),imageType));
    
    for iImg = indexedIdx(:)'
    
       [~,map] = imread(fullfile(figDirectory,d(iImg).name));
    
       %# It's a grayscale image if rgb map values are all equal
       isGrayscale(iImg) = all(all(bsxfun(@eq,map,map(:,1)),2),1);
    end
    
    %# finally, it is possible that the images are *stored* as truecolor
    %# but containing, in fact, a grayscale image
    
    truecolorIdx = find(cellfun(@(x)strcmp(x,'truecolor'),imageType));
    
    for iImg = truecolorIdx(:)'
    
       img = imread(fullfile(figDirectory,d(iImg).name));
    
       %# It's a grayscale image if rgb map values are all equal
       isGrayscale(iImg) = all(all(all(bsxfun(@eq,img(:,:,1),img),1),2),3);
    end
    

    【讨论】:

    • 以及如何处理这个灰度图?我在第一篇文章中上传了一张灰度图片,您的代码没有正确处理!
    • @Col Heather:您必须加载图像才能到达地图,然后您可以检查它是颜色还是灰度。查看我的编辑。
    • @Col Heather:另外,如果图像存储为真彩色,但包含仅灰度信息,则需要实际加载图像。
    • 对于提供的示例,因为它是真彩色图像,那么我认为 imread 不会返回要处理的颜色图。正如我在回复中更新的那样,我认为转换为 HSV 并检查饱和度更容易,因为灰度这将为零。
    【解决方案4】:

    来自 imread http://www.mathworks.co.uk/help/techdoc/ref/imread.html 的手册

    如果文件包含灰度图像,则 A 是 M×N 数组。如果 文件包含一个真彩色图像,A 是一个 M×N×3 数组。

    所以 A 将具有用于彩色图像的第三维。

    如果您想测试灰度,则可以将图像转换为 hsv。

    B = rgb2hsv(A)
    

    来自手册,http://www.mathworks.co.uk/help/techdoc/ref/hsv2rgb.html

    当 B(:,2) 为 0 时,颜色是不饱和的(即灰色阴影)。

    对于像发布的那样的真彩色图像,如果 unique(B(:,:,2)) 为零,因此

    A = imread(fname_input);        
    B = rgb2hsv(A);
    
    %# if saturation levels are zero then it's a greyscale image
    if(unique(B(:,:,2)) == 0)
        hascolor = 0;
    else         
        hascolor = 1; 
    end 
    

    【讨论】:

      猜你喜欢
      • 2013-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多