Empty for loop index variable

4 views (last 30 days)
Hello everyone,
I am relatively new to Matlab and am using the R2015a version. I am trying to identify the lowermost boundary of a dark region which is spreading over a white background (Image attached for representation). The boundary is defined by spotting the intensity gradient in the image. Below is the code which has been working satisfactorily for me.
w=imread('C:\Users\Downloads\Spilt ink.jpg');
row_no=size(w,1); %image height
col_no=size(w,2); %image width
w_red=w(:,:,1);
count=0;
term=0;
axis on
subplot(1,2,1), imshow(w), title('Original linked image', 'FontSize', 14);
subplot(1,2,2), imshow(w_red), title('Image with line mask', 'FontSize', 14);
for i=(col_no-10):-1:2 %no. of columns (counted horizontally)
for j=(row_no-10):-1:2 %no. of rows (counted vertically)
if(abs(w_red(j,i)-w_red(j,i-1))>12)
count=count+1;
end
if(count>(0.05*row_no))
hold on
burnedImage = w;
% Creating line mask over the already existing second image
subplot(1, 2, 2);
hLine = imline(gca,[i i],[(row_no-10) 10]);
term=1;
end
if(term==1)
i
break % To get out of inner loop
end
end
count=0;
if(term==1)
break % To get out of upper for loop
end
end
I want to implement the same code for a video. So far, I have extracted the individual frames from the video and I use the code above to display images of a line burned into the original frame- which didn't happen. When I tried troubleshooting the code, I noticed this.
Name Size Bytes Class Attributes
i 0x0 0 double
The variable i (now inside another for loop meant for iterating frames) is completely blank, which never happened in the previous code.
This is what the already mentioned code looks like inside the loop. Kindly note that this a truncated part of the code.
for frame = 1 : numberOfFrames
thisFrame = read(videoObject, frame);
hImage = subplot(1, 2, 2);
w=image(thisFrame);
row_no=size(w,1); %image height
col_no=size(w,2); %image width
w_red=w(:,:,1);
count=0;
term=0;
for i=(col_no-10):-1:2 %no. of columns (counted horizontally)
for j=(row_no-10):-1:2 %no. of rows (counted vertically)
if(abs(w_red(j,i)-w_red(j,i-1))>12)
count=count+1;
end
if(count>(0.05*row_no))
hold on
burnedImage = w;
% Creating line mask over the already existing second image
subplot(1, 2, 2);
hLine = imline(gca,[i i],[(row_no-10) 10]);
term=1;
end
if(term==1)
i
break % To get out of inner loop
end
end
count=0;
if(term==1)
break % To get out of upper for loop
end
end
The remainder of the code is derived from an existing program linked here (https://in.mathworks.com/matlabcentral/fileexchange/47726-video-processing-tutorial)
I can't point where I'm going wrong, hence would really appreciate some help.
  2 Comments
Guillaume
Guillaume on 7 Jan 2020
Obvious question: What is the value of col_no when the code fails. If it's less than 12, i will indeed be empty.
On the other hand, the double loop is completely unneeded. You can replace the whole lot with:
%Note: In the diff call below, I'm using the same bounds as your for loops. It's not clear why the first row and last 10 rows or the last 10 columns are ignored
gradient = diff(w_red(2:end-10, 1:end-10), [], 2); %difference betweeen pixel and preceding one in each row
abovethreshold = sum(abs(gradient) > 12) > 0.05 * size(w, 1);
selectedcolumn = find(abovethreshold, 1, 'last') + 1; %only want the last column that is above threshold
%draw the line as you did
subplot(1, 2, 2);
hline = imline(gca, [selectedcolumn, selectedcolumn], [size(w, 1) - 10, 10]);
Abhilash Nair
Abhilash Nair on 8 Jan 2020
Edited: Abhilash Nair on 8 Jan 2020
Thank you so much. I failed to notice that col_no was trying to obtain a value from the matrix w which is of class 'matlab.graphics.primitive.Image'. Also appreciate you making the code neater, I shall modify the code to this soon.
I have encountered another problem though. I tried burning a line mask into the selected column of the redscale image (so that I can save that image with the line separately).
for frame = 1 : numberOfFrames
thisFrame = read(videoObject, frame);
row_no=size(thisFrame,1); %image height
col_no=size(thisFrame,2); %image width
w_red=thisFrame(:,:,1);
count=0;
term=0;
himage=subplot(1, 2, 1);
title('Redscale image','FontSize', 14);
imshow(w_red);
for i=(col_no-10):-1:2 %no. of columns (counted horizontally)
for j=(row_no-10):-1:2 %no. of rows (counted vertically)
if(abs(w_red(j,i)-w_red(j,i-1))>12)
count=count+1;
end
if(count>(0.05*row_no))
hold on
burnedImage = w_red;
% Creating line mask over the already existing second image
subplot(1, 2, 1);
hLine = imline(gca,[i i],[(row_no-10) 10]);
% Creating a binary mask from hLine.
binaryImage = hLine.createMask();
subplot(1, 2, 2);
burnedImage(binaryImage)=255;
imshow(burnedImage);
title('Image with line mask','FontSize', 14);
term=1;
end
if(term==1)
i
break % To get out of inner loop
end
end
count=0;
if(term==1)
break % To get out of upper for loop
end
end
I've ensured that the subplot chosen is of a 2-D array, redscale image. However, I've encountered this error.
Error using imroi/parseInputsForCreateMask (line 97)
Ambiguous syntax. Associated axes contains more than one image. Specify image handle as input argument to resolve ambiguity.
Type "help imroi/createMask" for more information.
Error in imline/createMask (line 165)
[obj,h_im] = parseInputsForCreateMask(varargin{:});
Error in linetracker3 (line 95)
binaryImage = hLine.createMask();
As far as I am aware, masks only work for monochrome images and w_red is one. Could you please point out where I could be going wrong?

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 8 Jan 2020
Just before title('Redscale image','FontSize', 14); you switch to subplot axes 1. Then you imshow(w_red); which draws an image in that subplot 1 axes. Then
if(count>(0.05*row_no))
hold on
so you turn hold on for subplot 1 axes.
Now, inside the double nested for loop over rows and columns, you do not create any additional images in subplot 1 axes. But eventually you finish those two loops, and you proceed to the next for frame iteration, where you do
himage=subplot(1, 2, 1);
title('Redscale image','FontSize', 14);
imshow(w_red);
so you switch to subplot 1 axes, and you imshow() on that axes. But hold is still on for that axes, so now you will have two images in the axes -- the one for frame #1, and the one for frame #2. Now imline gets confused about which image you want to draw the line for.
  1 Comment
Abhilash Nair
Abhilash Nair on 8 Jan 2020
Thank you! I just switched from hold on to hold off and now the code is giving meaningful data.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!