Issue with Blockproc when using PadPartialBlocks

65 ビュー (過去 30 日間)
Jason
Jason 2026 年 1 月 26 日 20:10
コメント済み: Jason 2026 年 1 月 27 日 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 件のコメント
Stephen23
Stephen23 2026 年 1 月 26 日 20:41
編集済み: Stephen23 2026 年 1 月 26 日 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 2026 年 1 月 26 日 21:47
編集済み: Jason 2026 年 1 月 27 日 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

サインインしてコメントする。

採用された回答

Matt J
Matt J 2026 年 1 月 27 日 16:05
編集済み: Matt J 2026 年 1 月 27 日 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 件のコメント
Matt J
Matt J 2026 年 1 月 27 日 17:16
You're welcome, but my advice from before still stands. This is not a job for blockproc.
Jason
Jason 2026 年 1 月 27 日 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)

サインインしてコメントする。

その他の回答 (1 件)

Matt J
Matt J 2026 年 1 月 26 日 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 件のコメント
Jason
Jason 2026 年 1 月 26 日 21:45
What about if you put useparallel as true?
Matt J
Matt J 2026 年 1 月 26 日 23:12
編集済み: Matt J 2026 年 1 月 27 日 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.

サインインしてコメントする。

製品


リリース

R2024b

Community Treasure Hunt

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

Start Hunting!

Translated by