You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AsPylib中translate_Bspline加载Bspline模块失败求助

问题:AsPylib中translate_Bspline函数调用失败

场景说明

按照AsPylib官方文档编写图像平移代码,执行以下命令时出现错误,但其他几何变换功能正常:

data2 = astro.translate_Bspline(data, [40.3, 150.2], 3)

报错信息

Error in aspylib.astro.translate_Bspline()
Traceback (most recent call last):
File "C:\Aspylib_v3.0.0\aspylib\astro\transform.py", line 40, in translate_Bspline
cdll.Bspline.Translate.argtypes = [c_long, c_long, c_long, ndpointer(dtype=np.float32), ndpointer(dtype=np.float32), c_long, ndpointer(dtype=np.float32)]
^^^^^^^^^^^^
File "C:\Users\hfedd\AppData\Local\Programs\Python\Python311\Lib\ctypes_init_.py", line 446, in getattr
dll = self.dlltype(name)
^^^^^^^^^^^^^^^^^^^
File "C:\Users\hfedd\AppData\Local\Programs\Python\Python311\Lib\ctypes_init
.py", line 376, in init
self._handle = _dlopen(self._name, mode)
^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: Could not find module 'Bspline' (or one of its dependencies). Try using the full path with constructor syntax.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\hfedd\Downloads\new8.py", line 19, in
data2 = astro.translate_Bspline(data, [40.3, 150.2], 3)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Aspylib_v3.0.0\aspylib\astro\transform.py", line 54, in translate_Bspline
raise Exception("more than 3 consecutive failures, execution stopped")
Exception: more than 3 consecutive failures, execution stopped

问题代码

怀疑问题出在transform.py文件的ctypes用法上,原代码如下:

# -*- coding: iso_8859_1 -*-

import numpy as np
import platform as pf
import aspylib.conf as conf

from ctypes import c_long, c_float, cdll
from numpy.ctypeslib import ndpointer 

def translate_Bspline(images, shift, spline_degree):
    """
    ---------------------
    Purpose
    Translates an image (or list of images) by non-integer shifts in both X and Y directions.
    B-Spline interpolation with arbitrary order (from 2 to 9) is used to calculate the translated pixels.
    ---------------------
    Inputs
    * images (2D or 3D Numpy array) = array that contains the data of one image (2D case) or the data of a list of images (3D case).
    * shift ([float, float]) = 2 elements list that contains respectively the shifts in X (vertical) and Y (horizontal) directions.
    * spline_degree (integer) = the degree of the B-Spline that is used for interpolation : it can be 2, 3, 4, 5, 6, 7, 8 or 9.
    ---------------------
    Output (2D or 3D Numpy array) = transformed image data.
    ---------------------
    """

    ierror = 0
    while True:
        try:
            if len(images.shape)==2:
                dim = 1
                dim_x, dim_y = images.shape
            else:
                dim, dim_x, dim_y = images.shape
                
            indata = np.ascontiguousarray(np.array(images, dtype = np.float32))
            dxy = np.ascontiguousarray(np.array(shift, dtype = np.float32))
            outdata = np.ascontiguousarray(np.empty(images.shape, dtype = np.float32))
            
            if pf.system()=='Windows':
                cdll.Bspline.Translate.argtypes = [c_long, c_long, c_long, ndpointer(dtype=np.float32), ndpointer(dtype=np.float32), c_long, ndpointer(dtype=np.float32)]
                cdll.Bspline.Translate(dim,dim_x,dim_y,indata,dxy,spline_degree,outdata)
            elif pf.system()=='Linux':
                mydll = cdll.LoadLibrary("libbspline.so")
                mydll.Translate.argtypes = [c_long, c_long, c_long, ndpointer(dtype=np.float32), ndpointer(dtype=np.float32), c_long, ndpointer(dtype=np.float32)]
                mydll.Translate(dim,dim_x,dim_y,indata,dxy,spline_degree,outdata)

            del indata
            del dxy
            break
        except:
            print("error in aspylib.astro.translate_Bspline()")
            ierror+=1
            if ierror>3:
                raise Exception("more than 3 consecutive failures, execution stopped")
            pass

    return outdata

修复方案

针对原代码的问题,修改后的transform.py代码如下:

# -*- coding: iso_8859_1 -*-

import numpy as np
import platform as pf
import aspylib.conf as conf
import os

from ctypes import c_long, c_float, cdll
from numpy.ctypeslib import ndpointer 

# 缓存加载的DLL实例,避免重复加载
_bspline_dll = None

def translate_Bspline(images, shift, spline_degree):
    """
    ---------------------
    Purpose
    对单张图像(2D数组)或多张图像(3D数组)进行非整数像素的XY方向平移。
    使用2-9阶B样条插值计算平移后的像素值。
    ---------------------
    Inputs
    * images (2D或3D Numpy数组):单张图像数据(2D)或多张图像数据(3D)
    * shift ([float, float]):XY方向的平移量,分别对应垂直(X)和水平(Y)方向
    * spline_degree (整数):B样条插值阶数,可选2-9
    ---------------------
    Output (2D或3D Numpy数组):变换后的图像数据
    ---------------------
    """
    global _bspline_dll

    # 处理图像维度
    if len(images.shape) == 2:
        dim = 1
        dim_x, dim_y = images.shape
    else:
        dim, dim_x, dim_y = images.shape
        
    # 转换为连续内存的float32数组
    indata = np.ascontiguousarray(images, dtype=np.float32)
    dxy = np.ascontiguousarray(shift, dtype=np.float32)
    outdata = np.empty_like(indata, dtype=np.float32)

    # 加载Bspline库
    if _bspline_dll is None:
        system = pf.system()
        if system == 'Windows':
            # 优先从AsPylib安装目录的lib文件夹加载DLL
            lib_path = os.path.join(os.path.dirname(conf.__file__), 'lib', 'Bspline.dll')
            if not os.path.exists(lib_path):
                # 找不到则尝试系统PATH或当前目录
                lib_path = 'Bspline.dll'
            _bspline_dll = cdll.LoadLibrary(lib_path)
        elif system == 'Linux':
            _bspline_dll = cdll.LoadLibrary("libbspline.so")
        else:
            raise RuntimeError(f"不支持的操作系统: {system}")

        # 设置函数参数类型,明确要求数组为C连续内存
        _bspline_dll.Translate.argtypes = [
            c_long, c_long, c_long,
            ndpointer(dtype=np.float32, flags='C_CONTIGUOUS'),
            ndpointer(dtype=np.float32, flags='C_CONTIGUOUS'),
            c_long,
            ndpointer(dtype=np.float32, flags='C_CONTIGUOUS')
        ]

    # 调用插值函数
    _bspline_dll.Translate(dim, dim_x, dim_y, indata, dxy, spline_degree, outdata)

    return outdata

修改说明

  1. 修复DLL加载问题:Windows下显式指定DLL的可能路径,避免隐式加载找不到模块的问题;同时用全局变量缓存DLL实例,避免重复加载。
  2. 优化数组处理:用np.empty_like替代np.empty,简化代码且保证输出数组与输入维度一致。
  3. 改进错误处理:移除无意义的循环重试逻辑,直接抛出明确错误,便于排查问题。
  4. 严谨参数类型:给ndpointer添加C_CONTIGUOUS标志,确保传递给C函数的数组是连续内存布局,符合ctypes要求。

内容的提问来源于stack exchange,提问作者Hendrik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 10:05:37