Comment créer une image OpenCV à partir d'une image PIL?
Je veux faire du traitement d'image avec OpenCV (en Python), mais j'ai commencer avec un PIL Image
objet, donc je ne peux pas utiliser le cvLoadImage()
appel, car celle-ci prend un nom de fichier.
Cette recette (adapté de http://opencv.willowgarage.com/wiki/PythonInterface) ne fonctionne pas car cvSetData
se plaint argument 2 of type 'void *'
. Des idées?
from opencv.cv import *
from PIL import Image
pi = Image.open('foo.png') # PIL image
ci = cvCreateImage(pi.size, IPL_DEPTH_8U, 1) # OpenCV image
data = pi.tostring()
cvSetData(ci, data, len(data))
Je pense que le dernier argument de la cvSetData
est mal aussi, mais je ne suis pas sûr de ce qu'il devrait être.
source d'informationauteur Arkady
Vous devez vous connecter pour publier un commentaire.
L'exemple que vous avez essayé de s'adapter est de la nouvelle interface python pour OpenCV 2.0. C'est probablement la source de la confusion entre le préfixe et non le préfixe des noms de fonction (
cv.cvSetData()
contrecv.SetData()
).OpenCV 2.0 est maintenant livré avec deux jeux de liaisons python:
opencv.{cv,highgui,ml}
modulescv.pyd
), qui enveloppe toute la OpenCV fonctionnalités (y compris leshighgui
etml
modules.)La raison derrière le message d'erreur est que le RASADE enveloppe ne gère pas la conversion d'une chaîne python pour un bon vieux C tampon. Cependant, la GORGÉE wrapper est livré avec le
opencv.adaptors
module, conçu pour prendre en charge les conversions denumpy
etPIL
images d'OpenCV.Suivantes (testé) code devrait résoudre votre problème d'origine (conversion à partir de la LIP à OpenCV), à l'aide de l'interface SWIG :
Toutefois, cela ne résout pas le fait que le
cv.cvSetData()
fonction échouera toujours (avec les RASADE wrapper de mise en œuvre).Vous pouvez ensuite utiliser le nouveau style wrapper, qui vous permet d'utiliser la
cv.SetData()
fonction de ce que vous pouvez attendre :Une troisième approche serait de passer votre OpenCV interface python à la ctypes à base de wrapper. Il est livré avec les fonctions de l'utilitaire pour l'explicite de la conversion de données entre par exemple python cordes et C tampons. Un rapide coup d'oeil sur google recherche de code semble indiquer qu'il s'agit d'une méthode de travail.
Concernant le troisième paramètre de la
cvSetData()
la fonction, la taille du buffer d'image, mais l'image de l'étape. L'étape est le nombre d'octets dans une ligne de l'image, qui estpixel_depth * number_of_channels * image_width
. Lepixel_depth
paramètre est la taille, en octets, des données associées à un canal. Dans votre exemple, il serait tout simplement la largeur de l'image (un seul canal, un octet par pixel).C'est vraiment déroutant à la fois gorgée et nouveau binding python. Par exemple, dans le OpenCV 2.0, cmake peut accepter à la fois BUILD_SWIG_PYTHON_SUPPORT et BUILD_NEW_PYTHON_SUPPORT. Mais de toute façon, j'ai un peu compris la plupart des pièges.
Dans le cas d'utilisation "importer cv" (le nouveau binding python), une étape de plus est nécessaire.
La conversion est nécessaire pour les images RVB, car la séquence est différente dans la LIP et IplImage. La même chose s'applique à l'Ipl pour PIL.
Mais si vous utiliser opencv.adaptateurs, il est déjà pris en charge. Vous pouvez regarder dans les détails adaptors.py si vous êtes intéressé.
Je l'ai fait à l'aide de la python2.6 liaisons de OpenCV2.1:
La rotation de l'image et de la réversion de la chaîne est de permuter RVB en BGR, qui est utilisé dans OpenCV l'encodage vidéo. Je suppose que ce serait aussi nécessaire pour toute autre utilisation d'une image converti à partir du DIP à OpenCV.
Je ne suis pas un expert mais j'ai réussi à obtenir un opencv image à partir d'une image de PIL avec ce code: