gray_image = cv2.cvtColor(contrast, cv2.COLOR_BGR2GRAY)
TypeError: src is not a numpy array, neither a scalar
Je travaille actuellement pour résoudre ce problème, toute aide serait appréciée. Comme mentionné dans les commentaires, l'image PIL doit être convertie au format accepté CV2, quelqu'un peut-il fournir une explication en utilisant l'exemple ci-dessous?
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 est presque complètement orienté objet, donc la plupart des fonctions renvoient des objets.
Par exemple:
>>> image = Image.open('img6.png')
>>> type(image)
<class 'PIL.PngImagePlugin.PngImageFile'>
Le PIL Image
est une classe (d'où la capitale) donc il retourne un objet. Donc, si l'image est un objet, elle a probablement des propriétés, comme les données d'image, la hauteur/largeur de l'image, etc., ainsi que des méthodes intégrées, comme .show()
qui affichera l'image . Vous pouvez lire les documents de la classe PIL Image
pour en savoir plus.
Vous transmettez donc des classes à des fonctions qui attendent des tableaux. Va avoir un problème là-bas. Une façon de résoudre ce problème consiste à lire les données dans un tableau numpy en utilisant image.getdata()
, qui est la manière habituelle d'accéder aux valeurs des pixels dans PIL.
Cependant , numpy convertira automatiquement le Image
en un tableau pour vous avec une simple commande: np.asarray()
.
>>> image = Image.open('img6.png')
>>> type(image)
<class 'PIL.PngImagePlugin.PngImageFile'>
>>> image_data = np.asarray(image)
>>> type(image_data)
<class 'numpy.ndarray'>
Yay! Maintenant, nous avons un tableau de l'image. Mais surtout, PIL lit les images sous forme d'images RVB comme la plupart des autres bibliothèques, mais OpenCV utilise en fait l'ordre des canaux BGR. Vous devrez donc vous assurer d'échanger les premier et dernier canaux si vous souhaitez utiliser OpenCV pour écrire, afficher ou modifier des images d'une manière qui dépend de leur couleur.
Un seul problème à gauche ... concernant le réglage du contraste. Contrast
du module ImageEnhance
renvoie également un objet:
>>> contrast = ImageEnhance.Contrast(image)
>>> type(contrast)
<class 'PIL.ImageEnhance.Contrast'>
Mais cela renvoie un objet Contrast
et non un objet Image
. En fait, votre code n'a même pas modifié l'image; tout ce que vous avez fait est de créer l'objet Enhancer. Vous devez appeler une méthode pour effectuer réellement l'ajustement du contraste (et un facteur de la force que vous souhaitez qu'il soit). Vérifiez les documents pour ImageEnhance :
Toutes les classes d'amélioration implémentent une interface commune, contenant une seule méthode:
enhance(factor)
Renvoie une image améliorée.
Paramètres:
factor
- Une valeur à virgule flottante contrôlant l'amélioration. Le facteur 1.0 renvoie toujours une copie de l'image d'origine, des facteurs plus faibles signifient moins de couleurs (luminosité, contraste, etc.) et des valeurs plus élevées. Il n'y a aucune restriction sur cette valeur.Type de retour:
Image
Maintenant, la méthode this renvoie un Image
, afin que nous puissions exécuter np.asarray()
sur le résultat. Ainsi, le pipeline final serait quelque chose comme:
Image
enhance(factor)
sur l'objet d'amélioration du contraste et la valeur de retour sera une autre classe Image
Image d'entrée:
>>> 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()
Image de sortie:
Merci à Alexander Reynolds pour la grande explication. lizardwizard, puisque vous ne pouvez pas comprendre l'erreur dans votre code, vérifiez ceci
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)