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!