what is wrong with the blockproc function in my code?
2 views (last 30 days)
Show older comments
Hadeer tawfik
on 19 Sep 2016
Edited: Hadeer tawfik
on 20 Sep 2016
I am trying to write the function 'replace' that accesses every block in the image, keeps the first 2000 cooefficient and sets the rest of them to zero. but every time i do that i find this error message:
Error using blockproc>parse_inputs (line 997)
Invalid block function. BLOCKPROC expects the user function, FUN, to be a valid function handle.
Error in blockproc (line 219)
[source,fun,options] = parse_inputs(source,block_size,fun,varargin{:});
Error in blk2 (line 6)
J3 = blockproc(I3,[8 8],'dct2',f);
here is the function f code:
function features = replace(block)
for( i = 2000:length(block.data) )
% set each element to 0
block.data(i) = 0
end
%and the DCT and blockproc code:
I3 = imread('process/13.jpg');
figure;
imshow(I3);
f = @(block)replace(block.data);
J3 = blockproc(I3,[8 8],'dct2',f);
figure
imshow(J3);
imshow(log(abs(J3)),[]), colormap(jet), colorbar
J3(abs(J3) < 5) = 0;
%B=J;
%B(1:1) = 0;
[M N]=size(J3);
fun3=zigzag(J3);
in4=izigzag(fun3,M,N);
f = @(block)replace(block.data);
J22 = blockproc(in4,[8 8],'idct2',f);
figure
imshow(J22,[0 255]);
figure
imshow(log(abs(J22)),[]), colormap(jet), colorbar
Accepted Answer
Walter Roberson
on 20 Sep 2016
blockproc requires a function handle as its third parameter. You are passing the string 'dct2' or 'idct2' in that position. Those are not function handles.
Perhaps what you want is
f = @(block)replace(dct2(block.data));
J3 = blockproc(I3, [8 8], f);
but keep in mind that each 8 x 8 block will have only 64 entries. So perhaps what you want is
f = @(block)dct2(block.data);
J3 = replace( blockproc(I3, [8 8], f) );
and similar change for idct2
3 Comments
Walter Roberson
on 20 Sep 2016
Change your replace function to
function features = replace(block)
features = block;
features(2000:end) = 0;
However, remember that with your code of invoking replace() for each block, your blocks are only going to be 8 x 8 so replace will have nothing to do.
It does not make sense to zero out all except the first DCT coefficients of a block unless the dct2 of the block returns an array with at least 2000 elements. dct2() returns as output an array the same size as its input, so instead of passing in 8 x 8 blocks you would need to modify that to have at least 2000 elements for it to make sense to zero all but the first 2000 elements. Perhaps you want to apply the dct2 to the entire image? Or perhaps you want to use 64 x 64 blocks, as those would have 4096 entries so you would be zeroing out slightly more than half of them?
I would also suggest that you rethinking what the "first" 2000 coefficients are. In MATLAB, the elements are counted down columns from the beginning, so zeroing out after the first 2000 would involve leaving intact the first 31 columns and the first 16 rows of the 32nd column, and zeroing out the last 16 rows of the 32nd column and all of the 33rd to 64th column. Does that make sense to you?
If you are thinking in terms of what JPEG does, remember that JPEG does a zig-zag unraveling to produce a vector from each block, so the "first" 2000 coefficients for JPEG would be the first 2000 along that zig-zag pattern. The zeros would be distributed in a much different pattern than what you are currently using.
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!