从直方图阈值绘制

时间:2014-06-17 21:29:08

标签: image matlab histogram threshold

% OTSU THRESHOLDING
% X=imread('cameraman.tif')
% a=ones(256,1)*[1:256];
% c2=double(X).*(a/2+50)+(1-double(X)).*a/2;
% c3=uint8(255*mat2gray(c2));
% IDX = otsu(c3,2); 
%----------------------------------------------------------
%
% function [IDX,sep] = otsu(I,n)

I = single(I);

    %% Convert to 256 levels
    I = I-min(I(:));
    I = round(I/max(I(:))*255);

    %% Probability distribution
    unI = sort((I));
    nbins = min(length(unI),256);

    [histo,pixval] = hist(I(:),256);

    P = histo/sum(histo);


    %% Zeroth- and first-order cumulative moments
    w = cumsum(P);
    mu = cumsum((1:nbins).*P);

    %% Maximal sigmaB^2 and Segmented image
    if n==2
        sigma2B =...
            (mu(end)*w(1:end-1)-mu(1:end-1)).^2./w(1:end-1)./(1-w(1:end-1));

        [maxsig,k] = max(sigma2B);
        k

这是我用来查找Otsu阈值的代码(仅限2类)。因此在找到最佳阈值即k后,如何计算阈值图像? 如何改变每个图像的像素值< k = 0并且> = k = 1,使得它创建二进制图像?

2 个答案:

答案 0 :(得分:0)

根据您的阈值k,您只需使用二进制运算来计算阈值图像。

简单地说,如果你的图像是I,那么可以像这样计算阈值图像:

outThreshold = I >= k;

您也可以使用outThreshold = im2bw(I,k);执行相同的操作(感谢@Daniel!)。它基本上执行我刚才描述的内容。

在任何情况下,都会返回二进制地图,其中强度大于或等于k的像素设置为true / 1,而那些较小的像素则设置为kfalse / 0设置为graythresh。以下是使用graythresh的示例。 MATLAB有一个内置的阈值查找算法,使用Otsu I = imread('cameraman.tif'); %// Built-in to MATLAB - A grayscale image k = 255*graythresh(im); %// Output is scaled between 0 - 1. %//Multiply by 255 to get 8-bit intensity subplot(1,2,1); imshow(I); outThresh = I >= k; subplot(1,2,2); imshow(outThresh);

thresholds = [32 96 128 192];

因此,你得到这个数字:

enter image description here

白色的位置表示超过阈值的像素,而黑色的位置则表示没有。


根据您的评论(您确实应该更新您的帖子),您希望寻找一种执行多阈值处理的方法。这仍然很简单。假设您有一系列阈值,如下所示:

for

这就是说我们需要考虑五个区域:

  • 强度值介于0到31之间的像素
  • 强度值在32到95之间的像素
  • 强度值介于96到127之间的像素
  • 强度值在128到191之间的像素
  • 强度值介于192到255之间的像素

请注意,对于此示例,上端是独占。因此,我们不包括结束间隔,但我们在下一个间隔中包含此数字,并将其指定为间隔的下限。

我们只需使用map = zeros(size(I)); thresholdArray = [0 thresholds 255]; for k = 1 : numel(thresholdArray)-1 lower = thresholdArray(k); upper = thresholdArray(k+1); map(I >= lower & I < upper) = k; end %// Rescale to 0 - 255 outMap = uint8(255*(map - min(map(:))) / (max(map(:)) - min(map(:)))); figure; subplot(2,2,1); imshow(I); subplot(2,2,2); imhist(I); subplot(2,2,3); imshow(outMap); subplot(2,2,4); imhist(outMap); 循环并创建一个 map 变量,该变量可查找每个范围内的所有像素,并将其设置为ID号。让我们按递增的顺序给出这些ID,因此第一个区域的ID分配为1,下一个ID为2,依此类推。这是代码:

(256 / numThresholds)

这是输出的样子:

enter image description here

代码执行多阈值处理,以及使用直方图显示原始图像以及使用直方图显示阈值图像。请注意,我重新调整了输出映射,使其从0到255.因此,每个都会被赋值为{{1}}的倍数。在这种情况下,它是64。

答案 1 :(得分:0)

im2bw(I,p)使用阈值p

将图像I转换为黑白图像