Issue with Blockproc when using PadPartialBlocks

72 vues (au cours des 30 derniers jours)
Jason
Jason le 26 Jan 2026 à 20:10
Commenté : Jason le 27 Jan 2026 à 17:34
I have an image that I want to break up into regions and calculate the Standard deviation of (using STD2). I only want the result to contain calculations for COMPLETE blocks. Walter has kindly suggested to use "PadMethod"as NaN, then the resulting data would have NaNs in the partial columns / rows that I can then process out.
However, using PadPartialBlocks doesn't seem to be working as it should
bss = [500,500];
fh = @(bs) std2(bs.data);
J = blockproc(IM2, bss, fh,'UseParallel',true,'PadPartialBlocks',true,'PadMethod',NaN);
The last column (=col 21) which is the "partial" column doesn't have values I was expecting. Surely they should all be NaN? Its as though the NaN isn't actally been replaced in the last partial column - what am I doing wrong?
  2 commentaires
Stephen23
Stephen23 le 26 Jan 2026 à 20:41
Modifié(e) : Stephen23 le 26 Jan 2026 à 20:42
It seems to work:
IM2 = rand(10,10);
bss = [3,3];
fh = @(bs) std2(bs.data);
J = blockproc(IM2, bss, fh, 'UseParallel',true, 'PadPartialBlocks',true, 'PadMethod',NaN)
J = 4×4
0.2605 0.3164 0.2651 NaN 0.4085 0.2991 0.2368 NaN 0.3742 0.2664 0.3372 NaN NaN NaN NaN NaN
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
What is size(IM2) ? Even better: upload your data by clicking the paperclip button.
Jason
Jason le 26 Jan 2026 à 21:47
Modifié(e) : Jason le 27 Jan 2026 à 8:42
Hi Stephen, heres my part of Image (limited by max of 5MB), so I've reduced the height (Ithe original image is 10242 x 8000 pixels).
Here is my code:
blockSizeAcross = 500;
blockSizeDown = 500;
bss = [blockSizeAcross,blockSizeDown]; % Each blockproc region
[rows, columns, numColors] = size(IM);
numBlocksAcross = floor(columns / blockSizeAcross);
numPixelsAcross = numBlocksAcross * blockSizeAcross;
numBlocksTall = floor(rows / blockSizeDown);
numPixelsTall = numBlocksTall * blockSizeDown;
% Add Grids on Image so can see the sub images
hold(ax,'on');
k=1:numBlocksAcross;
axis(ax,'image');
xline(ax,k*blockSizeAcross,'r--'); drawnow;
k=1:numBlocksTall;
yline(ax,k*blockSizeDown,'r--'); drawnow;
fh = @(bs) [mean2(bs.data),std2(bs.data)]; % Can combine operations in one call to blockproc!
J = blockproc(IM2, bss, fh,'UseParallel',true,'PadPartialBlocks',true,'PadMethod',NaN);
I2 = J(:,1:2:end);
SD = J(:,2:2:end);
% I'd rather not have to reshape to remove the partial block (column), I want to have it as NaN's
% reshape i.e. remove last column if its a partial block
if columns>numPixelsAcross
I2(:,end)=[];
SD(:,end)=[];
end

Connectez-vous pour commenter.

Réponse acceptée

Matt J
Matt J le 27 Jan 2026 à 16:05
Modifié(e) : Matt J le 27 Jan 2026 à 16:15
Integer types cannot hold NaN values, so you will have to convert your int8 input to floating point:
load('ImgForBlockProcQuestion.mat');
IM=double(IM);
blockSizeAcross = 500;
blockSizeDown = 500;
bss = [blockSizeAcross,blockSizeDown]; % Each blockproc region
fh = @(bs) [mean2(bs.data),std2(bs.data)]; % Can combine operations in one call to blockproc!
J = blockproc(IM, bss, fh,'UseParallel',true,'PadPartialBlocks',true,'PadMethod',NaN);
You can now see that NaNs are present:
nnz(isnan(J))
ans = 46
  3 commentaires
Matt J
Matt J le 27 Jan 2026 à 17:16
You're welcome, but my advice from before still stands. This is not a job for blockproc.
Jason
Jason le 27 Jan 2026 à 17:34
so the reason I haven't tried this yet is whilst I do use std2, I also have my own image sharpness function involving FFT and a few fancy operations (sorry I can't divulge anymore). I wasn't sure if the other approach would work, especially as my fucntion is of the form
sharpness=myfunc(app,Image)
I know using parfor you can't run fucntion where app is an argument and found I had to do this:
sharpness=app.myfunc(Image)

Connectez-vous pour commenter.

Plus de réponses (1)

Matt J
Matt J le 26 Jan 2026 à 20:44
what am I doing wrong?
Nothing you've shown us currently. The border values will/should be NaNs as you expect.
J = blockproc(rand(6), [5,5], @(bs)std2(bs.data) ,'PadPartialBlocks',true,'PadMethod',NaN)
J = 2×2
0.2842 NaN NaN NaN
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
  3 commentaires
Jason
Jason le 26 Jan 2026 à 21:45
What about if you put useparallel as true?
Matt J
Matt J le 26 Jan 2026 à 23:12
Modifié(e) : Matt J le 27 Jan 2026 à 0:17
You can go ahead and test it, but I suspect UseParallel will make things worse with a Process pool and only marginally better with a Thread pool. At least, on my computer it does (with 6 workers):
parpool('Threads')
Starting parallel pool (parpool) using the 'Threads' profile ...
Connected to parallel pool with 6 workers.
ans =
ThreadPool with properties:
NumWorkers: 6
Busy: false
FileStore: [1x1 parallel.FileStore]
ValueStore: [1x1 parallel.ValueStore]
bss=[500,500];
IM2=rand(9999);
tic;
IM3=padarray(IM2, [1,1],nan,'post');
J1=sqrt( sepblockfun(IM3.^2,bss,'mean') - sepblockfun(IM3,bss,'mean').^2 );
toc;
Elapsed time is 0.704048 seconds.
tic;
J2= blockproc(IM2, bss, @(bs) std2(bs.data), 'UseParallel',false, ...
'PadPartialBlocks',true,'PadMethod',NaN);
toc
Elapsed time is 1.841515 seconds.
tic;
J2= blockproc(IM2, bss, @(bs) std2(bs.data), 'UseParallel',true, ...
'PadPartialBlocks',true,'PadMethod',NaN);
toc
Elapsed time is 1.800456 seconds.

Connectez-vous pour commenter.

Produits


Version

R2024b

Community Treasure Hunt

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

Start Hunting!

Translated by