Question about preprocessing FDG-PET image

Hi everyone,
I’m new to neurodata and I am learn to preprocess 18F-FDG Pet images for deep learning models. Raw data (left one) n output (right one) look like this:

But after preprocessing (spatial norm using MNI template + intensity normalization + gaussian smoothing), they are all look wrong, can you tell me help me identify what is the problem with my matlab code, and should i use spm matlab for preprocessing PET data or is there any robust python toolbox for preprocessing PET data, here is my code. Thank you so much for your help.

function preprocess_pet_batch(root_dir, output_dir)

spm(‘defaults’, ‘PET’);spm_jobman(‘initcfg’);

template = fullfile(spm(‘Dir’), ‘toolbox’, ‘OldNorm’, ‘PET.nii’);if ~exist(template, ‘file’)error(‘SPM PET template not found at:\n  %s\nCheck your SPM installation.’, template);end

if ~exist(output_dir, ‘dir’)mkdir(output_dir);end

subj_entries = dir(root_dir);subj_dirs    = subj_entries([subj_entries.isdir] & …~ismember({subj_entries.name}, {‘.’,‘..’}));

if isempty(subj_dirs)warning(‘No subject folders found in: %s’, root_dir);returnend

fprintf(‘\n=== PET Preprocessing Pipeline ===\n’);fprintf(‘Root dir  : %s\n’, root_dir);fprintf(‘Output dir: %s\n’, output_dir);fprintf(‘Subjects  : %d\n\n’, numel(subj_dirs));

for s = 1:numel(subj_dirs)subj_name = subj_dirs(s).name;subj_path = fullfile(root_dir, subj_name);fprintf('[%d/%d] Subject: %s\n', s, numel(subj_dirs), subj_name);

% Find all .nii files recursively under this subject folder
nii_files = find_nii_files(subj_path);

if isempty(nii_files)
    fprintf('  >> No .nii files found – skipping.\n');
    continue
end

for f = 1:numel(nii_files)
    src_nii = nii_files{f};
    fprintf('  [%d/%d] %s\n', f, numel(nii_files), src_nii);

    try
        % ---- mirror folder structure in output_dir ---- %
        rel_path   = strrep(src_nii, root_dir, '');   % relative path
        rel_path   = strtrim(rel_path);
        if rel_path(1) == filesep
            rel_path(1) = [];
        end
        dst_nii    = fullfile(output_dir, rel_path);
        dst_folder = fileparts(dst_nii);
        if ~exist(dst_folder, 'dir')
            mkdir(dst_folder);
        end

        % Copy source .nii (and companion .mat if present) to output
        copyfile(src_nii, dst_nii);
        src_mat = strrep(src_nii, '.nii', '.mat');
        if exist(src_mat, 'file')
            copyfile(src_mat, strrep(dst_nii, '.nii', '.mat'));
        end

        % From here on, work on the copy so the source is untouched
        pet_file = dst_nii;

        reset_origin(pet_file);

        [pet_dir, pet_stem, pet_ext] = fileparts(pet_file);
        warped_file = fullfile(pet_dir, ['w' pet_stem pet_ext]);
        run_normalise(pet_file, template);

        
        [~, w_stem, w_ext] = fileparts(warped_file);
        global_normed_file = fullfile(pet_dir, ['g' w_stem w_ext]);
        run_intensity_norm(warped_file, global_normed_file);

        
        [~, gn_stem, gn_ext] = fileparts(global_normed_file);
        smoothed_file = fullfile(pet_dir, ['s' gn_stem gn_ext]);
        spm_smooth(global_normed_file, smoothed_file, [8 8 8]);

        delete_if_exists(warped_file);
        delete_if_exists(global_normed_file);
        sn_mat = fullfile(pet_dir, [pet_stem '_sn.mat']);
        delete_if_exists(sn_mat);
        % delete_if_exists(pet_file);
        fprintf('     >> Done: %s\n', smoothed_file);

    catch ME
        fprintf('     !! ERROR on %s\n     %s\n', src_nii, ME.message);
    end
end
end
fprintf('\n=== All subjects processed. ===\n');
end

function nii_list = find_nii_files(folder)
% Return cell array of absolute paths to all .nii files under folder.
    items    = dir(fullfile(folder, '**', '*.nii'));
    nii_list = fullfile({items.folder}, {items.name})';
end


function reset_origin(nii_file)
% Reset the origin of a NIfTI volume to its centre of mass.
    V   = spm_vol(nii_file);
    dim = V.dim;
    M   = V.mat;
    M(1:3, 4) = -M(1:3, 1:3) * (dim(:) / 2);
    spm_get_space(nii_file, M);
end


function run_normalise(pet_file, template)
% Estimate + write spatial normalisation to MNI space using SPM OldNorm.
    clear matlabbatch

    matlabbatch{1}.spm.spatial.normalise.estwrite.subj.source  = {pet_file};
    matlabbatch{1}.spm.spatial.normalise.estwrite.subj.wtsrc   = '';
    matlabbatch{1}.spm.spatial.normalise.estwrite.subj.resample = {pet_file};

    matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.template = {template};
    matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.weight   = '';
    matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.smosrc   = 8;
    matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.smoref   = 0;
    matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.regtype  = 'mni';
    matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.cutoff   = 25;
    matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.nits     = 16;
    matlabbatch{1}.spm.spatial.normalise.estwrite.eoptions.reg      = 1;

    matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.preserve = 0;
    matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.bb       = ...
        [-90 -126 -72; 90 90 108];
    matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.vox      = [2 2 2];
    matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.interp   = 4;
    matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.wrap     = [0 0 0];
    matlabbatch{1}.spm.spatial.normalise.estwrite.roptions.prefix   = 'w';

    spm_jobman('run', matlabbatch);
end


function run_intensity_norm(in_file, out_file)

    V    = spm_vol(in_file);
    Y    = spm_read_vols(V);
    mask = Y > 0;

    if ~any(mask(:))
        error('Intensity normalisation: no positive voxels found in %s', in_file);
    end

    global_mean = mean(Y(mask));
    fprintf('     Global mean = %.4f\n', global_mean);

    Y_norm      = Y / global_mean;
    Vout        = V;
    Vout.fname  = out_file;
    spm_write_vol(Vout, Y_norm);
end


function delete_if_exists(fpath)
    if exist(fpath, 'file')
        delete(fpath);
    end
end

root_dir = '...';
output_dir = '...';
preprocess_pet_batch(root_dir, output_dir);