Edge detection using Convolution
Afficher commentaires plus anciens
I am trying to detect the edges in an image using convolution. Tried this but get error " final_lena does not look like it has the correct dimensions."
smooth_image = conv2(single(lena), F, 'same');
vert_ = conv2(single(smooth_image), gx, 'same');
hor_ = conv2(single(smooth_image), gy, 'same');
final_lena = sqrt(vert_.^2 + hor_.^2);
Réponses (2)
What exactly is throwing that error? That's not an error from conv2(). Is this a part of something that's being auto-graded?
I don't know what sort of filters you chose or which variation of the lena image you're working with. It may simply be that the grader presumes a different source image geometry or something. The one I'm using is 512x512 RGB.
How you choose to reduce the RGB image to grayscale will change the resultant pixel values, so if the grader expects you to convert to a particular brightness measure, you'd need to use that. The rgb2gray() uses BT601 luma (Y). Otherwise, see:
Similarly, if the grader expects you to use a particular filter kernel(s), then your result values will differ if you don't. Since it's left up to me, I'm just going to use a prenormalized Scharr filter so that the gradient magnitude stays within the unit interval. You can use a regular Sobel or whatever you want, but bear in mind that your resulting gradient magnitude image will be on the interval [0 4.5] instead of [0 1]. There may be some expectation that you clamp or rescale the result.
Lastly, use im2single() instead of single(). Many tools (e.g. imshow(), imwrite()) presume a nominal data range based on the class of the array. For floating point images, the nominal data range is [0 1]. When you do single() on a uint8 array, it only casts the data, but its data range is still [0 255], and so it'll be interpreted as being out of range (whiter than white). Using im2double(), im2single(), im2uint8(), etc handles both casting and rescaling.
% note that i had to spoof the file extension to upload a TIFF
% you shouldn't have to do that on desktop
lena = imread('lena.tif.txt'); % RGB
lena = rgb2gray(lena); % convert to BT601 luma
% prenormalized scharr filter
% this is prenormalized for 2-pass gradient estimation
a = 0.155140;
b = 0.534738;
fk = [a b a; 0 0 0; -a -b -a];
% 3x3 gaussian
a = 0.003744;
b = 0.970049;
fkg = [a a a; a b a; a a a];
% use im2double()/im2single() instead of double()/single()
smooth_image = conv2(im2single(lena), fkg, 'same');
% smooth_image is already class 'single'
vert_ = conv2(smooth_image, fk.', 'same'); % d/dx
hor_ = conv2(smooth_image, fk, 'same'); % d/dy
final_lena = sqrt(vert_.^2 + hor_.^2); % gradient magnitude
imshow(final_lena)
There's also the possibility that the grader doesn't expect you to use the 'same' flags with conv2(), though that seems kind of odd that you wouldn't.
2 commentaires
Ken
le 20 Avr 2022
I don't know what to say. I almost wonder if the error message is being incorrectly given (i.e. that the actual error has nothing to do with the dimensions). The image is already grayscale, so it's not a question of gray conversion. You have filter kernels specified. It only makes sense that you'd use the 'same' flag with conv2(), and certainly the result is the same size. You need to make sure the output is rescaled correct for its class before you display or save it, but other than that, I don't know what it's complaining about.
You might want to ask your TA or whoever is administering this for some sort of clarification, because otherwise I think we'd both be guessing from this point forward.
% read image and convert it to a double
lena = imread('https://courses.edx.org/c4x/ETHx/AMRx/asset/lena.jpg');
% you can cast without rescaling, but be careful what you do
% while the image is in this improperly-scaled state
lena = double(lena);
% ---- Filters ----------------------
% filter to detect horizontal edges
gx = [1;0;-1]./sqrt(2);
% filter to detect vertical edges
gy = [1 0 -1]./sqrt(2);
% smoothing filter
F = [1 4 6 4 1; 4 16 24 16 4; 6 24 36 24 6; 4 16 24 16 4; 1 4 6 4 1];
F = F./norm(F);
smooth_image = conv2(lena, F, 'same');
vert_ = conv2(smooth_image, gx, 'same');
hor_ = conv2(smooth_image, gy, 'same');
final_lena = sqrt(vert_.^2 + hor_.^2);
final_lena = uint8(final_lena);
imshow(final_lena)
Image Analyst
le 20 Avr 2022
Try this. There are no errors.
%============================================================================================================================================
% Initialization Steps.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 15;
markerSize = 40;
% read image and convert it to a double
rgbImage = imread('lenaColor.png');
subplot(3, 3, 1);
imshow(rgbImage, 'Border', 'tight')
impixelinfo;
axis('on', 'image');
title('Original Image', 'fontSize', fontSize, 'Interpreter','none');
[rows, columns, numberOfColorChannels] = size(rgbImage);
% Get the gray scale image.
if numberOfColorChannels == 3
grayImage = rgb2gray(rgbImage);
else
grayImage = rgbImage;
end
grayImage = double(grayImage);
subplot(3, 3, 2);
imshow(grayImage, [], 'Border', 'tight')
impixelinfo;
axis('on', 'image');
title('Gray Scale Image', 'fontSize', fontSize, 'Interpreter','none');
% ---- Filters ----------------------
% filter to detect horizontal edges
gx = [1;0;-1]./sqrt(2);
% filter to detect vertical edges
gy = [1 0 -1]./sqrt(2);
% smoothing filter
F = [1 4 6 4 1; 4 16 24 16 4; 6 24 36 24 6; 4 16 24 16 4; 1 4 6 4 1];
F = F./norm(F)
subplot(3, 3, 3);
imshow(F, [], 'Border', 'tight')
impixelinfo;
axis('on', 'image');
title('Smoothing Filter Image', 'fontSize', fontSize, 'Interpreter','none');
% Convolve with filter F to blur the image.
smooth_image = conv2(single(grayImage), F, 'same');
subplot(3, 3, 4);
imshow(smooth_image, [], 'Border', 'tight')
impixelinfo;
axis('on', 'image');
title('Blurred smooth_image Image', 'fontSize', fontSize, 'Interpreter','none');
verticalEdgeImage = conv2(single(smooth_image), gx, 'same');
subplot(3, 3, 5);
imshow(verticalEdgeImage, [], 'Border', 'tight')
impixelinfo;
axis('on', 'image');
title('verticalEdgeImage', 'fontSize', fontSize, 'Interpreter','none');
horizontalEdgeImage = conv2(single(smooth_image), gy, 'same');
subplot(3, 3, 6);
imshow(horizontalEdgeImage, [], 'Border', 'tight')
impixelinfo;
axis('on', 'image');
title('horizontalEdgeImage', 'fontSize', fontSize, 'Interpreter','none');
% Magnitude of images, like you could get directly from imgradient().
final_lena = sqrt(verticalEdgeImage.^2 + horizontalEdgeImage.^2);
subplot(3, 3, 7);
imshow(final_lena, [], 'Border', 'tight')
impixelinfo;
axis('on', 'image');
title('final_lena Image', 'fontSize', fontSize, 'Interpreter','none');
g = gcf;
g.WindowState = 'maximized';

19 commentaires
Ken
le 20 Avr 2022
Image Analyst
le 20 Avr 2022
Well you either have to use the one I attached (and you forgot to download) or you have to change the name to the filename of yours.
Ken
le 21 Avr 2022
Image Analyst
le 21 Avr 2022
I don't know who or what generated that comment. Perhaps a TA is telling you that you're not supposed to use the built in conv2 function or something.
Or it could be that the filter F is supposed to be the Sobel filter kernel which will do an edge detection instead of the filter you used which is used to slightly blur the image, not enhance/find edges in it.
Ken
le 21 Avr 2022
Image Analyst
le 21 Avr 2022
OK, that's what I thought. You don't even need the F matrix or the convolution using it. You computed it wrong anyway.
DGM
le 21 Avr 2022
The way I read it, the problem statement is specifying to use to use those filter kernels. F doesn't make sense to me either, but why would it be given that way unless the purpose is to mislead the student?
Image Analyst
le 21 Avr 2022
Oh, maybe. I thought the code was code @Ken wrote, not code that was part of the problem. If it's part of the problem, then so be it, but that F kernel is a blurring kernel, not an edge finding kernel.
Or maybe they want you to use the 'full' convolution option instead of 'same'. Perhaps that will get the message to go away. Was the message something somebody, like your professor manually wrote? Or was it automatically generated by some grading program when you submitted your code?
Ken
le 21 Avr 2022
Ken
le 21 Avr 2022
Oh, I forgot your derivative filters aren't 3x3. You could make them symmetric and it would run, but I still have no idea if that's right. I have to wonder about the normalization of the filters. F isn't sum-normalized, and expanding gx,gy to make them symmetric will increase the range of the gradient estimate unless they're scaled accordingly.
% read image and convert it to a double
lena = imread('https://courses.edx.org/c4x/ETHx/AMRx/asset/lena.jpg');
% you can cast without rescaling, but be careful what you do
% while the image is in this improperly-scaled state
lena = double(lena);
% ---- Filters ----------------------
% filter to detect horizontal edges
gx = [1;0;-1]./sqrt(2);
% filter to detect vertical edges
gy = [1 0 -1]./sqrt(2);
% smoothing filter
F = [1 4 6 4 1; 4 16 24 16 4; 6 24 36 24 6; 4 16 24 16 4; 1 4 6 4 1];
F = F./norm(F);
smooth_image = conv2(lena, F, 'full');
vert_ = conv2(smooth_image, [gx gx gx], 'full');
hor_ = conv2(smooth_image, [gy;gy;gy], 'full');
final_lena = sqrt(vert_.^2 + hor_.^2);
final_lena = uint8(final_lena);
imshow(final_lena)
I figured the blur was just an attempt to suppress noise.
Ken
le 22 Avr 2022
Image Analyst
le 22 Avr 2022
Who is this mysterious "grader" ? A real live person or an automated computer grader? Like I said, I ran the code (my code) and it ran fine with no error whatsoever.
Ken
le 26 Avr 2022
Ken
le 26 Avr 2022
That still sounds like so much baloney. Even if you did exactly what they're telling you to do, your output image would still be 518x518, which is the same size as it would have been before if you simply omitted the 'same' flags, which (if I recall) has already been tried without success. If you replicate the derivative filters so that they're square, the output would be 520x520, but there's no suggestion that that was ever intended (well it was never suggested that the filters be combined either)...
I guess you could convolve them together? I don't really know whether you're still trying to calculate gradient magnitude or what you're supposed to do with this combined filter. For sake of demonstration, consider the results with an image full of circular edges. Note the behavior
lena = imread('circlesBrightDark.png');
lena = double(lena);
% ---- Filters ----------------------
% filter to detect horizontal edges
gx = [1;0;-1]./sqrt(2);
% filter to detect vertical edges
gy = [1 0 -1]./sqrt(2);
% smoothing filter
F = [1 4 6 4 1; 4 16 24 16 4; 6 24 36 24 6; 4 16 24 16 4; 1 4 6 4 1];
F = F./norm(F);
% 518x518 using old way without 'same'
%fk = conv2(gx, gy); % makes result 518x518
fk = conv2([gx gx gx], [gy; gy; gy]); % makes result 520x520
fk = conv2(fk, F);
% single pass?
final_lena = conv2(lena, fk);
final_lena = uint8(final_lena);
imshow(final_lena)
% grad magnitude estimate?
pass = conv2(lena, fk);
final_lena2 = sqrt(pass.^2 + pass.^2);
final_lena2 = uint8(final_lena2);
imshow(final_lena2)
% compare the symmetry to prior methods
smooth_image = conv2(lena, F);
vert_ = conv2(smooth_image, [gx gx gx]);
hor_ = conv2(smooth_image, [gy;gy;gy]);
final_lena0 = sqrt(vert_.^2 + hor_.^2);
final_lena0 = uint8(final_lena0);
imshow(final_lena0)
Note that the first two attempts have grossly asymmetric response. They both have suppressed response to vertical and horizontal edges. I don't know how that combined filter is supposed to be applied, so I'm just guessing here. It's sort of a half-scale Kayyali filter combined with a gaussian. I don't know what that's even for, so maybe I'm using it wrong.
Ken
le 27 Avr 2022
Hah. I guess accidents do happen.
Is there any other sort of contextual information that came with this dumb assignment? Any rumors among classmates? Maybe a clue about the intended size... or whether the size is actually the problem or not?
Maybe Image Analyst might have ideas as to how to appropriately apply a combined filter of that sort.
Catégories
En savoir plus sur Deblurring dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!





