How to apply fluorescent filtering on an already working edge detection code?

Hi all, back again!
I have a really great piece of code for edge detection (see attached) however prior to getting it working, my previous code created fluorescent style images such as attached. The code for it is seen here:
"
Function Vid_Edge_Detection_flourescent
v = VideoReader('VID00125.AVI');
n = v.NumFrames;
for i = 1:n
I0 = read(v,i);
I1 = im2bw(I0,graythresh(I0)-0.03); % binarize image with treshold
I2 = bwareaopen(I1,50); % remove small regions (50 pixels)
I3 = edge(I2);
II = imfuse(I0,I3);
imshow(II,'initialmagnification','fit')
pause(0.1)
end
end
"
From what I understand, the old code produced a double layer, the background one being altered to a green background and the forground being the edge detection. Essentially, I'm trying to get the same thing for the new attached code but because of all the for loops, I really have no idea where/what to change. Can anyone assist?
Thanks in advance,
Ben

 Accepted Answer

Not sure what you want. Do you just want the edges overlaid on the original image frames, perhaps in some specified color, like magenta? Do you want the main image converted to grayscale and then put into the green channel while the edges to into the blue and red channel? Like this:
rgbImage = cat(3, edgeImage, rgb2gray(thisFrame), edgeImage);
where thisFrame is the original RGB image, and edgeImage is a grayscale image with values of 0 and 255 only?

6 Comments

Hi again!
Apologies, the initial query wasnt structured superbly. Ideally id like something like the photo in the original post, where like you said, the edge detection is used ontop of the original image frames as an overlay. Magenta or any other colour works as long as a clear contrast is visible, hence the reason why I thought a green (fluorescent style) background was the best way to go.
Thanks again!
Ben: So what was wrong with my suggestion? Doesn't it look like the image you wanted? If not, why not?
rgbImage = imread('peppers.png');
subplot(2, 2, 1);
imshow(rgbImage);
title('Original RGB Image', 'FontSize', 15);
grayImage = rgb2gray(rgbImage);
subplot(2, 2, 2);
imshow(grayImage);
title('Gray Scale Image', 'FontSize', 15);
edgeImage = edge(grayImage, 'Canny');
% Thicken the edges a bit to make them more visible.
edgeImage = imdilate(edgeImage, true(3));
% Make uint8
edgeImage = 255 * uint8(edgeImage);
subplot(2, 2, 3);
imshow(edgeImage);
title('Edge Image', 'FontSize', 15);
rgbImage2 = cat(3, edgeImage, grayImage, edgeImage);
subplot(2, 2, 4);
imshow(rgbImage2);
title('Final RGB Image', 'FontSize', 15);
Here was your example below. Why is mine above not right?
So your ending product is perfect! The only thing I am having trouble with is applying it into a video processing format. I have been attempting to place the line of code you suggested into Test.4, though it is being rejected due to these errors:
"
Error using rgb2gray>parse_inputs (line 80)
MAP must be a m x 3 array.
Error in rgb2gray (line 52)
isRGB = parse_inputs(X);
Error in Test_4 (line 75)
grayImage = rgb2gray(rgbImage);
"
Evidently it's not an rgb image. So you can't call rgb2gray(). So just check for that
if size(rgbImage, 3) == 3
grayImage = rgb2gray(rgbImage);
else
grayImage = rgbImage;
end
Apologies for the daft questions, I'm still very much new to video processing. I get why you've changed the image size but im not too sure why the rgbImage wont work, because its greyscaled?
More importatly, Ive meddled around with the for loop where I think youre suggested code is supposed to go, but it wont recognise 'rgbImage' despite me changing it. I feel that I've overlapped some old and new code but havent clicked to what it is..
"
for frame = 1 : numberOfFrames
% Extract the frame from the movie structure.
% thisFrame = read(videoReaderObject, frame);
I0 = read(videoReaderObject, frame);
rgbImage = I0;
if size(rgbImage, 3) == 3
grayImage = rgb2gray(rgbImage);
else
grayImage = rgbImage;
end
I1 = im2bw(I0,graythresh(I0)-0.03); % binarize image with threshold
I2 = bwareaopen(I1,50); % remove small regions (50 pixels)
grayImage = rgb2gray(rgbImage);
thisFrame = edge(grayImage, 'Canny');
edgeImage = imdilate(edgeImage, true(3));
edgeImage = 255 * uint8(edgeImage);
thisFrame = uint8(255 * thisFrame);
% Make RGB
thisFrame = cat(3, edgeImage, grayImage, edgeImage);
"
It simply says Unrecognized function or variable 'rgbImage'.
Error in Test_4 (line 65)
if size(rgbImage, 3) == 3
Thank you as always, youve been a great help!
Hi again!
Still having trouble with the rbg2gray part. Though I did manage to figure out the other two sections of the cat function working (see below). Even if I change the final, middle part to grayImage instead of rgb2gray, it wont work. Could I ask what the appropriate lines are to get the correct background?
% Extract the frame from the movie structure.
% thisFrame = read(videoReaderObject, frame);
I0 = read(videoReaderObject, frame);
I1 = im2bw(I0,graythresh(I0)-0.03); % binarize image with threshold
I2 = bwareaopen(I1,50) ; % remove small regions (50 pixels)
%edgeImage = edge(grayImage, 'Canny');
I3 = edge(I2);
% Thicken the edges a bit to make them more visible.
thisFrame = I3;
thisFrame = imdilate(I3, true(3));
% Make uint8
thisFrame = uint8(255 * thisFrame);
rgbImage = I0;
if size(rgbImage, 3) == 3
grayImage = rgb2gray(rgbImage);
else
grayImage = rgbImage;
end
% Make RGB
thisFrame = cat(3, I3, rgb2gray(thisFrame), I3);

Sign in to comment.

More Answers (1)

Figured it out for future users. You simply change the middle thisFrame to grayImage as seen below:
thisFrame = cat(3, thisFrame, (grayImage), I3);
The bold ones can seemingly change the the colour of the edge detection lines, will definitely play around with it more.
Once again thank you for the assistance Image Analyst, couldn't have done it without you.

4 Comments

Looks weird to me. thisFrame if probable a 3-D RGB color image, so that's 3 channels. Then you're concatenating a gray image and an edge image onto it. That should make a 5 channel image, not a 3 channel RGB image. Even if thisFrame were gray scale (same as grayImage), it would be RGB but the edges would be only in the blue channel with the gray scale image in the red and green channel. This would appear as a yellow image with blue outlines on it, not a green image with magenta outlines like you wanted.
I just changed I3 to thisFrame and it seems to have corrected the colour to magenta as seen attached. From my eyes it seems to have done the job though I'm not the specialist here!
Back again! Thought it was probably best to comment on this again to save time. It seems that once I run the code it works up until the prompt "Do you want to recall the individual frames as a movie". Which then works for a certain number of frames within the video (this varies) and then produces this error:
"
Error using VideoWriter/writeVideo (line 368)
Frame must be 964 by 544
Error in Test_3 (line 284)
writeVideo(videoWriterObject, thisFrame);
"
I have absolutely no clue why it is doing this despite efforts to find out. Could you/anyone else advise?
See attached for the file. Any AVI should work, thanks as always..
It's probably recalling a still image that's not the same size as the others that it has been using to build the movie with so far. Check the size of thisFrame and see what it is for each frame, like
fprintf('For %s\n Frame #%d, rows = %d, columns = %d\n', ...', ...
outputFullFileName, frame, size(thisFrame, 1), size(thisFrame, 2));
When if throws the error, look in the command window for what it said for all the frames up to that point.

Sign in to comment.

Categories

Find more on Convert Image Type in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!