MATLAB Canny edge detection: Maximum recursion limit of 500 reached - matlab

i'm getting this error
Maximum recursion limit of 500 reached
as I try to execute the function edge(img,'canny').
Fun fact is that the function is called within a script which worked til now (and now it doesn't).
I tried to increase the maximum iteration number ( set(0,'RecursionLimit,value) ) but if I try values too low it appears the same error, if I try values too high the system crashes.
What can I do?
--Update--
I tried to executed the edge() function without specifying 'canny'... This way it works, but I absolutely need the canny edge method!!
--Update--
It also works with the 'sobel' method. Could the problem be on 'canny'?
--Update--
Solved! The problem was a function I created this morning named "gradient" which overriden the function "gradient" called by the Canny Edge detector method

You didn't convert your image to black and white properly. The values stored in your 512 by 512 matrix are on the scale of 0 to 255. To reduce it to the black and white scale used by the edge() function simply divide by 255.
% Load data file
load('lenna512.mat')
% Scale to proper intensity range for the type double (0 to 1)
lenna512_bw = lenna512/255;
% Preview figure if it went alright
figure(1)
imshow(lenna512_bw);
% Detect the edges
edges_result = edge(lenna512_bw,'canny');
% Show result
figure(2)
imshow(result)
Note Intensity images of the type double have the range 0 to 1 while intensity images of type uint8 or uint16 have the range 0 to 255. So instead of using:
lenna512_bw = lenna512/255;
You could also use:
lenna512_bw = uint8(lenna512);
or
lenna512_bw = uint16(lenna512);
Converting the matrix to the type uint8 or uint16 while having the appropriate range for these types set to 0 to 255 as already available in your matrix.
More on imagetypes here and on numerical types here
Good luck!
The resulting images:

Related

max of images correlation with xcorr2 shifted by 2 pixels compared to imfilter

preparing lab code for real-time fixed point implementation, I wrote the following function
function res = imcorr(inIm,kernel)
% res=imfilter(inIm,kernel,'replicate'); %initial implementation
% res=imfilter(inIm,kernel); %same as we crop the result below
res=xcorr2(inIm,kernel); %faster, works with singles, but shifts result by 2 pixels
s=size(inIm);
rect=[fix((size(res,2)-s(2))/2), fix((size(res,1)-s(1))/2), s(2), s(1)];
res=imcrop(res,rect);
then I used the code from https://gist.github.com/goulu/ba70175f870fdb2c25e3 ( edited from http://www.mathworks.com/help/signal/ref/xcorr2.html ) as testbench and noticed there is a 2 pixels shift in both directions between the results obtained by xcorr2 and imfilter:
where does this come from ?
don't know exactly why but it seems imfilter and xcorr2 do rounding differently with odd/even image sizes, so finally I could obtain the same results by cropping like this :
rect=[(size(res,2)-s(2))/2+1.5 (size(res,1)-s(1))/2+1.5 s(2)-1-yoff s(1)-1-xoff];
res=imcrop(res,fix(rect));

regionprops() is giving an error in matlab

I'm using regionprops() but I'm getting an error with the following code:
J = imread('E:\Canopy New Exp\Data Set\input.jpg');
I = rgb2gray(J);
BW = regionprops(J,'basic');
stats = regionprops('table',BW,'Centroid',...
'MajorAxisLength','MinorAxisLength');
centers = stats.Centroid;
diameters = mean([stats.MajorAxisLength stats.MinorAxisLength],2);
radii = diameters/2;
hold on;
viscircles(centers,radii);
hold off;
But I'm getting the following error:
Error using regionprops
Expected input number 1, L, to be one of these types:
double, single, uint8, uint16, uint32, uint64, int8, int16, int32, int64
Instead its type was char.
Error in regionprops (line 142)
validateattributes(L, {'numeric'}, ...
Error in Untitled (line 8)
stats = regionprops('table',BW,'Centroid',...
Any suggestions?
Thanks in advance!
You are doing regionprops twice, and the second time with 'table' as the first parameter. regionprops expects an image (black and white, connected components, or labelled) as the first parameter, so that is why you are getting the error type char.
Instead feed in a black and white (binary) image to one call of regionprops, and that should be done:
thresh = graythresh(I); % get a threshold (you could just pick one)
I_BW = im2bw(I,thresh); % make the image binary with the given threshold
stats = regionprops(I_BW,'basic'); % do regionprops on the thresholded image
You can also do regionprops with 2 image parameters, one to show the regions in the other, so instead of the regionprops call above, you could possibly try:
stats = regionprops(I_BW, J, 'basic');
regionprops outputs an object so in the third line of the above code sample you call it on J, an image, which is fine and returns an appropriate object BW. But then in the following line you call it again on the BW object and that's where the error comes from. It isn't meaningful to call it twice on successive objects, but it's more likely that that wasn't your intention and you meant to binarise the image first with im2bw.
When you read the error messages output by matlab be aware that the bottom line is the line in your code where the error occurred. If you are supplying the wrong kind of input to one of matlab's builtin functions (this is by far the most common kind of error in my own experience) then it won't be until you've gone deeper into matlab's internal functions that the error manifests.
So reading the error report from the bottom upwards you go deeper into the call stack until the top line, which is the 'actual' error. That top line gives you the cause of the conflict, which is half the story. You can then take that half back to the line of your code to see why it happened and how to fix it.
You're probably feeding it a RGB array NxMx3. regionprops takes a NxM binary array according to the documentation.

Why does MATLABs "imwrite" scale 12-bit images and how to circumvent this?

I have an image given as an N x M - matrix with 12-bit data and I want to use imwrite to save the image as a .pgm file.
Why does MATLAB scale the image to 16bit? How can I circumvent this?
Using the 'MaxValue' argument also seems to alter the image, as it can't be displayed properly afterwards e.g. in IrfanView.
The MaxValue parameter is a little counter intuitive. It does specify to write the PGM tagged with a max value of a certain depth (e.g. 12-bit here), but it also tells iwwrite to rescale the data. The rescaling happens in writepnm>remap_pixel_values:
function newdata = remap_pixel_values(data, maxval)
%REMAP_PIXEL_VALUES Remap pixel values in array of pixel values.
%
% NEWDATA = REMAP_PIXEL_VALUES(DATA, MAXVAL) remaps the pixel values in
% DATA as follows
%
% Class of DATA Input Output
% ------------- ----- ------
% uint8 The set {0,1,...,255} The set {0,1,...,maxval}
% uint16 The set {0,1,...,65535} The set {0,1,...,maxval}
% double The interval [0,1] The set {0,1,...,maxval}
So with uint16 data, it will rescale the data by applying a scale of 65535/maxval via the bit shift bitshift(data,-4);. You don't want it to rescale the data, but you also want it to write the file as 12-bit (this happens in writepnm>write_raw_data. The workaround is to apply the opposite scale before calling imwrite:
Iscaled = uint16(double(I)*(2^16-1)/(2^12-1))
imwrite(Iscaled,'test.pgm','MaxValue',2^12-1)
Note that you could use double values scaled between [0,1] too, according to the table in the above code comments.
For reading 12-bit PGM/PPM, see here.

column to block using sliding window in matlab

using im2col sliding window in matlab i have converted the input image block into column and again by using col2im i do the inverse process but the output is not same as the input image. How can i recover the input image? can anyone please help me.
Here is the code
in=imread('tire.tif');
[mm nn]=size(in);
m=8;n=8;
figure,imshow(in);
i1=im2col(in,[8 8],'sliding');
i2 = reshape( sum(i1),mm-m+1,nn-n+1);
out=col2im(i2,[m n],[mm nn],'sliding');
figure,imshow(out,[]);
thanks in advance...
You didn't specify exactly what the problem is, but I see a few potential sources:
You shouldn't expect the output to be exactly the same as the input, since you're replacing each pixel value with the sum of pixels in an 8-by-8 neighborhood. Also, you will get a shrinkage of the resulting image by 7 pixels in each direction (i.e. [m-1 n-1]) since the 'sliding' option of IM2COL does not pad the array with zeroes to create neighborhoods for pixels near the edges.
These two lines are redundant:
i2 = reshape( sum(i1),mm-m+1,nn-n+1);
out=col2im(i2,[m n],[mm nn],'sliding');
You only need one or the other, not both:
%# Use this:
out = reshape(sum(i1),mm-m+1,nn-n+1);
%# OR this:
out = col2im(sum(i1),[m n],[mm nn],'sliding');
Image data in MATLAB is typically of type 'uint8', meaning each pixel is represented as an unsigned 8-bit integer spanning the range 0 to 255. Assuming this is what in is, when you perform your sum operation you will implicitly end up converting it to type 'double' (since an unsigned 8-bit integer will likely not be big enough to hold the sum totals). When image pixel values are represented with a double type, the pixel values are expected to span the range 0 to 1, so you will want to scale your resulting image by its maximum value to get it to display properly:
out = out./max(out(:));
Lastly, check what kind of input image you are using. For your code, you are essentially assuming in is 2-D (i.e. a grayscale intensity image). If it is a truecolor (i.e. RGB) image, the third dimension is going to cause you some trouble, and you will have to either process each color plane separately and recombine them or convert the RGB image to grayscale. If it is an indexed image (with an associated color map), you will not be able to do the sort of processing you describe above without first converting it to a grayscale representation.
Why are you expecting the output to be the same?
i2 is the result of performing a SUM around a pixel neighborhood (essentially a low-pass filter), which is the final blurry image that you see. i.e you are NOT doing an inverse process with the COL2IM call.
i1 obtained from 'sliding' option has the information that you would get from 'distinct' option as well, which you need to filter out. Now, this may not be the best way to code it up but it works. Assume that mm is a multiple of m and nn is a multiple of n. If this is not the case, then you'll have to zero-pad accordingly to make this the case.
in=imread('tire.tif');
[mm nn]=size(in);
m=8;n=8;
i1 = im2col(in,[m,n],'sliding');
inSel = [];
for k=0:mm/m-1
inSel = [inSel 1:n:nn+(nn-n+1)*n*k];
end
out = col2im(i1(:,inSel),[m,n],[mm,nn],'distinct');

How to average multiple images in matlab?

I am trying to get the average image from 1000 frames.
Each image is 512 by 512 pixel size.The file I got from the experiments is a tiff unit 16 data.
the tiff file contains 1000 frames of the same spot.
I was thinking writing a m file where I read out 1000 frames from the tiff file then average them but it seems will eat up the memory very fast.
What is the better way to get the average image of these 1000 frames. If the only way is to average them after load all the frames into matlab, how should I average over 1000 frames?
Thanks.
try the following:
a=zeros(512);
for i=1:1000
a=a+frame(i);
end
a=a/1000;
a is the average of the frames.
After each image is read you can accumulate it in the temporary variable, i.e. add current image to this variable at each step. After you read all images the accumulator will store the sum of all images. Finally, divide it by the number of images and you will get final image.
But it is significant that images are usually stored as uint8 (unsigned 8-bit integer). And if it is summed up, the overflow will occur. To prevent this accumulator should be e.g. uint32 or double. If you want the final image to be uint8, an explicit convertion is required.
% slight modiifcations to the last answer
if the files are named image1.tif, image2.tif,....image1000.tif)
im = imread('image1.tif');
for i = 2:1000
im = imadd(im,imread(sprintf('image%d.tif',i)));
end
im = im/1000;
imshow(im,[]);
The problem gets interesting when you have names like image00001, image00002,....image00010,...image00100,.... here just read from 2-10 in one loop 11-99 in another and so so...hope it helps
source = 'D:\file_path\'; %'
im_number=262; % image number should not exceed 16 843 009 images
sum=uint32(imread([source,'image1.bmp'],'bmp')); % converts image array to Unsigned 32-bit integer to escape overflow
for n=2:im_number;
sum=imadd(sum,uint32(imread([source,'image', num2str(n),'.bmp'],'bmp'))); % perform addition without overflow
% using images specific function imadd
end;
sum = imdivide(sum,im_number); % performing normalization of addition using images specific function imdivide
imshow(uint8(sum),[]); % displais the image converted back to Unsigned 8-bit integer
imwrite(uint8(sum),[source,'sum_image.bmp'],'bmp'); % saves the averaged image
% assuming there are files named: '1.tif','2.tif',...'1000.tif'
im = imread('1.tif');
for i = 2:1000
im = imadd(im,imread(sprintf('%d.tif',i)));
end
im = im/1000;
imshow(im,[]);
J=0;
for i =1:index %index is the number of images to be averaged
I=uint32(imread(['frame',num2str(i),'.bmp']));
J=imadd(I,J);
end
J=floor(J/index);
J=uint16(J); %J is the required image