Skip to content
Snippets Groups Projects

Create forward prjection structure for twin cluster.

Open Zheheng Liu requested to merge 2-add-TRD-fwd-proj into master
1 file
+ 540
0
Compare changes
  • Side-by-side
  • Inline
+ 540
0
classdef GtGrainClusterCalcBlobNoiseVars < handle
properties
cluster;
parameters;
invalid_pixel_nvar = 3e38;
detector_margin = 1;
use_detector_mask = [];
end
properties (Access = protected)
bbuims = [];
bbvims = [];
bbwims = [];
data_type;
det_ind;
detector_mask;
end
methods (Access = public)
function [self, cl] = GtGrainClusterCalcBlobNoiseVars(cl_ids, phase_id, p, detinds, varargin)
% GtGrainClusterCalcBlobNoiseVars(cl, phase_id, p, detinds)
% The function reads the blobs as the estimate of
% Poisson noise variance. Next, upon the parameter
% detector_weights.nvar_images, the background images are read
% to get more accurate Poisson noise. An alternative method is
% to load raw images as noise variances. The parameters are
% located at parameters.rec.grains.options.detector_weights.
% The optional input 'detector_margin' will inactivate the
% pixels at the edges of detector and default number is 1; the
% default value of 'use_detector_mask' is true, which uses the
% detector mask saved in 'detector%d_mask.edf' (same convention
% as dark.edf).
% If we have got the object det_weights =
% GtGrainClusterCalcBlobNoiseVars(gr, phase_id, p, detinds_1),
% we can read the noise variance again by
% det_weights.loadNoiseVarianceForIndicatedDet(detinds_2)
conf = struct(...
'detector_margin', 1, ...
'use_detector_mask', true);
conf = parse_pv_pairs(conf, varargin);
self.detector_margin = conf.detector_margin;
self.use_detector_mask = conf.use_detector_mask;
if (~exist('phase_id', 'var') || isempty(phase_id))
phase_id = 1;
end
if (~exist('p', 'var') || isempty(p))
self.parameters = gtLoadParameters;
else
self.parameters = p;
end
if isnumeric(cl_ids)
cl_ids = sort(unique(cl_ids), 'ascend');
self.cluster = gtLoadCluster(phase_id, cl_ids);
else
self.cluster = cl_ids;
cl_ids = sort(unique(cat(2, cl_ids.samp_ors.id)), 'ascend');
end
self.set_unused_bl_to_empty();
if isstruct(self.cluster.blobs)
self.cluster.blobs = {self.cluster.blobs};
end
self.normalize_blobs();
if (~exist('detinds', 'var') || isempty(detinds))
detinds = 1:numel(self.cluster.blobs);
end
self.loadNoiseVarianceForIndicatedDet(detinds)
if nargout > 1
cl = self.cluster;
end
end
function gr = loadNoiseVarianceForIndicatedDet(self, detinds)
% this function is used to read the noise variance for
% indicated detector indices.
% For example, as we have got the object det_weights =
% GtGrainClusterCalcBlobNoiseVars(gr, phase_id, p, detinds_1),
% we can read the noise variance again by
% det_weights.loadNoiseVarianceForIndicatedDet(detinds_2)
for ii_d = 1:numel(detinds)
if ~isempty(self.cluster.blobs{detinds(ii_d)})
self.det_ind = detinds(ii_d);
self.get_bboxes_and_datatype();
self.get_noise_var_into_grain();
end
end
if nargout
gr = self.grain;
end
end
function saveClusterToFile(self, phase_id)
cl_ids = sort(unique(cat(2, self.cluster.samp_ors.id)), 'ascend');
gtSaveCluster(phase_id, cl_ids, self.cluster)
end
function applyDetectorMask(self, detinds)
if (~exist('detinds', 'var')) || isempty(detinds)
detinds = 1;
end
% fill the missing use_detector_mask for the detectors.
nof_missing_flags = max(detinds) - numel(self.use_detector_mask);
if (nof_missing_flags > 0)
self.use_detector_mask = [self.use_detector_mask(:)', self.use_detector_mask(ones(1, nof_missing_flags))];
end
for ii_d = 1:numel(detinds)
if isempty(self.cluster.blobs{detinds(ii_d)})
self.use_detector_mask(detinds(ii_d)) = false;
else
if (self.use_detector_mask(detind))
self.load_detector_mask(detinds(ii_d)); % load detector mask from detector%d_mask.edf
end
if (self.use_detector_mask(detind))
self.apply_detector_mask(detinds(ii_d)); % apply the detector mask
end
end
end
end
function inactivatePixelsOutsideDetector(self, detinds)
if (~exist('detinds', 'var')) || isempty(detinds)
detinds = 1;
end
for ii_d = 1:numel(detinds)
detbbmin = 1 + self.detector_margin;
detbbumax = self.parameters.acq(detinds(ii_d)).xdet - self.detector_margin;
detbbvmax = self.parameters.acq(detinds(ii_d)).ydet - self.detector_margin;
for ii_b = 1:numel(self.cluster.blobs{detinds(ii_d)})
bbuim = self.cluster.blobs{detinds(ii_d)}(ii_b).bbuim;
bbvim = self.cluster.blobs{detinds(ii_d)}(ii_b).bbvim;
bbuim = bbuim(1):bbuim(2);
bbvim = bbvim(1):bbvim(2);
bbuim = (bbuim > detbbumax) & (bbuim < detbbmin);
bbvim = (bbvim > detbbvmax) & (bbvim < detbbmin);
if any(bbuim)
self.cluster.blobs{detinds(ii_d)}(ii_b).nvar(bbuim, :, :) = self.invalid_pixel_nvar;
end
if any(bbvim)
self.cluster.blobs{detinds(ii_d)}(ii_b).nvar(:, bbvim, :) = self.invalid_pixel_nvar;
end
end
end
end
function deselectBlobCoveredByInvalidPixels(self, detinds)
nof_ors = numel(self.cluster.samp_ors);
if iscell(self.cluster.blobs)
if (~exist('detinds', 'var')) || isempty(detinds)
detinds = 1;
end
for ii_d = 1:numel(detinds)
for ii_ors = 1:nof_ors
global_pos = self.cluster.samp_ors(ii_ors).proj(detinds(ii_d)).global_pos;
for ii_b = 1:numel(global_pos)
exist_valid_pixel = self.cluster.blobs{detinds(ii_d)}(global_pos(ii_b)).mask > 0.1;
exist_valid_pixel = self.cluster.blobs{detinds(ii_d)}(global_pos(ii_b)).nvar(exist_valid_pixel);
exist_valid_pixel = exist_valid_pixel < (self.invalid_pixel_nvar * 0.9);
exist_valid_pixel = any(exist_valid_pixel(:));
if ~exist_valid_pixel
self.cluster.samp_ors(ii_ors).proj(detinds(ii_d)).selected(ii_b) = false;
end
end
end
end
else
for ii_ors = 1:nof_ors
global_pos = self.cluster.samp_ors(ii_ors).proj(1).global_pos;
for ii_b = 1:numel(global_pos)
exist_valid_pixel = self.cluster.blobs(global_pos(ii_b)).mask > 0.1;
exist_valid_pixel = self.cluster.blobs(global_pos(ii_b)).nvar(exist_valid_pixel);
exist_valid_pixel = exist_valid_pixel < (self.invalid_pixel_nvar * 0.9);
exist_valid_pixel = any(exist_valid_pixel(:));
if ~exist_valid_pixel
self.cluster.samp_ors(ii_ors).proj(1).selected(ii_b) = false;
end
end
end
end
end
function showNoiseVariance2DStack(self, detind, lim_max)
if (~exist('detind', 'var')) || isempty(detind)
detind = 1;
end
if (~exist('lim_max', 'var')) || isempty(lim_max)
lim_max = 1e4;
end
stack = arrayfun(@(x) sum(x.nvar, 3), self.cluster.blobs{detind}, 'UniformOutput', false);
stack = cat(3, stack{:});
GtVolView(min(stack, lim_max));
end
end
methods (Access = protected)
function set_unused_bl_to_empty(self)
for ii_ors = 1:numel(self.cluster.samp_ors)
for ii_det = 1:numel(self.cluster.samp_ors(ii_ors).proj)
for ii_b = 1:numel(self.cluster.samp_ors(ii_ors).proj(ii_det).bl)
self.cluster.samp_ors(ii_ors).proj(ii_det).bl(ii_b).intm = [];
self.cluster.samp_ors(ii_ors).proj(ii_det).bl(ii_b).mask = [];
end
end
end
end
function normalize_blobs(self)
num_det = numel(self.cluster.blobs);
for ii_d = 1:num_det
nof_bl = numel(self.cluster.blobs{ii_d});
for ii_b = 1:nof_bl
sum_intm = sum(abs(self.cluster.blobs{ii_d}(ii_b).intm(:)));
if ((~isempty(sum_intm)) && (abs(sum_intm) > 1e-5) && (abs(sum_intm - 1) > 1e-5))
self.cluster.blobs{ii_d}(ii_b).intm = self.cluster.blobs{ii_d}(ii_b).intm / sum_intm;
end
end
end
end
function get_bboxes_and_datatype(self)
detind = self.det_ind;
self.data_type = class(self.cluster.blobs{detind}(1).intm);
self.bbuims = cat(1, self.cluster.blobs{detind}(:).bbuim);
self.bbvims = cat(1, self.cluster.blobs{detind}(:).bbvim);
% The bbwim is only used to read the median images, so TT
% does not need it as there is no median images for TT.
if isfield(self.cluster.blobs{detind}, 'bbwim')
self.bbwims = cat(1, self.cluster.blobs{detind}(:).bbwim);
end
end
function load_detector_mask(self, detind)
% load detector mask from detector_mask.edf under
% p.acq(detind).dir (currently only work for dct detector 1)
detmaskdir = sprintf('detector%d_mask.edf', detind);
detmaskdir = fullfile(self.parameters.acq(detind).dir, detmaskdir);
if exist(detmaskdir, 'file')
det_mask = edf_read(detmaskdir);
self.detector_mask{detind} = det_mask' > 0;
else
self.use_detector_mask(detind) = false;
end
end
function get_noise_var_into_grain(self)
% get parameters
nvar_param = self.get_parameters_of_nvar_generation();
% get the Poisson noise variance
if isempty(nvar_param.nvar_images)
nvar_param.nvar_images = 'blob';
end
fprintf('Loading %s images ...\n', image_type)
var_dark = [];
dark = [];
c = tic;
switch nvar_param.nvar_images
case 'median' % read background noise from median images. The total noise variance is blob + median image
self.copy_bl_int_to_nvar()
self.load_bg_from_median_imgs();
case 'raw' % directly use raw images as noise variance
[var_dark, dark] = GtGrainCalcBlobNoiseVars.calcDarkImageVariance(self.parameters.acq(self.det_ind));
self.load_nvar_from_raw_imgs(dark);
otherwise % only use blob as noise variance
self.copy_bl_int_to_nvar()
end
fprintf('Done in %.2f s.\n', toc(c));
% get the noise variance of dark images
if (nvar_param.use_dark_image_variance)
c = tic;
fprintf('Calculating background noise variance from dark images ... ')
self.add_noise_of_dark_images(var_dark, dark) % Calculate the noise in dark images
fprintf('Done in %.2f s.\n', toc(c));
end
end
function nvar_param = get_parameters_of_nvar_generation(self)
nvar_param = struct(...
'nvar_images', [], ...
'use_dark_image_variance', false, ...
'save_cluster', false);
rec_opt = self.parameters.rec.grains.options;
if (isfield(rec_opt, 'detector_weights') && ...
~isempty(rec_opt.detector_weights))
weight_opt = rec_opt.detector_weights;
if (isfield(weight_opt, 'nvar_images') && ...
ischar(weight_opt.nvar_images))
nvar_param.nvar_images = lower(weight_opt.nvar_images);
end
if (isfield(weight_opt, 'use_dark_image_variance') && ...
~isempty(weight_opt.use_dark_image_variance))
nvar_param.use_dark_image_variance = weight_opt.use_dark_image_variance;
end
if (isfield(weight_opt, 'save_cluster') && ...
~isempty(weight_opt.save_cluster))
nvar_param.save_cluster = weight_opt.save_cluster;
end
end
% As for TT, we can only use the blob as the noise variance.
if (~strcmpi(self.parameters.acq(self.det_ind).type, '360degree'))
nvar_param.nvar_images = [];
nvar_param.use_dark_image_variance = false;
end
end
function copy_bl_int_to_nvar(self)
switch lower(self.parameters.acq(self.det_ind).type)
case {'180degree', '360degree'}
blob_type = 'blob';
case 'topotomo'
blob_type = 'blob_topo';
end
nof_bl = numel(self.cluster.blobs{self.det_ind});
if ~isfield(self.cluster.blobs{self.det_ind}(1), 'nvar')
tmpbl = gtFwdSimBlobDefinition(blob_type, nof_bl);
for ii_b = nof_bl:-1:1
tmpbl(ii_b) = gtAddMatFile(tmpbl(ii_b), self.cluster.blobs{self.det_ind}(ii_b), true, false, false, false, false);
end
self.cluster.blobs{self.det_ind} = tmpbl;
end
for ii_b = nof_bl:-1:1
self.cluster.blobs{self.det_ind}(ii_b).nvar = abs(self.cluster.blobs{self.det_ind}(ii_b).intm) * self.cluster.blobs{self.det_ind}(ii_b).intensity;
end
end
function load_bg_from_median_imgs(self)
% According to gtPreprocessing, the median image is regarded as
% the background of next parameters.prep.fullint projection
% images.
acq = self.parameters.acq(self.det_ind);
outdir = fullfile(acq.dir, '1_preprocessing', 'full');
fullint = self.parameters.prep.fullint;
totproj = 2 * acq.nproj;
nof_med = ceil(totproj/fullint);
gauge = GtGauge(nof_med, 'loading background noise from median images ... ');
% loop for median images
for fullint_lb = 0:fullint:(fullint * (nof_med - 1))
fullint_ub = min(fullint_lb + fullint, totproj);
fname = fullfile(outdir, sprintf('med%04d.edf', fullint_lb));
gauge.incrementAndDisplay();
self.add_median_image_to_spots(fname, fullint_lb, fullint_ub, totproj, acq.xdet, acq.ydet);
end
end
function add_median_image_to_spots(self, fname, fullint_lb, fullint_ub, totproj, xdet, ydet)
% This function finds the blobs (partially) use this median
% image as background and adds this median image to (the part of)
% the noise variance of the blobs.
% truncate the blobs that are partially outside the range of
% the median image, and finds the blobs (partially) in the range
[bbwims_modified, bool_inint] = self.modify_bbwims_and_check_bl_exist_med(fullint_lb, fullint_ub, totproj);
if any(bool_inint)
% find the blob regions inside the detector.
bbuim_inint = self.bbuims(bool_inint, :);
bbuim_inint_ondet = GtGrainCalcBlobNoiseVars.calcOndetBbim(bbuim_inint, 1 + self.detector_margin, xdet - self.detector_margin);
subbbu = bsxfun(@minus, bbuim_inint_ondet, bbuim_inint(:, 1) - 1);
bbvim_inint = self.bbvims(bool_inint, :);
bbvim_inint_ondet = GtGrainCalcBlobNoiseVars.calcOndetBbim(bbvim_inint, 1 + self.detector_margin, ydet - self.detector_margin);
subbbv = bsxfun(@minus, bbvim_inint_ondet, bbvim_inint(:, 1) - 1);
inds_inint = find(bool_inint);
% The information helping to read the median image
info = edf_info(fname);
% loop for the blobs: read the median image and add it to the blob
for ii_inint = 1:numel(inds_inint)
ind_b = inds_inint(ii_inint);
% determine the available bounding box
bbwim = bbwims_modified(ind_b, :);
bbwlow = max(fullint_lb, bbwim(1)) - bbwim(1) + 1;
bbwup = min(fullint_ub - 1, bbwim(2)) - bbwim(1) + 1;
bb_ii = [bbuim_inint_ondet(ii_inint, :); bbvim_inint_ondet(ii_inint, :)];
bb_ii(:, 2) = bb_ii(:, 2) - bb_ii(:, 1) + 1;
% read median image in the bounding box
medimg_crop = cast(edf_read(fname, bb_ii(:)', [], info), self.data_type)';
medimg_crop(medimg_crop <= 0) = self.invalid_pixel_nvar;
% add the median image to the blob noise variance
medbg = medimg_crop(:, :, ones(1, bbwup - bbwlow + 1));
subu = subbbu(ii_inint, :);
subv = subbbv(ii_inint, :);
spotaddbg = self.cluster.blobs{self.det_ind}(ind_b).nvar(subu(1):subu(2), subv(1):subv(2), bbwlow:bbwup) + medbg;
self.cluster.blobs{self.det_ind}(ind_b).nvar(:, :, bbwlow:bbwup) = cast(self.invalid_pixel_nvar, self.data_type);
self.cluster.blobs{self.det_ind}(ind_b).nvar(subu(1):subu(2), subv(1):subv(2), bbwlow:bbwup) = cast(spotaddbg, self.data_type);
end
end
end
function [bbwims_modified, bool_inint] = modify_bbwims_and_check_bl_exist_med(self, fullint_lb, fullint_ub, totproj)
% truncate the blobs that are partially outside the range of
% the median image, and finds the blobs (partially) in the range
bbwims_modified = self.bbwims;
bool_inint = any(bbwims_modified < (fullint_ub - totproj), 2) & any(bbwims_modified >= (fullint_lb - totproj), 2);
if any(bool_inint)
bbwims_modified(bool_inint, :) = bbwims_modified(bool_inint, :) - totproj;
end
bool_inint = any(bbwims_modified < (fullint_ub + totproj), 2) & any(bbwims_modified >= (fullint_lb + totproj), 2);
if any(bool_inint)
bbwims_modified(bool_inint, :) = bbwims_modified(bool_inint, :) + totproj;
end
bool_inint = any(bbwims_modified < fullint_ub, 2) & any(bbwims_modified >= fullint_lb, 2);
end
function load_nvar_from_raw_imgs(self, dark)
acq = self.parameters.acq(self.det_ind);
dir = fullfile(acq.dir, '0_rawdata', acq.name);
if (~exist('dark', 'var') || isempty(dark))
dark = edf_read(fullfile(dir, 'dark.edf'));
end
dark = cast(dark', self.data_type); % dark image needs substracting from raw images
totproj = 2 * acq.nproj;
gauge = GtGauge(totproj, 'loading raw images as noise ... ');
self.set_bl_nvar_to_inf(); % initialize the noise variance to a very large value
fname = fullfile(acq.dir, '0_rawdata', acq.name, sprintf('%s0000.edf', acq.name));
info = edf_info(fname); % The information helping to read the median image
% find the blob regions inside the detector.
bbuims_ondet = GtGrainCalcBlobNoiseVars.calcOndetBbim(self.bbuims, 1 + self.detector_margin, acq.xdet - self.detector_margin);
subbbu = bsxfun(@minus, bbuims_ondet, self.bbuims(:, 1) - 1);
bbvims_ondet = GtGrainCalcBlobNoiseVars.calcOndetBbim(self.bbvims, 1 + self.detector_margin, acq.ydet - self.detector_margin);
subbbv = bsxfun(@minus, bbvims_ondet, self.bbvims(:, 1) - 1);
% loop for raw images
for ii_proj = 0:(totproj-1)
gauge.incrementAndDisplay();
[bbwims_modified, bool_inproj] = self.modify_bbwims_and_check_bl_exist_raw(ii_proj, totproj);
if any(bool_inproj)
fname = fullfile(acq.dir, '0_rawdata', acq.name, sprintf('%s%04d.edf', acq.name, ii_proj));
inds_inproj = find(bool_inproj);
% loop for the blobs: read the raw image and add it to the blob
for ind_b = inds_inproj(:)'
bbwim = bbwims_modified(ind_b, :);
bbw = ii_proj - bbwim(1) + 1;
bb_ii = [bbuims_ondet(ind_b, :); bbvims_ondet(ind_b, :)];
dark_crop = dark(bb_ii(1, 1):bb_ii(1, 2), bb_ii(2, 1):bb_ii(2, 2)); % dark image needs substracting from raw images
bb_ii(:, 2) = bb_ii(:, 2) - bb_ii(:, 1) + 1;
rawimg_crop = cast(edf_read(fname, bb_ii(:)', [], info), self.data_type)'; % read raw image
rawimg_crop(rawimg_crop <= 0) = self.invalid_pixel_nvar;
rawimg_crop = rawimg_crop - dark_crop; % dark image needs substracting from raw images
subu = subbbu(ind_b, :);
subv = subbbv(ind_b, :);
self.cluster.blobs{self.det_ind}(ind_b).nvar(subu(1):subu(2), subv(1):subv(2), bbw) = cast(rawimg_crop, self.data_type);
end
end
end
end
function [bbwims_modified, bool_inproj] = modify_bbwims_and_check_bl_exist_raw(self, ii_proj, totproj)
bbwims_modified = self.bbwims;
bool_inproj = any(bbwims_modified <= (ii_proj - totproj), 2) & any(bbwims_modified >= (ii_proj - totproj), 2);
if any(bool_inproj)
bbwims_modified(bool_inproj, :) = bbwims_modified(bool_inproj, :) - totproj;
end
bool_inproj = any(bbwims_modified <= (ii_proj + totproj), 2) & any(bbwims_modified >= (ii_proj + totproj), 2);
if any(bool_inproj)
bbwims_modified(bool_inproj, :) = bbwims_modified(bool_inproj, :) + totproj;
end
bool_inproj = any(bbwims_modified <= ii_proj, 2) & any(bbwims_modified >= ii_proj, 2);
end
function set_bl_nvar_to_inf(self)
% initialize the noise variance to a very large value
switch lower(self.parameters.acq(self.det_ind).type)
case {'180degree', '360degree'}
blob_type = 'blob';
case 'topotomo'
blob_type = 'blob_topo';
end
nof_bl = numel(self.cluster.blobs{self.det_ind});
if ~isfield(self.cluster.blobs{self.det_ind}(1), 'nvar')
tmpbl = gtFwdSimBlobDefinition(blob_type, nof_bl);
for ii_b = nof_bl:-1:1
tmpbl(ii_b) = gtAddMatFile(tmpbl(ii_b), self.cluster.blobs{self.det_ind}(ii_b), true, false, false, false, false);
end
self.cluster.blobs{self.det_ind} = tmpbl;
end
for ii_b = nof_bl:-1:1
self.cluster.blobs{self.det_ind}(ii_b).nvar = cast(ones(size(self.cluster.blobs{self.det_ind}(ii_b).intm)) * self.invalid_pixel_nvar, self.data_type);
end
end
function add_noise_of_dark_images(self, var_n_dark, dark)
bbuim = self.bbuims;
bbvim = self.bbvims;
% find the range of the detector
bbuim_ondet = GtGrainCalcBlobNoiseVars.calcOndetBbim(bbuim, 1 + self.detector_margin, self.parameters.acq(self.det_ind).xdet - self.detector_margin);
subbbu = bsxfun(@minus, bbuim_ondet, bbuim(:, 1) - 1);
bbvim_ondet = GtGrainCalcBlobNoiseVars.calcOndetBbim(bbvim, 1 + self.detector_margin, self.parameters.acq(self.det_ind).ydet - self.detector_margin);
subbbv = bsxfun(@minus, bbvim_ondet, bbvim(:, 1) - 1);
bbwsize = abs(self.bbwims(:,2) - self.bbwims(:,1)) + 1;
detind = self.det_ind;
if ~exist('var_n_dark', 'var') || isempty(var_n_dark)
[var_n_dark, dark] = GtGrainCalcBlobNoiseVars.calcDarkImageVariance(self.parameters.acq(detind));
end
var_n_dark(~dark) = self.invalid_pixel_nvar; % set the noise variance of bad pixels to a very large number.
var_n_dark = cast(var_n_dark', self.data_type);
nof_blobs = numel(self.cluster.blobs{detind});
for n = 1:nof_blobs
tmp_dark_var = var_n_dark(bbuim_ondet(n, 1):bbuim_ondet(n, 2), bbvim_ondet(n, 1):bbvim_ondet(n, 2));
tmp_dark_var = tmp_dark_var(:, :, ones(1, bbwsize(n)));
spotaddbg = self.cluster.blobs{detind}(n).nvar(subbbu(n, 1):subbbu(n, 2), subbbv(n, 1):subbbv(n, 2), :) + tmp_dark_var;
% set the noise variance out of the detector to a very large number
self.cluster.blobs{detind}(n).nvar = cast(ones(size(self.cluster.blobs{detind}(n).nvar)) * self.invalid_pixel_nvar, self.data_type);
self.cluster.blobs{detind}(n).nvar(subbbu(n, 1):subbbu(n, 2), subbbv(n, 1):subbbv(n, 2), :) = cast(spotaddbg, self.data_type);
end
end
function apply_detector_mask(self, detind)
nof_bl = numel(self.cluster.blobs{detind});
size_detmask = size(self.detector_mask);
for ii_b = 1:nof_bl
size_nvar = size(self.cluster.blobs{detind}(ii_b).nvar);
nvarinactmask = false(size_nvar(1), size_nvar(2));
bbim = self.cluster.blobs{detind}(ii_b).bbuim;
bbuinds = bbim(1):bbim(2);
bool_bbuindsondet = ~((bbuinds < 1) | (bbuinds > size_detmask(1)));
bbim = self.cluster.blobs{detind}(ii_b).bbvim;
bbvinds = bbim(1):bbim(2);
bool_bbvindsondet = ~((bbvinds < 1) | (bbvinds > size_detmask(2)));
nvarinactmask(bool_bbuindsondet, bool_bbvindsondet) = ~self.detector_mask(bbuinds(bool_bbuindsondet), bbvinds(bool_bbvindsondet));
nvarinactmask = nvarinactmask(:, :, ones(1, size_nvar(3)));
self.cluster.blobs{detind}(ii_b).nvar(nvarinactmask) = self.invalid_pixel_nvar;
end
end
end
end
\ No newline at end of file
Loading