How to do this without blkproc function..?

3 views (last 30 days)
B = blkproc(I,[8 8],'P1*x*P2',T,T');
B2 = blkproc(B,[8 8],'P1.*x',mask);
% I have this code..
%I want to replace blkproc without using that fuction.. And the code is at follows.
%
%
m = 8;
n = 8;
p =0;
q = 0;
NColBlocks = 0;
for Colnum = 1: n : size(I,2)
NColBlocks = NColBlocks + 1;
NRowBlocks = 0;
for Rownum = 1: m : size(I,1)
NRowBlocks = NRowBlocks + 1;
fun = T*T';
B_temp{NRowBlocks, NColBlocks} = ...
fun(I(Rownum - p: Rownum + m - 1 + p, ...
Colnum - q: Colnum + n - 1 + q));
end
end
B = cell2mat(B_temp);
% But it created error, So, how to correct it..
  4 Comments
Geoff Hayes
Geoff Hayes on 26 Sep 2014
But what is the error? Is it occurring because the number of rows and columns in your input image I are not (evenly) divisible by eight (your m and n) or is it because of the evaluation of fun? What is T, and what are you attempting with
fun(I(Rownum - p: Rownum + m - 1 + p, ...
Colnum - q: Colnum + n - 1 + q));
My understanding, is that fun is a function handle that performs an operation on the block of data. See blokproc fun input arg for details. And yet you are using a matrix instead? Please add some context surrounding this code.
Nimisha
Nimisha on 26 Sep 2014
Edited: Matt J on 13 Oct 2014
I = imread('scene.jpg');
I = I(:,:,3);
%I = im2double(I);
T = dctmtx(8);
B = blkproc(I,[8 8],'P1*x*P2',T,T');
mask = [1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
B2 = blkproc(B,[8 8],'P1.*x',mask);
I2 = blkproc(B2,[8 8],'P1*x*P2',T',T);
imshow(I), figure, imshow(I2)
% In this program, when i run it, as a output it gives grayscale image..
% I want coloured image because my input is coloured image..?please modify my code if possible.

Sign in to comment.

Accepted Answer

Geoff Hayes
Geoff Hayes on 26 Sep 2014
Nimisha - it seems as if you are attempting to do some sort of JPG compression (given the use of dctmtx on the image) so try the following
I = imread('scene.jpg');
I = double(I(:,:,3)); % note the conversion to double (diff from im2double)
T = dctmtx(8); % T is of double data type, so that is y I must be double too
m = 8; % block size
n = 8;
B_temp = {};
numCols = size(I,2); % use these rather than access size repeatedly
numRows = size(I,1);
NColBlocks = 0;
for col = 1:n:numCols
NColBlocks = NColBlocks + 1;
NRowBlocks = 0;
% determine where in I we will be extracting the column data
% colStrt will be the starting column (and will always be valid)
colStrt = col;
% colStop will be the end or stopping column and is either n greater than
% colStart (less one) or is the last column in the image (to avoid indexing
% errors)
colStop = min(col+n-1,numCols);
for row = 1:m:numRows
NRowBlocks = NRowBlocks + 1;
% create an empty block of zeros
blk = zeros(m,n);
% determine where in I we will be extracting the row data
% rowStrt will be the starting row (and will always be valid)
rowStrt = row;
% rowStop will be the end or stopping row and is either m greater than
% rowStart (less one) or is the last row in the image (to avoid indexing
% errors)
rowStop = min(row+m-1,numRows);
% extract the block or as much of it as we can
blk(1:rowStop-rowStrt+1,1:colStop-colStrt+1) = ...
I(rowStrt:rowStop,colStrt:colStop);
% do the transformation on the 8x8 block and save it to the cell array
B_temp{NRowBlocks, NColBlocks} = T*blk*T';
end
end
% convert the transformed blocks in the cell array to a matrix
% note that the matrix B may be larger than I due to the zero padding
B = cell2mat(B_temp);
The above code should do what you want for B = blkproc(I,[8 8],'P1*x*P2',T,T');, though as Sean indicated, why not use blockproc instead?
Note how if the number of rows and/or columns in the image are not evenly divisible by eight, we use an 8x8 block of zeros and populate that with as much of the data as we can (so we are zero padding the last block in the final column and in the final row). This means that B will be larger than I because of the additional padding. This is to avoid the Index exceeds matrix dimensions. error that you may have been observing.
You should be able to modify the above to perform the additional transformations on the 8x8 blocks (the application of the mask (though you may have to reshape this to an 8x8 matrix), and the reverse transformation T'*blk*T*.
  13 Comments
PINAK JOSHI
PINAK JOSHI on 29 Mar 2017
Sorry, I am very amateur in MATLAB. Can anybody please tell me what exactly 'P1*x*P2' and 'P1.*x' here?

Sign in to comment.

More Answers (1)

Sean de Wolski
Sean de Wolski on 26 Sep 2014
Why don't you want to use blkproc (or blockproc)?
You could always use two for-loops to do this.

Community Treasure Hunt

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

Start Hunting!