寻找 OpenCV4 插值标志/重映射函数的 OpenCV2 替代品

Looking for an OpenCV4 alternative for OpenCV2 Interpolation Flag/Remapping Function

提问人:Oğulcan Cingiler 提问时间:11/8/2023 最后编辑:Oğulcan Cingiler 更新时间:11/8/2023 访问量:27

问:

我目前正在将大约 10 年前编写的 Python 2.7 代码移植到 Python 3,它是使用 OpenCV 2.x 编写的,在一行中有一个部分会扭曲图像,但是当我尝试使用 OpenCV 4.x 在 Python 3 中运行该行时,由于 OpenCV 无法识别插值标志,我无法运行它。

这是一行:

cv.Remap(im, output_image, ix, iy, flags=cv.CV_INTER_LINEAR+cv.CV_WARP_FILL_OUTLIERS+cv.CV_WARP_INVERSE_MAP)

OpenCV 在当前版本中有一个非常相似的功能,这行没有其他插值标志可以工作,但结果似乎不同:

output_image = cv.remap(im,output_image,ix,iy,flags=cv.INTER_LINEAR)

im 是输入图像,output_image 是之前声明过的空数组,ix 和 iy 是两个数组。该代码是光场显微镜校准代码,在此功能中,他们正在执行“立方翘曲”,我在互联网上也找不到任何信息。

我尝试使用 warpPerspective,但它要求一个转换矩阵,而我没有。我尝试使用findTransformECC,但无法使其正常工作。我尝试在 Python 2.7 中使用 OpenCV 2.4,它有效,但由于不再支持 Python 2,因此最好有一个更面向未来的解决方案。

以下是完整功能:

# Warp an image.
    #
    # This function expects im to be a numpy float32 array.  Returns 
    def warp_image(self, input_image, output_pixels_per_lenslet, direction="R",
                   cropToInside = False, lenslet_offset = None, output_size = None):
        #im = cv.fromarray(input_image)
        im = (input_image)
        ul = self.eval_point([0, 0], 'f')
        #ur = self.eval_point([0, im.cols], 'f')
        ur = self.eval_point([0, im.shape[1]], 'f')
        #ll = self.eval_point([im.rows, 0], 'f')
        ll = self.eval_point([im.shape[0],0], 'f')
        #lr = self.eval_point([im.rows, im.cols], '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]))

        # Don't crop left of lenslets (0, y) or above (x, 0)
        leftbound = max(leftbound, 0)
        topbound = max(topbound,0)

        if output_size != 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)
        
        # Create the output image
        #output_image = cv.CreateMat(putative_output_size[0], putative_output_size[1], im.type)
        output_image = np.empty(shape=(putative_output_size[0],putative_output_size[1]),dtype = im.dtype)
        # Apply the transform.
        scaled_shift = (0.0, 0.0)
        if (direction == 'f' or direction == '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 != 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 np.any(lenslet_offset) != 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((putative_output_size[0], putative_output_size[1])).astype('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((putative_output_size[0], putative_output_size[1])).astype('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 = cv.fromarray(ix_array.astype(np.float32))
        #iy = cv.fromarray(iy_array.astype(np.float32))
        ix = ix_array.astype(np.float32)
        iy = iy_array.astype(np.float32)

        
        cv.Remap(im, output_image, ix, iy, flags=cv.CV_INTER_LINEAR+cv.CV_WARP_FILL_OUTLIERS+cv.CV_WARP_INVERSE_MAP)
        result = np.asarray(output_image)

        # Don't crop left of lenslets (0, y) or above (x, 0)
        leftbound = max(leftbound, 0)
        topbound = max(topbound,0)
    
        if cropToInside:
            return result[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 result
OpenCV的 插值 重新映射

评论

0赞 toyota Supra 11/8/2023
请发布脚本,以便我们对其进行测试。
1赞 Oğulcan Cingiler 11/8/2023
谢谢!我添加了完整的功能,如果需要,我也可以发布完整的脚本

答: 暂无答案