what is wrong with the blockproc function in my code?
2 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hadeer tawfik
le 19 Sep 2016
Modifié(e) : Hadeer tawfik
le 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
Réponse acceptée
Walter Roberson
le 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 commentaires
Walter Roberson
le 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.
Plus de réponses (0)
Voir également
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!