类型错误:src 不是 numpy 数组,也不是标量

2024-01-30

    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)

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

例如:

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

The PIL Image是一个类(因此是大写),因此它返回一个对象。因此,如果图像是一个对象,它可能具有属性,例如图像数据、图像的高度/宽度等,以及内置方法,例如.show()这将显示图像。你可以阅读 PIL 文档Image class http://pillow.readthedocs.io/en/3.1.x/reference/Image.html了解更多。

因此,您将类传递给需要数组的函数。那里会有问题。解决此问题的一种方法是将数据读入 numpy 数组,使用image.getdata() http://pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.getdata,这是在 PIL 中访问像素值的常用方法。

However, 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目的。事实上,您的代码甚至没有修改图像;您所做的就是创建增强器对象。您必须调用一个方法来实际执行对比度调整(以及您希望其强度的一个因素)。检查ImageEnhance 文档 http://pillow.readthedocs.io/en/3.1.x/reference/ImageEnhance.html:

所有增强类都实现一个公共接口,包含一个方法:

enhance(factor)

返回增强图像。

参数: factor– 控制增强的浮点值。因子 1.0 始终返回原始图像的副本,较低的因子意味着较少的颜色(亮度、对比度等),而较高的值意味着更多。对此值没有任何限制。

返回类型: Image

Now, this方法返回一个Image,所以我们可以运行np.asarray()关于结果。所以最终的管道将是这样的:

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

输入图像:

>>> 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()

输出图像:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

类型错误:src 不是 numpy 数组,也不是标量 的相关文章

随机推荐