TypeError:src不是一个numpy数组,也不是标量

时间:2017-08-24 14:41:59

标签: python python-2.7 opencv numpy image-processing

    gray_image = cv2.cvtColor(contrast, cv2.COLOR_BGR2GRAY)

TypeError: src is not a numpy array, neither a scalar

我目前正在努力解决这个问题,任何帮助将不胜感激。如评论中所述,PIL图像需要转换为CV2接受格式,任何人都可以使用下面给出的示例提供解释吗?

import cv2
import numpy as np
from matplotlib import pyplot as plt
from cycler import cycler
from PIL import Image, ImageEnhance

# Loads the image then enhances it
image = Image.open('lineCapture.png')
contrast = ImageEnhance.Contrast(image)

# Reads the enhanced image and converts it to grayscale, creates new file
gray_image = cv2.cvtColor(contrast, cv2.COLOR_BGR2GRAY) //there is a problem here
cv2.imwrite('enhancedGrayscaleLineCapture.png', gray_image)

# Adaptive Gaussian Thresholding
th1 = cv2.adaptiveThreshold(gray_image,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
        cv2.THRESH_BINARY,11,2)
# Otsu's thresholding
ret2,th2 = cv2.threshold(gray_image,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Otsu's thresholding after Gaussian filtering
blur = cv2.GaussianBlur(gray_image,(5,5),0)
ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# writes enhanced and thresholded img
cv2.imwrite('enhancedGrayscaleThresholdLineCapture.png', th2)

2 个答案:

答案 0 :(得分:8)

PIL几乎完全面向对象,因此大多数函数都返回对象。

例如:

>>> image = Image.open('img6.png')
>>> type(image)
<class 'PIL.PngImagePlugin.PngImageFile'>

PIL Image是一个类(因此是大写),因此它返回一个对象。因此,如果图像是一个对象,它可能具有属性,如图像数据,图像的高度/宽度等,以及内置方法,如.show()将显示图像。您可以read the docs for the PIL Image class了解更多信息。

所以你将类传递给期望数组的函数。那里有问题。解决此问题的一种方法是使用image.getdata()将数据读入numpy数组,这是访问PIL中像素值的常用方法。

但是,numpy会使用简单的命令自动将Image转换为数组:np.asarray()

>>> image = Image.open('img6.png')
>>> type(image)
<class 'PIL.PngImagePlugin.PngImageFile'>
>>> image_data = np.asarray(image)
>>> type(image_data)
<class 'numpy.ndarray'>

耶!现在我们从图像中得到一个数组。但重要的是,PIL像大多数其他库一样读取RGB图像,但OpenCV实际上使用BGR通道排序。因此,如果您打算使用OpenCV以依赖于其颜色的方式编写,显示或修改图像,则需要确保交换第一个和最后一个通道。

只留下一个问题......处理对比度调整。来自Contrast模块的ImageEnhance也会返回一个对象:

>>> contrast = ImageEnhance.Contrast(image)
>>> type(contrast)
<class 'PIL.ImageEnhance.Contrast'>

但是这会返回Contrast个对象,而不是Image个对象。实际上你的代码甚至没有修改过图像;您所做的就是创建增强器对象。你必须调用一种方法来实际执行对比度调整(以及你想要它的强度因素)。查看docs for ImageEnhance

  

所有增强类都实现了一个通用接口,包含一个方法:

     

enhance(factor)

     

返回增强的图像。

     

参数: factor - 控制增强的浮点值。因子1.0总是返回原始图像的副本,较低的因子意味着较少的颜色(亮度,对比度等),而较高的值则更多。这个值没有限制。

     

返回类型: Image

现在,方法返回Image,因此我们可以对结果运行np.asarray()。所以最终的管道就像:

  1. 将图片加载到Image
  2. 创建对比度增强对象
  3. 在对比度增强对象上调用enhance(factor),返回值为另一个Image
  4. 获取对比度调整后的图像数据的numpy数组
  5. 从RGB转换为BGR顺序
  6. 通常使用
  7. 输入图片:

    Input image

    >>> pil_image = Image.open('img6.png')
    >>> contrast_enhancer = ImageEnhance.Contrast(pil_image)
    >>> pil_enhanced_image = contrast_enhancer.enhance(2)
    >>> enhanced_image = np.asarray(pil_enhanced_image)
    >>> r, g, b = cv2.split(enhanced_image)
    >>> enhanced_image = cv2.merge([b, g, r])
    >>> cv2.imshow('Enhanced Image', enhanced_image)
    >>> cv2.waitKey()
    

    输出图片:

    Contrast Enhanced Image

答案 1 :(得分:3)

感谢Alexander Reynolds的出色解释。蜥蜴蜥蜴,因为你无法弄清楚代码中的错误,请查看

import cv2
import numpy as np
from matplotlib import pyplot as plt
from cycler import cycler
from PIL import Image, ImageEnhance

# Loads the image then enhances it
image = Image.open('lineCapture.png')
contrast = ImageEnhance.Contrast(image)
img=contrast.enhance(2)
img = np.asarray(img)
r, g, b,a = cv2.split(img)
contrast=cv2.merge([b, g, r])
# Reads the enhanced image and converts it to grayscale, creates new file
gray_image = cv2.cvtColor(contrast, cv2.COLOR_BGR2GRAY) #there is a problem here


# Adaptive Gaussian Thresholding
th1 = cv2.adaptiveThreshold(gray_image,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
        cv2.THRESH_BINARY,11,2)
# Otsu's thresholding
ret2,th2 = cv2.threshold(th1,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Otsu's thresholding after Gaussian filtering
blur = cv2.GaussianBlur(th2,(5,5),0)
ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# writes enhanced and thresholded img
cv2.imwrite('enhancedGrayscaleThresholdLineCapture.png', th3)