Filter löschen
Filter löschen

Local Thresholding in blocks error

2 Ansichten (letzte 30 Tage)
Joana Teixeira
Joana Teixeira am 1 Apr. 2022
Kommentiert: Walter Roberson am 22 Apr. 2022
I'm trying to do Local Thresholding. I have to divide an image into SxS blocks and then apply the thresholding. But I get the error "Index in position 2 exceeds array bounds (must not exceed 1).", I think it has something to do with my for loop. Can anyone help me? I would be very grateful.
Here is my code:
function []=my_function(filename,S)
IM=imread(filename);
if size(IM,3)==3
IC=rgb2gray(IM);
else
IC=IM;
end
TOtsu=graythresh(IC);
[NL,NC]=size(IC);
MNC=round(NC/S)*ones(S);
MNC(:,S)=NC-(S-1)*round(NC/S);
MNL=round(NL/S)*ones(S);
MNL(:,S)=NL-(S-1)*round(NL/S);
for f=1:S
for g=1:S
NLB=MNL(f,g); %lines of the block
NCB=MNC(f,g); %columns of the block
end
end
ICblocks=[NLB;NCB];
for i=1:NLB
for j=1:NCB
if var(ICblocks(i,j))<1 %image is uniform
if (ICblocks(i,j) < TOtsu)
IFinal(i,j) = 0;
elseif (ICblocks(i,j) > TOtsu)
IFinal(i,j) = 1;
end
else %image is not uniform
IFinal(i,j)=imbinarize(IC,TOtsu);
end
end
end
subplot(1,2,1);imshow(IC);title('IC')
subplot(1,2,2);imshow(IFinal);title('Threshold Local')
end

Antworten (2)

yanqi liu
yanqi liu am 2 Apr. 2022
yes,sir,may be check the loop process,such as
filename = 'football.jpg';
S = 3;
IM=imread(filename);
if size(IM,3)==3
IC=rgb2gray(IM);
else
IC=IM;
end
sz = size(IC);
TOtsu=graythresh(IC);
IFinal = [];
for f=0:S-1
for g=0:S-1
recti = round([sz(2)/S*f+1, sz(1)/S*g+1, sz(2)/S-1, sz(1)/S-1]);
ICfg = imcrop(IC, recti);
TOtsufg=graythresh(ICfg);
IFinal(recti(2):recti(2)+recti(4), recti(1):recti(1)+recti(3)) = imbinarize(ICfg,TOtsufg);
end
end
subplot(1,2,1);imshow(IC);title('IC')
subplot(1,2,2);imshow(IFinal);title('Threshold Local')
  1 Kommentar
Joana Teixeira
Joana Teixeira am 4 Apr. 2022
Hello! This code is changing the purpose that i want to do.

Melden Sie sich an, um zu kommentieren.


Walter Roberson
Walter Roberson am 22 Apr. 2022
filename = 'football.jpg';
S = 3;
my_function(filename, S);
Name Size Bytes Class Attributes IC 256x320 81920 uint8 ICblocks 2x1 16 double IM 256x320x3 245760 uint8 MNC 3x3 72 double MNL 3x3 72 double NC 1x1 8 double NCB 1x1 8 double NL 1x1 8 double NLB 1x1 8 double S 1x1 8 double TOtsu 1x1 8 double f 1x1 8 double filename 1x12 24 char g 1x1 8 double i 1x1 8 double j 1x1 8 double Name Size Bytes Class Attributes IC 256x320 81920 uint8 ICblocks 2x1 16 double IFinal 1x1 8 double IM 256x320x3 245760 uint8 MNC 3x3 72 double MNL 3x3 72 double NC 1x1 8 double NCB 1x1 8 double NL 1x1 8 double NLB 1x1 8 double S 1x1 8 double TOtsu 1x1 8 double f 1x1 8 double filename 1x12 24 char g 1x1 8 double i 1x1 8 double j 1x1 8 double
Index in position 2 exceeds array bounds. Index must not exceed 1.

Error in solution>my_function (line 34)
if var(ICblocks(i,j))<1 %image is uniform
function []=my_function(filename,S)
IM=imread(filename);
if size(IM,3)==3
IC=rgb2gray(IM);
else
IC=IM;
end
TOtsu=graythresh(IC);
[NL,NC]=size(IC);
MNC=round(NC/S)*ones(S);
MNC(:,S)=NC-(S-1)*round(NC/S);
MNL=round(NL/S)*ones(S);
MNL(:,S)=NL-(S-1)*round(NL/S);
for f=1:S
for g=1:S
NLB=MNL(f,g); %lines of the block
NCB=MNC(f,g); %columns of the block
end
end
Look at that loop. You are ovewriting all of NLB and all of NCB each iteration of the loops. f and g are each scalars, so you are overwriting them with scalars.
ICblocks=[NLB;NCB];
So after the loop, NLB and NCB are each scalars. You create a column vector from that, which is going to give you a 2 x 1 result in ICBlocks
for i=1:NLB
for j=1:NCB
NLB and NCB are each scalars -- the last entries in the MNL and MNC arrays.
whos
if var(ICblocks(i,j))<1 %image is uniform
and you use them to try to index ICblocks, which is 2 x 1.
if (ICblocks(i,j) < TOtsu)
IFinal(i,j) = 0;
elseif (ICblocks(i,j) > TOtsu)
IFinal(i,j) = 1;
end
else %image is not uniform
IFinal(i,j)=imbinarize(IC,TOtsu);
end
end
end
subplot(1,2,1);imshow(IC);title('IC')
subplot(1,2,2);imshow(IFinal);title('Threshold Local')
end
  1 Kommentar
Walter Roberson
Walter Roberson am 22 Apr. 2022
Your MNL and MNC arrays are calculating the number of row and columns to use for each block, taking into account that the image might not be an exact multiple of the block size. That calculation in itself is not a bad thing.
You later take var() of something. You obviously want to take the variance of a block extracted from the image. To do that you need to know the starting and ending column numbers of the block, and the starting and ending row numbers of the block. But your code does not calculate starting and ending row numbers. You could try calculating them by taking your index and multiplying by the block size (with a small offset), but if you do that, then you lose the advantage of having stored the sizes in the arrays.
I would suggest that you cumsum() the MNL and MNC with a starting offset of 1. For example,
MNL = [3 3 3 2]
MNL = 1×4
3 3 3 2
Lbounds = cumsum([1, MNL])
Lbounds = 1×5
1 4 7 10 12
and now block #K vertically would be rows Lbounds(K):Lbounds(K+1)-1

Melden Sie sich an, um zu kommentieren.

Produkte


Version

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by