Reputation: 83
So I need to take the derivative of an image in the x-direction for this assignment, with the goal of getting some form of gradient. My thought is to use the diff(command) on each row of the image and then apply a Gaussian filter. I haven't started the second part because the first is giving me trouble. In attempting to get the x-derivative I have:
origImage = imread('TightRope.png');
for h = 1:3 %%h represents color channel
for i = size(origImage,1)
newImage(i,:,h) = diff(origImage(i,:,h)); %%take derivative of row and translate to new row
end
end
The issue is somewhere along the way I get the error 'Subscripted assignment dimension mismatch.'.
Error in Untitled2 (line 14)
newImage(i,:,h) = diff(origImage(i,:,h));
Does anyone have any ideas on why that might be happening and if my approach is correct for getting the gradient/gaussian derivative?
Upvotes: 2
Views: 934
Reputation: 104474
Given a N
element vector, diff
returns a N-1
length vector, so the reason why you are getting an alignment mismatch is because you are trying to assign the output of diff
into an incorrect number of slots. Concretely, supposing that N
is the total number of columns, you are using diff
on a 1 X N
vector which thus returns a 1 x (N - 1)
vector and you are trying to assign this output as a single row into the output image which is expected to be 1 x N
. The missing element is causing the alignment mismatch. diff
works by taking pairs of elements in the vector and subtracting them to produce new elements, thus the reason why there is one element missing in the final output.
If you want to get your code working, one way is to pad each row of the image or signal vector with an additional zero (for example) as input into diff
. Something like this could work. Take note that I'll be converting your image to double
to allow the derivative to take on negative values:
origImage = imread('...'); %// Place path to image here and read in
origImage = im2double(origImage); %// Change - Convert to double precision
newImage = zeros(size(origImage)); %// Change - Create blank new image and populate each row per channel manually
for h = 1:3 %%h represents color channel
for ii = 1:size(origImage,1) %// Change - fixed for loop iteration
newImage(ii,:,h) = diff([0 origImage(ii,:,h)]); %// Change
end
end
Take note that your for
loop was incorrect since it didn't go over every row... just the last row.
When I use the onion.png
image that's part of the image processing toolbox:
...and when I run this code, I get this image using imshow(newImage,[]);
:
Take note that the difference filter was applied to each channel individually and I changed the intensities per channel so that the smallest value gets mapped to 0 and the largest value gets mapped to 1. How you can interpret this image is that any areasthat have a non-black colour have some non-zero differences and hence there is some activity going on in those areas and any areas that have a dark / black colour means that there is no activity going on in those areas. Take note that we applied a horizontal filter, so if you wanted to do this vertically, you'd simply repeat the behaviour but apply this column-wise instead of row-wise as you did above.
Upvotes: 1
Reputation: 16791
If your goal is to use diff
to generate the derivative rather than to create a loop, you can just tell diff
to give you the derivative in the x-direction (along dimension 2):
newImage = diff(double(origImage), 1, 2);
The 1
is for the first derivative and 2
is for the derivative along the second dimension. See diff.
As @rayryeng mentions in his answer, it's important to cast the image as double
.
Upvotes: 1
Reputation: 944
Why not use fspecial
along with imfilter
instead?
figure;
I = imread('cameraman.tif');
subplot 131; imshow(I); title('original')
h = fspecial('prewitt');
derivative = imfilter(I,h','replicate'); %'
subplot 132; imshow(derivative); title('derivative')
hsize = 5;
sigma = 1;
h = fspecial('gaussian', hsize, sigma) ;
gaussian = imfilter(derivative,h','replicate'); %'
subplot 133; imshow(gaussian); title('derivative + gaussian')
The result is the following one:
Upvotes: 2