TypeError: Layout of the output array image is incompatible 问题解决
Posted mazinkaiser1991
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TypeError: Layout of the output array image is incompatible 问题解决相关的知识,希望对你有一定的参考价值。
本周在使用findContours的过程中遇到了以下问题:
TypeError: Layout of the output array image is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)
感谢这篇文章:https://www.jianshu.com/p/cc3f4baf35bb,引导我往正确的方向进行思考。
先讲结论造成以上问题的原因是:输入与输出的numpy格式不一致。
我一开始的第一反应是为什么findContours函数会有“output array image”,我只关注contours。这其实是我在写代码中一个盲区,对于findContours函数我一般都是这么写:
_, contours, _ = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
对于第一个与第三个返回值现阶段直接就跳过,这其实恰恰是产生问题的关键原因,完整的findContours函数输出应该如下:
binary, contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
binary的输出与image完全一样,所以在使用的时候一般就忽略了这个参数,顺便提一句在findContours函数的注释中有这么一句:
@note Since opencv 3.2 source image is not modified by this function.
opencv3.2之后就不会再修改image了,但是findContours函数为什么要改原图?挺让人费解的。到了opencv4.2之后这个返回值干脆就被取消了,又造成了一系列的软件兼容问题。
返回到这个错误上来,上面说了这么多就是想说findContours函数其实是有一个image array输出的。而这个array的要求非常严格。
我在处理image是按照channel维度对它进行遍历,然后在每个channel上执行findContours函数,为了确保后续操作不会影响原图,我首先对每个channel执行了复制操作,这又是产生问题的另一个关键因素。当时是执行了copy.deepcopy()操作,这在我之前的使用过程中都是没有问题的,包括我今天做实验依然没有问题,但是那天程序却一直在报错。而后改为了numpy的copy函数才通过。
我首先把可以用于numpy的拷贝方法与其对应的flags输出列在下面:
第一列表示原图的flags属性,one_channel表示使用遍历方式获得的一个channel的flags属性,cv2.split表示使用split函数获得的每一个channel的flags属性,numpy.copy()表示首先使用遍历方式获得一个channel,而后调用copy函数得到的一个channel的flags属性,最后copy.deepcopy()与numpy.copy()类似先遍历获得一个channel然后复制。
引用这篇博客中的一个关键结论:输入与输出必须完全一致,不单是值上的一致性,还需要保证array结构上的一致性。通过对比上表就可以发现,其实就是两点不一样:“C_CONTIGUOUS”与“OWNDATA ”,“OWNDATA ”非常好理解,使用切片方式获取数据,自然不拥有数据,只拥有数据的引用。“C_CONTIGUOUS”表示数据是在一个单一的C风格的连续段中,由于numpy存储数据是连续存储最后一个维度,而后倒数第二个,以此类推。因此单独获得一个channel的数据也就不是连续的了。
现在也就是比较明确了,对于opencv输入也是输出的函数,必须保证array在flags层面上的一致性。
在使用过程中推荐使用split函数与numpy copy()函数,因为我在使用copy.deepcopy过程中就遇到了“output array image is incompatible”问题。
PS:还要提一句findContours函数输入可以是(n, n)维度的,不一定要(n,n, 1)维度。
以上是关于TypeError: Layout of the output array image is incompatible 问题解决的主要内容,如果未能解决你的问题,请参考以下文章
TypeError: view must be a callable or a list/tuple in the case of include()
TypeError: view must be a callable or a list/tuple in the case of include()
Django urls.py报错: raise TypeError('view must be a callable or a list/tuple in the case of includ
django错误笔记——TypeError: view must be a callable or a list/tuple in the case of include().解决办法
nodejs - react - TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type str
nodejs - react - TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type str