Using convn with pictures and kernel.

30 views (last 30 days)
I have an image with this dimension 6x6 (M,N). where the third dimension is the number of picture 6x6x20.
I will convolve each image with 2 mask 3x3x2 (M,N,#mask)
first I want to transform my images to cells without use a bucle function, I think is possible with "num2cell", but I don't have enought experience using this function. something like
Image_Cell = {6x6x1;
6x6x2;
.
.
6x6x20};
size(Image_Cell)
ans =
20 1
Finally, convolve each mask with each picture. and I know how to do it with for function. But I would like to not depend of this because would be slower. I don't know if I can use "cellfun".
% Image Mask1 Image Mask2
Convolution = {convn(6x6x1,3x3x1,'valid'),convn(6x6x1,3x3x2,'valid');
convn(6x6x2,3x3x1,'valid'),convn(6x6x2,3x3x2,'valid');
convn(6x6x3,3x3x1,'valid'),convn(6x6x3,3x3x2,'valid');
.
.
convn(6x6x20,3x3x1,'valid'),convn(6x6x20,3x3x2,'valid')};
size(Convolution)
ans =
20 2

Accepted Answer

Guillaume
Guillaume on 22 Mar 2020
It would be pointless to convert your 3D arrays into cell arrays of 2D arrays. You would just be storing the same information but using more memory to do so. The code to apply the convolution would be the same: a loop. In addition since you want to do a 2D convolution, you'd be using conv2, not convn.
%Images: a M x N x NumImages matrix
%Masks: a P x Q x NumMasks matrix
result = zeros(size(Images, 1) - size(Masks, 1) + 1, size(Images, 2) - size(Masks, 2) + 1, size(Images, 3), size(Masks, 3)); %4D matrix for output
for imgidx = 1:size(Images, 3)
for maskidx = 1:size(Masks, 3)
result(:, :, imgidx, maskidx) = conv2(Images(:, :, Imgidx), Masks(:, :, Maskidx), 'valid');
end
end

More Answers (1)

Image Analyst
Image Analyst on 22 Mar 2020
I don't understand. If you have a 6x6 image, even though there are 20 independent pictures them stacked into a 3-D array, how are you going to convolve that 6x6 image with a 3-D 3x3x2 kernel? Plus, why are you doing it anyway since the valid results (with no edge effects will only be the 4x4 inner part of the array?
If you did use a 3-D filter on the 3-D stack of images, you'd basically be combining layers (slices) when you get the result. Is that what you want? Why? Please explain it to me so I can see if that's what you really need to do. What is the larger context here?
And anyway, you wouldn't do all that stuff with cell arrays or cellfun(), you'd simply call it once with the 3-D arrays:
outputImage = convn(imageStack3d, kernel3D,'valid');
Finally, I have no idea what a "bucle function" is. What is it? Regardless, I agree that you don't need whatever it is. All you need is the line of code above.
  2 Comments
cristhian elguera
cristhian elguera on 22 Mar 2020
Ha yes. I will try to explaint better.
I need to create a program that can filter (convolutions) a group of images with a group of masks.
for example, my images.
Images = rand(6,6,20);
I want to convolve them with sobel masks, in this case 2. But there may be more masks.
Mask(:,:,1) = [-1 0 -1; % first mask
-2 0 2;
-1 0 1];
Mask(:,:,2) = [-1 0 -1; % Second mask
-2 0 2;
-1 0 1];
Then, in total there would be 40 new images, each mask with each image.
the problem with "convn" is it returns an output of 4x4x19 dimensions
it means that this is not convolving a mask with an image, one by one.
outputImage = convn(Images, Mask,'valid');
size(outputImage)
ans =
4 4 19
A solution for this it can be
Cell_Images = {}
for i = 1:size(Mask,3)
Cell_Images{i} = convn(Images, Mask(:,:,i),'valid');
end
disp(Cell_Image)
[4×4×20 double] [4×4×20 double]
I will have two cells and in each cell with 20 images. But I don't want to use loop function. this is my problem.
Image Analyst
Image Analyst on 22 Mar 2020
You have to do it one 2-D image at a time. Even if your images and masks are stacked into 3-D arrays. You'll have to make a double loop and extract each image and each mask and call conv2() one at a time. Something like (untested):
[imageRows, imageColumns, numImages) = size(Images);
[maskRows, maskColumn, numMasks) = size(Mask);
output = zeros(imageRows, imageColumns, numImages, numMasks)
for k1 = 1 : numImages
thisImage = Images(:, :, k1);
for k2 = 1 : numMasks
thisMask = Mask(:, :, k2);
% Now convolve
edgeImage = conv2(double(thisImage, double(thisMask), 'same'));
% Put into output array.
output(:, :, k1, k2) = edgeImage;
end
end

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!