I'm working on an image processing project in MATLAB. In order to preprocess the image more easily, I've divided it in rows and columns, so from a original image (a 2D uint8 matrix), now I have a 3D matrix, like a stack.
After processing each block, I want to recompose the image again. The problem is that the number of rows and columns is dynamic, so I can't use (or don't know how to use it here) the cat
command or the [firstsubmatrix secondsubmatrix]
syntax.
By the way, I do the division like this:
numRows = 3
numCols = 3
blockHeight = originalHeight / numRows;
blockWidth = originalWidth / numCols;
blocks = uint8(zeros(numCols * numRows, blockHeight, blockWidth));
So for each block, I fill its content using
y0 = (row - 1) * rowHeight + 1;
y1 = row * rowHeight;
x0 = (col - 1) * rowWidth + 1;
x1 = col * rowWidth;
blocks(numBlock, :, :) = originalImage(y0:y1, x0:x1);
Is there a better way of doing it, and any way of having the blocks joined?
If I am understanding your question correctly, then this is how I would do it: Assume we have some data matrix with dimensions m by n
[m n] = size(data);
rows_wanted = 10;
cols_wanted = 10;
submatrix_rows = rows_wanted*ones(1,m/rows_wanted);
submatrix_cols = cols_wanted*ones(1,n/cols_wanted);
data_cells = mat2cell(data,submatrix_rows,submatrix_cols);
for k1 = 1:submatrix_rows;
for k2 = 1:submatrix_cols;
proc_data_cells{k1,k2} = function_for_matrics(data_cells{k,l});
end
end
proc_data_mtx = cell2mat(proc_data_cells);
convert your data into a cell, where each element of the cell is a submatrix, then go through each element, preform your function, and output it to a new cell. Use cell2mat to output a fully concatenated processed matrix.
If you have access to the Image Processing Toolbox, I would also check out the 'blkproc' function.
With regard to your specific question about how you could convert back and forth between a 2-D matrix and a 3-D matrix according to your diagram, I am first going to assume that originalHeight
and originalWidth
can be evenly divided by numRows
and numCols
, respectively. Building on a solution I gave to a similar problem that was previously asked, here is a solution using only reshapes and permutations of the matrices:
%# Convert from 2-D to 3-D:
blocks = reshape(permute(reshape(originalImage,blockHeight,blockWidth,[]),...
[1 3 2]),blockHeight,blockWidth,[]);
%# Convert from 3-D to 2-D:
newImage = reshape(permute(reshape(blocks,blockHeight,[],blockWidth),...
[1 3 2]),originalHeight,originalWidth);
Note that the blocks in the 3-D matrix are concatenated along the third dimension, so blocks(:,:,i)
is the ith block from the 2-D matrix. Note also that these solutions will extract and fill blocks in the 2-D matrix in a row-wise fashion. In other words, if originalImage = [A1 A2; A3 A4];
, then blocks(:,:,1) = A1;
, blocks(:,:,2) = A2;
, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With