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)
答案 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()
。所以最终的管道就像:
Image
类enhance(factor)
,返回值为另一个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()
输出图片:
答案 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)