如何将复杂值输入到OpenCV函数cv.dft()?

时间:2019-04-01 08:56:54

标签: python numpy opencv dft

我正在尝试执行研究论文中所述的内容。它描述了如何从图像中提取傅立叶特征。我尝试在编码时遵循这些步骤,但是反复遇到与输入数组的数据类型和尺寸有关的错误。 所以我问如何向函数输入复杂的值

我遵循了研究论文中的以下指示

傅里叶描述符:傅里叶描述符提供了一种编码方式 通过将每个像素位置(x,y)映射到一个图像边界 复数(x + i y)。

  1. 顺序记录每个像素的坐标值 (沿形状顺时针移动)
  2. 使用坐标值构造复数值向量 在步骤1中记录,即(x,y)→(x + i y)。
  3. 对复数值向量进行DFT

我的问题出在步骤3

这是我的实现方式

def get_dft(image):
    coordinates = cv.findNonZero(image)
    # the code below removes an unnecessary dimension
    coordinates = coordinates.reshape(coordinates.shape[0], 2)
    y = coordinates[:, 1] * 1j  # convert to complex numbers
    # the code below removes an unnecessary dimension
    y = y.reshape(coordinates.shape[0], 1)
    x = coordinates[:, 0].reshape(coordinates.shape[0], 1)
    # the statement below will convert from two separate arrays
    # to a single array with each element  
    # of the form [a + jb]
    t = x + y
    # below is where the error occurs
    dft = cv.dft(t, flags=cv.DFT_COMPLEX_INPUT) 

这是我得到的错误

TypeError: Expected cv::UMat for argument 'src'

当我转换为

a = numpy.ndarray(t)

我明白了

ValueError: sequence too large; cannot be greater than 32

要说的是大于32个尺寸。我不明白为什么会这样

当我尝试使用

a = numpy.ndarray([t])

我得到了错误

TypeError: only integer scalar arrays can be converted to a scalar index

简而言之,我想按照本文中提到的步骤进行操作,制作一个复杂的值向量,如

[[a+jb],[c+jd]...]    

并将其传递给DFT函数。

1 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法

def get_dft(image):
    coordinates = cv.findNonZero(image)
    coordinates = coordinates.reshape(coordinates.shape[0], 2).astype(float)
    y = coordinates[:, 1].reshape(coordinates.shape[0], 1)
    x = coordinates[:, 0].reshape(coordinates.shape[0], 1)
    t = cv.merge([x, y])  # used to convert to 2 channel
    dft = cv.dft(t, flags=cv.DFT_COMPLEX_INPUT)

我尝试了所有numpy api以及所有由于我不了解的原因而失败的方法,但幸运的是,OpenCV了

cv.merge(...)

工作。

它需要多个输入数组并合并以产生多通道输出。

我还尝试向OpenCV API函数输入复数

cv.dft(...)

这不是输入复数的正确方法。 OpenCV documentation explains complex input here

它指出标志cv.DFT_COMPLEX_INPUT

  

指定输入是复杂输入。如果设置了此标志,则输入必须具有2个通道。另一方面,出于向后兼容的原因,如果输入有2个通道,则输入已经被认为是复杂的

请注意,我还面临着转换为两个通道的问题,这是由于我没有正确理解结构cv :: UMat()的事实而发生的,该结构是该函数的输入所必需的。

摘要是,
如果要在OpenCV API函数中输入复数

cv.dft(...)

您的输入必须包含2个通道,才能完成制作两个通道的数组,即OpenCV函数

cv.merge(...)

link to its documentation,当您尝试合并多个单独的渠道时似乎可以正确完成工作。