Parth Doshi
Parth Doshi

Reputation: 4208

Local thresholding in MATLAB

I am trying to implement local thresholding in MATLAB 7.7. This is what my original image looks likeenter image description here:

As seen the the word Test is covered in black. This image is a PNG image having dimensions 919x551. I want to apply local thresholding to this image so that I can get the word Test to be visible clearly.

I have implemented the following code that works by dividing the entire image into sub images of 60*60 blocks.

However, when I am doing so, I am not getting the desired output.

My code:

clc;

clear all;
close all;

im = imread('C:\samples\test100.png');
subplot(3,3,1);
imshow(im);
title('original image');
im = rgb2gray(im);
im = double(im);

subplot(3,3,2);
imshow(im);
title('gray scale image');

[row col] = size(im);
max_im = max(max(im));
h = zeros(1,max_im+1);

!1st block
for n = 1:1:60
    for m = 1:1:60
        a(n,m) = im(n,m);
    end
end

a = a+1;
for n = 1:1:60
    for m = 1:1:60
        t = a(n,m);
        h(t) = h(t)+1;
    end
end

subplot(3,3,3);
bar(h)
[X,Y] = ginput(1);
for n = 1:1:60
    for m = 1:1:60
        if a(n,m)<X
            a(n,m) = 0;
        else
            a(n,m) = 255;
        end
    end
end

subplot(3,3,4);
imshow(uint8(a))
title('1st block image');

!2nd block
for n = 1:1:60
    for m = 61:1:60
        b(n,m-60) = im(n,m)
    end
end

b = b+1;
for n = 1:1:60
    for m = 1:1:60
        t = b(n,m);
        h(t) = h(t)+1;
    end
end

figure(2)
bar(h)
[X,Y] = ginput(1);
for n = 1:1:60
    if b(n,m)<X
        b(n,m) = 0;
    else
        b(n,m) = 255;
   end
end

imshow(uint8(b))

!3rd block
for n = 61:1:120
    for m = 1:1:60
        c(n-60,m) = im(n,m);
    end
end

c = c+1;
for n = 1:1:60
    for m = 1:1:60
        t = c(n,m);
        h(t) = h(t)+1;
    end
end

figure(3)
bar(h)
[X,Y] = ginput(1);
for n = 1:1:60
    for m = 1:1:60
        if c(n,m)< X
            c(n,m) = 0;
        else
            c(n,m) = 255;
        end
    end
end

imshow(uint8(c))

!final block

for n = 1:1:row
    for m = 61:1:col
        d(n-60,m-60) = im(n,m);
    end
end
d = d+1;
for n = 1:1:60
    for m = 1:1:60
        t = d(n,m);
        h(t) = h(t)+1;
    end
end
figure(4);

bar(h);
[X,Y] = ginput(1);
for n = 1:1:60
    for m = 1:1:60
        if d(n,m)<X
            d(n,m) = 0;
        else
            d(n,m) = 255;
        end
    end
end

imshow(uint8(d))
s = [a b;c d];

figure(5);
imshow(uint(s))

When I try to run the entire code I get an error as:

??? Undefined function or method 'local' for input arguments of type 'char'

However, when I run only the code for the 1st block I get the following output.

Enter image description here

How will I get the word Test visible by creating sub-images and then merging them together?

Upvotes: 0

Views: 9960

Answers (1)

clabacchio
clabacchio

Reputation: 1057

You can scan the greyscale image horizontally and then find the position of non-zero (or above the threshold) values and set that interval to be filled with white (256 or 1 if using im2double).

for j=1:551
    row = im(:,j)
    test = 0;
    im2=zeros(size(im))
    i=0;

    %Left black area
    while (test == 0 && i<919)
        im2(i,j)=0;
        if row(i)>threshold
            test=1;
        end;
        i=i+1;
    end;

    %White inner area
    while (test == 1 && i<919)
        im2(i,j)=1
        if row(i)>threshold
            test=0;
        end;
        i=i+1;
    end;

    %Left black area
    while (i<919)
        im2(i,j)=0;
        i=i+1;
    end;

This doesn't work with letters that have an empty area (such as 'p'), but you can modify the code a little to do that.

Upvotes: 2

Related Questions