Issue with Blockproc when using PadPartialBlocks

60 次查看(过去 30 天)
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 2 minutes 前
编辑:Stephen23 1 minute 前
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 about 17 hours 前
编辑:Jason about 6 hours 前
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 about 16 hours 前
编辑:Matt J about 16 hours 前
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 33 minutes 前
You're welcome, but my advice from before still stands. This is not a job for blockproc.
Jason
Jason 15 minutes 前
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 about 10 hours 前
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 about 9 hours 前
What about if you put useparallel as true?
Matt J
Matt J about 8 hours 前
编辑:Matt J about 7 hours 前
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