Pergunta

Estou tentando implementar o seguinte Limiar de erro mínimo (Por J. Kittler e J. Illingworth) Método no Matlab.

Você pode dar uma olhada no PDF:

Meu código é:

function [ Level ] = MET( IMG )
%Maximum Error Thresholding By Kittler
%   Finding the Min of a cost function J in any possible thresholding. The
%   function output is the Optimal Thresholding.

for t = 0:255 % Assuming 8 bit image
    I1 = IMG;
    I1 = I1(I1 <= t);
    q1 = sum(hist(I1, 256));

    I2 = IMG;
    I2 = I2(I2 > t);
    q2 = sum(hist(I2, 256));

    % J is proportional to the Overlapping Area of the 2 assumed Gaussians
    J(t + 1) = 1 + 2 * (q1 * log(std(I1, 1)) + q2 * log(std(I2, 1)))...
        -2 * (q1 * log(q1) + q2 * log(q2));
end

[~, Level] = min(J);

%Level = (IMG <= Level);

end

Eu tentei na imagem a seguir:Letters

Imagem do tamanho original.

O alvo é extrair uma imagem binária das letras (letras hebraicas). Apliquei o código nos sublocks da imagem (40 x 40). No entanto, obtive resultados inferiores a Método de agrupamento K-Means.

Perdi alguma coisa? Alguém tem uma ideia melhor?

Obrigado.

PS alguém adicionaria "limiar de adaptação" às tags de assunto (não posso como sou novo).

Foi útil?

Solução

Eu acho que seu código não está totalmente correto. Você usa o histograma absoluto da imagem em vez do histograma relativo que é usado no papel. Além disso, seu código é bastante ineficiente, pois calcula dois histogramas por limite possível. Eu mesmo implementei o algoritmo. Talvez alguém possa usar isso:

function [ optimalThreshold, J ] = kittlerMinimimErrorThresholding( img )
%KITTLERMINIMIMERRORTHRESHOLDING Compute an optimal image threshold.
%   Computes the Minimum Error Threshold as described in
%   
%   'J. Kittler and J. Illingworth, "Minimum Error Thresholding," Pattern
%   Recognition 19, 41-47 (1986)'.
%   
%   The image 'img' is expected to have integer values from 0 to 255.
%   'optimalThreshold' holds the found threshold. 'J' holds the values of
%   the criterion function.

%Initialize the criterion function
J = Inf * ones(255, 1);

%Compute the relative histogram
histogram = double(histc(img(:), 0:255)) / size(img(:), 1);

%Walk through every possible threshold. However, T is interpreted
%differently than in the paper. It is interpreted as the lower boundary of
%the second class of pixels rather than the upper boundary of the first
%class. That is, an intensity of value T is treated as being in the same
%class as higher intensities rather than lower intensities.
for T = 1:255

    %Split the hostogram at the threshold T.
    histogram1 = histogram(1:T);
    histogram2 = histogram((T+1):end);

    %Compute the number of pixels in the two classes.
    P1 = sum(histogram1);
    P2 = sum(histogram2);

    %Only continue if both classes contain at least one pixel.
    if (P1 > 0) && (P2 > 0)

        %Compute the standard deviations of the classes.
        mean1 = sum(histogram1 .* (1:T)') / P1;
        mean2 = sum(histogram2 .* (1:(256-T))') / P2;
        sigma1 = sqrt(sum(histogram1 .* (((1:T)' - mean1) .^2) ) / P1);
        sigma2 = sqrt(sum(histogram2 .* (((1:(256-T))' - mean2) .^2) ) / P2);

        %Only compute the criterion function if both classes contain at
        %least two intensity values.
        if (sigma1 > 0) && (sigma2 > 0)

            %Compute the criterion function.
            J(T) = 1 + 2 * (P1 * log(sigma1) + P2 * log(sigma2)) ...
                     - 2 * (P1 * log(P1) + P2 * log(P2));

        end
    end

end

%Find the minimum of J.
[~, optimalThreshold] = min(J);
optimalThreshold = optimalThreshold - 0.5;

Outras dicas

O limiar é um negócio bastante complicado. Nos muitos anos em que tenho sido limite de imagens, não encontrei uma única técnica que sempre tenha um bom desempenho, e desconfiei das reivindicações de desempenho universalmente excelente em periódicos CS.

O método de limiar de erro máximo funciona apenas no histograma bem bimodal (mas funciona bem neles). Sua imagem parece que o sinal e o plano de fundo podem não estar claramente separados o suficiente para que esse método de limiares funcione.

Se você deseja garantir que o código funcione bem, você pode criar um programa de teste como este e verificar se obtém uma boa segmentação inicial, bem como em qual nível de 'bimodalidade' o código quebra.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top