Local Thresholding in blocks error
1 次查看(过去 30 天)
显示 更早的评论
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
0 个评论
回答(2 个)
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')
Walter Roberson
2022-4-22
filename = 'football.jpg';
S = 3;
my_function(filename, S);
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
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]
Lbounds = cumsum([1, MNL])
and now block #K vertically would be rows Lbounds(K):Lbounds(K+1)-1
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Computer Vision with Simulink 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!