ANTsX / ANTsPy

A fast medical imaging analysis library in Python with algorithms for registration, segmentation, and more.
https://antspyx.readthedocs.io
Apache License 2.0
586 stars 161 forks source link

Error in outputting deformation field and Jacobian determinant #635

Closed yesulove closed 1 month ago

yesulove commented 1 month ago

1.code:

import os
import ants
import numpy as np
import time

fix_path = '/home/bmw/Downloads/image/ant1/us.tif'
move_path = '/home/bmw/Downloads/image/ant1/DAPI.tif'
cbd_path = '/home/bmw/Downloads/image/ant1/CBD.tif'

# 配准所使用的各种方法 各方法耗时:https://www.cnblogs.com/JunzhaoLiang/p/12308200.html
types = ['Translation', 'Rigid', 'Similarity', 'QuickRigid', 'DenseRigid', 'BOLDRigid', 'Affine', 'AffineFast', 'BOLDAffine',
         'TRSAA', 'ElasticSyN', 'SyN', 'SyNRA', 'SyNOnly', 'SyNCC', 'SyNabp', 'SyNBold', 'SyNBoldAff', 'SyNAggro', 'TVMSQ']

# 保存为png只支持unsigned char & unsigned short,因此读取时先进行数据类型转换
# fix_img = ants.image_read(fix_path, pixeltype='unsigned char')
# move_img = ants.image_read(move_path, pixeltype='unsigned char')
# print(fix_img.astype,fix_img.pixeltype)
# print(move_img.astype,move_img.pixeltype)

fix_img = ants.image_read(fix_path)
move_img = ants.image_read(move_path)
cbd = ants.image_read(cbd_path)

print(fix_img.astype,fix_img.pixeltype)
print(move_img.astype,move_img.pixeltype)
print(cbd.astype,cbd.pixeltype)

for t in types:
    start = time.time()

    out = ants.registration(fix_img, move_img, type_of_transform=t)
    if len(out['fwdtransforms']) == 0:
        print(f"No forward transform found for {t}")
        continue
    # jac = ants.create_jacobian_determinant_image(fix_img, out['fwdtransforms'][0],1)
    # ants.image_write(jac, "./result/jac.nii.gz")
    reg_img = out['warpedmovout'] # 获取配准结果
    trans = out['fwdtransforms']
    print(len(trans))
    #将变形场作用于CBD
    warpedCBD = ants.apply_transforms(fixed=fix_img, moving=cbd,
                                           transformlist=out['fwdtransforms'])
    # warpedCBD.to_file(t + 'CBD.mat')
    # reg_img.to_file(t+'.png')

    # warpedCBD.to_file(t+'.tif')
    # print(jac)
    # print('trans.asytpe:',trans.asytpe)
    # ants.image_write(warpedCBD,t+'CBD.mat')
    ants.write_transform(trans,t+'.mat')

    print(t+' : ', time.time()-start, '\n')

2.error1:

Traceback (most recent call last):
  File "/home/bmw/PycharmProjects/pythonProject/ant848/1.py", line 53, in <module>
    ants.write_transform(trans,t+'.mat')
  File "/home/bmw/anaconda3/lib/python3.11/site-packages/ants/core/ants_transform_io.py", line 382, in write_transform
    libfn = utils.get_lib_fn("writeTransform%s" % (transform._libsuffix))
                                                   ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'list' object has no attribute '_libsuffix'
3.When I execute“jac = ants.create_jacobian_determinant_image(fix_img, out['fwdtransforms'][0],1)”,there is another error:
Traceback (most recent call last):
  File "/home/bmw/PycharmProjects/pythonProject/ant848/1.py", line 37, in <module>
    jac = ants.create_jacobian_determinant_image(fix_img, out['fwdtransforms'][0],1)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/bmw/anaconda3/lib/python3.11/site-packages/ants/registration/create_jacobian_determinant_image.py", line 172, in create_jacobian_determinant_image
    libfn(processed_args)
RuntimeError: /home/bmw/ANTsPy/itksource/Modules/IO/ImageBase/include/itkImageFileReader.hxx:135:
 Could not create IO object for reading file /tmp/tmpeilrbyu90GenericAffine.mat
  Tried to create one of the following:
    BMPImageIO
    BioRadImageIO
    Bruker2dseqImageIO
    GDCMImageIO
    GE4ImageIO
    GE5ImageIO
    GiplImageIO
    HDF5ImageIO
    JPEGImageIO
    JPEG2000ImageIO
    LSMImageIO
    MGHImageIO
    MINCImageIO
    MRCImageIO
    MetaImageIO
    NiftiImageIO
    NrrdImageIO
    PNGImageIO
    StimulateImageIO
    TIFFImageIO
    VTKImageIO
  You probably failed to set a file suffix, or
    set the suffix to an unsupported type.
cookpa commented 1 month ago

Here is a simple example:

>>> import ants
>>> fi = ants.image_read(ants.get_ants_data('r16'))
>>> mi = ants.image_read(ants.get_ants_data('r64'))
>>> mytx = ants.registration(fixed=fi, moving=mi, type_of_transform = 'SyN' )
>>> mytx['fwdtransforms']
['/var/folders/zd/9qflmdq95ks8q89wwk9461l80000gn/T/tmpieytk74h1Warp.nii.gz', '/var/folders/zd/9qflmdq95ks8q89wwk9461l80000gn/T/tmpieytk74h0GenericAffine.mat']

The mytx['fwdtransforms'] list is file names, you don't need to write them with write_transform, you can just copy them wherever you want them to live.

Now, mytx['fwdtransforms'] in this example has two entries because it does a 'SyN' registration. If I do a linear registration,

>>> mytx = ants.registration(fixed=fi, moving=mi, type_of_transform = 'Translation' )
>>> mytx['fwdtransforms']
['/var/folders/zd/9qflmdq95ks8q89wwk9461l80000gn/T/tmplh7jcjcl0GenericAffine.mat']

there is only the 0GenericAffine.mat. The ants.create_jacobian_determinant_image function only works on warp images, not linear transforms.

yesulove commented 1 month ago

Here is a simple example:

>>> import ants
>>> fi = ants.image_read(ants.get_ants_data('r16'))
>>> mi = ants.image_read(ants.get_ants_data('r64'))
>>> mytx = ants.registration(fixed=fi, moving=mi, type_of_transform = 'SyN' )
>>> mytx['fwdtransforms']
['/var/folders/zd/9qflmdq95ks8q89wwk9461l80000gn/T/tmpieytk74h1Warp.nii.gz', '/var/folders/zd/9qflmdq95ks8q89wwk9461l80000gn/T/tmpieytk74h0GenericAffine.mat']

The mytx['fwdtransforms'] list is file names, you don't need to write them with write_transform, you can just copy them wherever you want them to live.

Now, mytx['fwdtransforms'] in this example has two entries because it does a 'SyN' registration. If I do a linear registration,

>>> mytx = ants.registration(fixed=fi, moving=mi, type_of_transform = 'Translation' )
>>> mytx['fwdtransforms']
['/var/folders/zd/9qflmdq95ks8q89wwk9461l80000gn/T/tmplh7jcjcl0GenericAffine.mat']

there is only the 0GenericAffine.mat. The ants.create_jacobian_determinant_image function only works on warp images, not linear transforms.

Thank you very much. Your answer has solved my confusion!

ncullen93 commented 1 month ago

Glad this was solved. I personally think it makes more sense to return actual transform classes but oh well. FYI - you could write it to another file by reading the transform first:

tx = ants.read_transform(trans[0])
ants.write_transform(tx,t+'.mat')
yesulove commented 1 month ago

Glad this was solved. I personally think it makes more sense to return actual transform classes but oh well. FYI - you could write it to another file by reading the transform first:

tx = ants.read_transform(trans[0])
ants.write_transform(tx,t+'.mat')

Thank you very much. I was wondering why write_transform is not working. Your response made me realize that it was because we needed to read_transform first. Your reply is too timely hahaha!