Local Thresholding in blocks error

2 ビュー (過去 30 日間)
Joana Teixeira
Joana Teixeira 2022 年 4 月 1 日
コメント済み: Walter Roberson 2022 年 4 月 22 日
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

回答 (2 件)

yanqi liu
yanqi liu 2022 年 4 月 2 日
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 件のコメント
Joana Teixeira
Joana Teixeira 2022 年 4 月 4 日
Hello! This code is changing the purpose that i want to do.

サインインしてコメントする。


Walter Roberson
Walter Roberson 2022 年 4 月 22 日
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 件のコメント
Walter Roberson
Walter Roberson 2022 年 4 月 22 日
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

サインインしてコメントする。

製品


リリース

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by