open cv error: (-215) scn == 3 || scn == 4 in function cvtColor

open cv error: (-215) scn == 3 || scn == 4 in function cvtColor

我目前使用 Ubuntu 14.04,使用 python 2.7 和 cv2。

当我运行这个代码时:

import numpy as np
import cv2

img = cv2.imread('2015-05-27-191152.jpg',0)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

它returns:

 File "face_detection.py", line 11, in <module>
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.error: /home/arthurckl/Desktop/opencv-3.0.0-rc1/modules/imgproc/src/color.cpp:7564: error: (-215) scn == 3 || scn == 4 in function cvtColor

我已经在这里搜索过,一个答案说我可能以错误的方式加载了我的照片,因为它应该有 3 个维度:行、列和深度。

当我打印 img.shape 时,它 returns 只有两个数字,所以我一定是做错了。但是我不知道怎么加载我的照片。

请设置如下

img = cv2.imread('2015-05-27-191152.jpg',1)     // Change Flag As 1 For Color Image
                                                //or O for Gray Image So It image is 
                                                //already gray

用正斜杠给出图像的完整路径。它为我解决了错误。

例如

import numpy as np
import cv2

img = cv2.imread('C:/Python34/images/2015-05-27-191152.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

此外,如果您在使用 cv2.imread 加载图像时在第二个参数中给出 0,则无需使用 cvtColor 转换图像,它已经作为灰度图像加载,例如。

import numpy as np
import cv2

gray = cv2.imread('C:/Python34/images/2015-05-27-191152.jpg',0)

首先你应该检查的是图像是否存在于根目录中。这主要是由于图像的高度 = 0。这意味着 cv2.imread(imageName) 没有读取图像。

这是我使用自己的 .jpg 格式图像集时观察到的结果。在 Opencv doc 中可用的示例脚本中,请注意它有 undistortcrop the image 行,如下所示:

# undistort
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)

# crop the image
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.jpg',dst)

因此,当我们第一次 运行 代码时,它会执行行 cv2.imwrite('calibresult.jpg',dst) 在当前目录中保存图像 calibresult.jpg。因此,当我下次 运行 代码时,连同我用于以 jpg 格式校准相机的示例图像集,代码也尝试考虑这个新添加的图像 calibresult.jpg 由于错误弹出

error: C:\builds\master_PackSlaveAddon-win64-vc12-static\opencv\modules\imgproc\src\color.cpp:7456: error: (-215) scn == 3 || scn == 4 in function cv::ipp_cvtColor

我所做的是:我只是在每个 运行 之后删除了新生成的图像,或者将图像的类型更改为 pngtiff 类型。那解决了问题。检查您是否正在输入和写入相同类型的 calibresult。如果是这样,只需更改类型。

只传递图片名称,不需要0:

img=cv2.imread('sample.jpg')
img = cv2.imread('2015-05-27-191152.jpg',0)

上面的代码行以灰度颜色模型读取您的图像,因为末尾附加了 0。如果您再次尝试将已经是灰色的图像转换为灰色图像,它将显示该错误。

所以要么使用上面的样式,要么尝试下面提到的代码:

img = cv2.imread('2015-05-27-191152.jpg')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

我觉得是因为cv2.imread看不懂.jpg图片,需要把.jpg改成.png

由于与其他答案中提到的标志 0 或 1 完全无关的原因,我已经出现了此错误消息。您可能也会看到它,因为如果您传递给它的路径字符串不是图像,cv2.imreadnot 出错:

In [1]: import cv2
   ...: img = cv2.imread('asdfasdf')  # This is clearly not an image file
   ...: gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
   ...:

OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cv::cvtColor, file C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp, line 10638
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-4-19408d38116b> in <module>()
      1 import cv2
      2 img = cv2.imread('asdfasdf')  # This is clearly not an image file
----> 3 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

error: C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp:10638: error: (-215) scn == 3 || scn == 4 in function cv::cvtColor

所以您看到的是 cvtColor 失败,而实际上它是一个静默的 imread 错误。下次你用那个神秘的比喻浪费你生命中的一个小时时请记住这一点.

解决方案

在将路径字符串传递给 cv2.imread 之前,您可能需要检查它是否代表有效文件:

import os


def read_img(path):
    """Given a path to an image file, returns a cv2 array

    str -> np.ndarray"""
    if os.path.isfile(path):
        return cv2.imread(path)
    else:
        raise ValueError('Path provided is not a valid file: {}'.format(path))


path = '2015-05-27-191152.jpg'
img = read_img(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

这样写,你的代码会优雅地失败。

此答案适用于在尝试访问相机时遇到同样问题的人。

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()

    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # Display the resulting frame
    cv2.imshow('frame',gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

使用Linux:

如果您尝试从您的计算机访问摄像头,很可能存在权限问题,请尝试 运行使用 sudo 设置 python 脚本应该可以修复它。

sudo python python_script.py

测试摄像头是否可用运行以下命令。

ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video0 output.mkv 

对于那些在尝试访问相机时遇到同样问题的人,可以编写安全检查代码。

if ret is True:
   gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
else:
   continue

或 如果你想关闭相机/如果框架本身有问题则停止

if ret is True:
   gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
else:
   break

供参考https://github.com/HackerShackOfficial/AI-Smart-Mirror/issues/36

cv2.error: /home/arthurckl/Desktop/opencv-3.0.0-rc1/modules/imgproc/src/color.cpp:7564: error: (-215) scn == 3 || scn == 4 in function cvtColor

上述错误是由于图像名称无效或本地目录中不存在该文件造成的。

img = cv2.imread('2015-05-27-191152.jpg',0)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

此外,如果您将 cv2.imread() 的第二个参数用作“0”,那么它已经转换为灰度图像。

通过传递 0 作为参数转换图像与应用以下内容之间的区别:

img = cv2.cvtCOLOR(img, cv2.COLOR_BGR2GRAY) 

就是,在img = cv2.cvtCOLOR(img, cv2.COLOR_BGR2GRAY)的情况下,图像是8uC1和32sC1类型的图像。

在 OS X 我意识到,虽然 cv2.imread 可以处理 "filename.jpg" 但不能处理 "file.name.jpg"。作为 python 的新手,我还不能提出解决方案,但正如 François Leblanc 所写,它更像是一个静默的 imread 错误。

因此文件名中的附加点和可能还有其他符号存在问题,例如“”(Space)或“%”等。

我还发现如果你的网络摄像头没有正确关闭或者有什么正在使用它,那么 CV2 也会给出同样的错误。 我必须重新启动我的电脑才能让它再次工作。

消除该错误的最简单解决方案是 运行 命令

cap.release()
cv2.closeAllWindows()

这对我有用,有时还需要重新启动内核,因为后台有旧进程 运行。

如果图像不在工作目录中,那么它也不会为此工作尝试将图像文件放在 pwd 中的同一文件夹中,因为有代码否则提供图像文件或文件夹的完整路径.

为避免将来出现此问题,请尝试使用异常处理进行编码 因此,如果由于某种随机原因发生错误终止,捕获设备将在程序结束后被释放。

2015-05-27-191152.jpg << 回头看你的图片格式,我偶尔会混淆.png和.jpg,遇到同样的错误。

在我的例子中,通过迁移到 OpenCV 4.0(或更高版本)解决了错误。

好吧,我遇到了同样的问题,但我没有获取输入图像而是获取视频帧,上述解决方案对此不起作用。 问题出在摄像头访问上,您的笔记本电脑的摄像头仍在被您之前的代码使用,您只需重新启动内核即可。