liz*_*ard 11 python opencv numpy image-processing python-2.7
gray_image = cv2.cvtColor(contrast, cv2.COLOR_BGR2GRAY)
TypeError: src is not a numpy array, neither a scalar
Run Code Online (Sandbox Code Playgroud)
我目前正在努力解决这个问题,任何帮助将不胜感激.如评论中所述,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)
Run Code Online (Sandbox Code Playgroud)
PIL几乎完全面向对象,因此大多数函数都返回对象.
例如:
>>> image = Image.open('img6.png')
>>> type(image)
<class 'PIL.PngImagePlugin.PngImageFile'>
Run Code Online (Sandbox Code Playgroud)
PIL Image是一个类(因此是大写),因此它返回一个对象.因此,如果图像是一个对象,它可能具有属性,如图像数据,图像的高度/宽度等,以及内置方法,如.show()显示图像.您可以阅读PIL Image类的文档以获取更多信息.
所以你要将类传递给期望数组的函数.那里有问题.解决此问题的一种方法是使用数据将数据读入numpy数组image.getdata(),这是访问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'>
Run Code Online (Sandbox Code Playgroud)
好极了!现在我们从图像中得到一个数组.但重要的是,PIL像大多数其他库一样读取RGB图像,但OpenCV实际上使用BGR通道排序.因此,如果您打算使用OpenCV以依赖于其颜色的方式编写,显示或修改图像,则需要确保交换第一个和最后一个通道.
只留下一个问题......处理对比度调整.Contrast从ImageEnhance模块返回一个对象:
>>> contrast = ImageEnhance.Contrast(image)
>>> type(contrast)
<class 'PIL.ImageEnhance.Contrast'>
Run Code Online (Sandbox Code Playgroud)
但这会返回一个Contrast对象,而不是一个Image对象.实际上你的代码甚至没有修改过图像; 您所做的就是创建增强器对象.你必须调用一种方法来实际执行对比度调整(以及你想要它的强度因素).检查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()
Run Code Online (Sandbox Code Playgroud)
输出图像: