python - 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 功能,从来没有遇到过这样的问题。任何人都可以提供任何见解吗?
提前致谢
安东尼奥
解决方案
推荐阅读
- vue.js - 如何为应用程序中的所有组件设置全局属性
- ruby-on-rails - Rails 片段缓存是否会对存储 SVG 或复杂 html 的性能有所改进?
- shopify - 使用 javascript 检查产品在 Shopify 中是否可用
- sql - 有没有更优雅的方式来编写这个 Oracle SQL 查询?
- google-cloud-platform - GCP 中的 HTTP 端点
- internet-explorer-11 - fls.doubleclick.net 仅在 IE11 中下载缓慢
- python - 谷歌 SMTP 在发送邮件时出错
- python-3.x - 在 python 中使用 pandas 打印名为 12/12/12 的列
- google-cloud-platform - 从 Cloud Source 启动 Dataproc PySpark 作业
- java - Java 8 将简单的列表转换为地图