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

OpenCV4兼容OpenCV2重映射函数及插值标志问题技术问询

光场显微镜校准代码移植解决方案(Python3+OpenCV4.x)

问题核心

原代码中cv.Remap的三个标志在OpenCV4.x中已变更:

  • cv.CV_INTER_LINEAR → cv.INTER_LINEAR
  • cv.CV_WARP_INVERSE_MAP:OpenCV3+的cv.remap默认采用目标像素→源像素的映射逻辑,与该标志的原行为一致,无需额外指定
  • cv.CV_WARP_FILL_OUTLIERS:该功能移至borderMode参数,通过cv.BORDER_CONSTANT实现边界填充

修改后的完整代码

# 图像扭曲函数
# 输入input_image需为numpy float32数组,返回处理后的图像
def warp_image(self, input_image, output_pixels_per_lenslet, direction="R",
               cropToInside=False, lenslet_offset=None, output_size=None):
    im = input_image
    ul = self.eval_point([0, 0], 'f')
    ur = self.eval_point([0, im.shape[1]], 'f')
    ll = self.eval_point([im.shape[0], 0], 'f')
    lr = self.eval_point([im.shape[0], im.shape[1]], 'f')
    
    leftbound = np.ceil(max(ul[1], ll[1]))
    rightbound = np.floor(min(ur[1], lr[1]))
    topbound = np.ceil(max(ul[0], ur[0]))
    bottombound = np.floor(min(ll[0], lr[0]))

    # 不裁剪透镜阵列左侧(0,y)或上方(x,0)区域
    leftbound = max(leftbound, 0)
    topbound = max(topbound, 0)

    if output_size is not None:
        putative_output_size = output_size
    else:
        nt = int(np.floor(bottombound - topbound))
        ns = int(np.floor(rightbound - leftbound))
        putative_output_size = (nt * output_pixels_per_lenslet, ns * output_pixels_per_lenslet)
    
    # 计算映射坐标
    scaled_shift = (0.0, 0.0)
    if direction.upper() == 'F':
        coeff = np.copy(self.forwardCoefficients)
        coeff[:,1:] *= output_pixels_per_lenslet
        coeff[:,3:] *= output_pixels_per_lenslet
        coeff[:,6:] *= output_pixels_per_lenslet
        if lenslet_offset is not None:
            scaled_shift = (lenslet_offset[0] / output_pixels_per_lenslet,
                            lenslet_offset[1] / output_pixels_per_lenslet)
    else:
        coeff = np.copy(self.reverseCoefficients)
        coeff[:,1:] /= output_pixels_per_lenslet
        coeff[:,3:] /= output_pixels_per_lenslet
        coeff[:,6:] /= output_pixels_per_lenslet
        if lenslet_offset is not None:
            scaled_shift = (lenslet_offset[0] * output_pixels_per_lenslet,
                            lenslet_offset[1] * output_pixels_per_lenslet)

    x, y = np.meshgrid(np.arange(putative_output_size[1], dtype='float32'), 
                       np.arange(putative_output_size[0], dtype='float32'))

    ix_array = (np.ones_like(x, dtype='float32') * coeff[0,0] 
                + x * coeff[0,1] + y * coeff[0,2] 
                + x*x * coeff[0,3] + x*y * coeff[0,4] + y*y * coeff[0,5] 
                + x*x*x * coeff[0,6] + x*x*y * coeff[0,7] + x*y*y * coeff[0,8] + y*y*y * coeff[0,9] 
                + scaled_shift[0])
    iy_array = (np.ones_like(y, dtype='float32') * coeff[1,0] 
                + x * coeff[1,1] + y * coeff[1,2] 
                + x*x * coeff[1,3] + x*y * coeff[1,4] + y*y * coeff[1,5] 
                + x*x*x * coeff[1,6] + x*x*y * coeff[1,7] + x*y*y * coeff[1,8] + y*y*y * coeff[1,9] 
                + scaled_shift[1])
    ix = ix_array.astype(np.float32)
    iy = iy_array.astype(np.float32)

    # OpenCV4.x版本的remap调用
    # 采用线性插值,边界填充为0(与原CV_WARP_FILL_OUTLIERS行为一致)
    output_image = cv.remap(im, ix, iy, 
                            flags=cv.INTER_LINEAR,
                            borderMode=cv.BORDER_CONSTANT,
                            borderValue=0.0)

    # 裁剪逻辑
    if cropToInside:
        return output_image[int(topbound * output_pixels_per_lenslet):int(bottombound * output_pixels_per_lenslet),
                            int(leftbound * output_pixels_per_lenslet):int(rightbound * output_pixels_per_lenslet)]
    else:
        return output_image

关键改动说明

  1. 标志参数适配

    • 移除CV_WARP_INVERSE_MAP:OpenCV3+的cv.remap默认将ix/iy视为目标像素到源像素的映射坐标,与原代码该标志的行为完全一致
    • 用borderMode=cv.BORDER_CONSTANT替代CV_WARP_FILL_OUTLIERS:对超出源图像边界的映射像素填充固定值(这里设为0,与原逻辑一致)
  2. 函数调用方式变更

    • OpenCV4.x的cv.remap无需预先创建输出图像,直接返回处理结果,简化了代码逻辑
  3. 细节优化

    • 用np.ones_like(x)替代手动创建全1数组,更高效且易维护
    • 修复了原代码中if np.any(lenslet_offset) != None的错误判断,改为if lenslet_offset is not None,避免空值判断异常

内容的提问来源于stack exchange,提问作者Oğulcan Cingiler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:04:54