首页 > 解决方案 > Python-OpenCV 填充函数;奇怪的类型错误

问题描述

我正在尝试使用 OpenCV 和(自然)NumPy 在 Python 中实现我自己的 MatLab 函数 imhmin() 版本。如果你不熟悉这个 MatLab 函数,它对分割非常有用。MatLab 的文档可以比我更好地解释它:

https://it.mathworks.com/help/images/ref/imhmin.html

这是我到目前为止所拥有的:

(为了简短起见,我没有包含 local_min 函数。它采用一个图像参数并返回一个相同大小的图像,其中局部最小值为 1,其他一切为 0。)

from volume import show
import cv2
import numpy

def main():
    arr = numpy.array( [[5,5,5,5,5,5,5],
                        [5,0,3,1,4,2,5],
                        [5,5,5,5,5,5,5]] ) + 1

    res = imhmin(arr, 3)

    print(res)


def imhmin(src, h):
    # TODO: speed up function by cropping image

    edm = src.copy()

    # d is the domain / all values contained in the array
    d = numpy.unique(edm)

    # for the index of each local minima (sorted gtl)
    indices = numpy.nonzero(local_min(edm)) # get indices
    indices = numpy.dstack((indices[0], indices[1]))[0].tolist() # zip
    # sort based on the value of edm[] at that index
    indices.sort(key = lambda _: edm[_[0],_[1]], reverse = True)

    for (x,y) in indices:
        start = edm[x,y] # remember original value of minima

        # for each in a list of heights greater than the starting height
        for i in range(*numpy.where(d==edm[x,y])[0], d.shape[0]-1):
            # prevent exceeding target height
            step = start + h if (d[i+1] - start > h) else d[i+1]

            #-------------- WORKS UNTIL HERE --------------#

            # complete floodFill syntax:
            # cv2.floodFill(image, mask, seed, newVal[, loDiff[, upDiff[, flags]]]) → retval, rect

            # fill UPWARD onto image (and onto mask?)
            cv2.floodFill(edm, None, (y,x), step, 0, step-d[i], 4)

            # fill DOWNWARD NOT onto image
            # have you overflowed?


if __name__ == "__main__":
    main()

在到达填充线之前,它工作正常。它咆哮了这个错误:

Traceback (most recent call last):
  File "edm.py", line 94, in <module>
    main()
  File "edm.py", line 14, in main
    res = imhmin(arr, 3)
  File "edm.py", line 66, in imhmin
    cv2.floodFill(edm, None, (y,x), step, 0, step-d[i], 4)
TypeError: Layout of the output array image is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)

起初我以为我布置参数的方式可能是错误的,因为step回溯中的内容,但我尝试更改该变量的名称,并得出结论step是 OpenCV 代码中的某个变量名称。它在谈论输出数组,我没有使用掩码,所以数组一定有问题edm

我可以通过用这个替换洪水填充线来抑制这个错误:

cv2.floodFill(edm.astype(numpy.double), None, (y,x), step, 0, step-d[i], 4)

不同之处在于我将 numpy 数组类型转换为浮点数组。然后我留下了这个错误:

Traceback (most recent call last):
  File "edm.py", line 92, in <module>
    main()
  File "edm.py", line 14, in main
    res = imhmin(arr, 3)
  File "edm.py", line 64, in imhmin
    cv2.floodFill(edm.astype(numpy.double), None, (y,x), step, 0, step-d[i], 4)
TypeError: Scalar value for argument 'newVal' is not numeric

这是我开始怀疑有什么严重错误的地方,因为step这里“显然”将是一个整数(也许它并不明显,但我确实尝试打印它,它看起来只是一个整数,而不是一个数组整数或类似的任何奇怪的东西)。

为了处理错误消息,我将newVal参数类型转换为浮点数。我得到了关于upDiff参数的几乎完全相同的错误消息,所以我也只是对它进行了类型转换,导致这行代码:

cv2.floodFill(edm.astype(numpy.double), None, (y,x), float(step), 0, float(step-d[i]), 4)

我知道这不是我想做的事情,但我只是想看看会发生什么。发生的事情是我遇到了这个看起来很可怕的错误:

Traceback (most recent call last):
  File "edm.py", line 92, in <module>
    main()
  File "edm.py", line 14, in main
    res = imhmin(arr, 3)
  File "edm.py", line 64, in imhmin
    cv2.floodFill(edm.astype(numpy.double), None, (y,x), float(step), 0, float(step-d[i]), 4)
cv2.error: OpenCV(3.4.2) /opt/concourse/worker/volumes/live/9523d527-1b9e-48e0-7ed0-a36adde286f0/volume/opencv-suite_1535558719691/work/modules/imgproc/src/floodfill.cpp:587: error: (-210:Unsupported format or combination of formats)  in function 'floodFill'

我什至不知道从哪里开始。我之前多次使用过 OpenCV 的 Floodfill 功能,从来没有遇到过这样的问题。任何人都可以提供任何见解吗?

提前致谢

安东尼奥

标签: pythonmatlabnumpyopencv

解决方案


推荐阅读