2010-08-26 9 views
3

J'ai une application qui reçoit un pointeur vers des données JPEG d'une API de caméra enveloppée avec ctypes, le convertit en wx.Image, et affiche les images en tant que film.Manipulation de bit d'image en Python

L'une des caractéristiques requises consiste à définir deux des composants d'un pixel égal au troisième. Par exemple, mon pixel au format RVB est (100,200,255), je veux définir les valeurs R et B égales à G, ou (200,200,200). Je dois faire t pour chaque pixel de l'image tout en conservant un framerate décent.

Je peux accéder aux valeurs RVB à partir de mon image wx.Image en appelant le Image.GetData, qui renvoie une chaîne contenant les valeurs de pixel au format suivant: RGBRGBRGB ... J'ai implémenté la fonctionnalité naïvement en itérant par ce RGBRGBRGB chaîne.

Cependant, cette approche naïve est beaucoup trop lent pour atteindre un FPS décent parce que (je pense):

a) J'Itère chaque pixel dans l'image.

b) Je fais trop de copies de données. J'ai considéré la conversion de mes données RVB en numpy, en effectuant l'opération (je suppose que numpy aurait un moyen plus rapide de faire ce genre de chose), puis en convertissant à wx.Image. Malheureusement, je ne peux pas convertir directement les données brutes en données chiffrées, car les données sont au format JPEG et non en tant que bitmap RVB. Donc, je devrais aller à partir de data-> wx.Image-> numpy array-> wx.Image.

J'ai également envisagé d'implémenter mon propre tampon python qui retournera, par exemple, la valeur du pixel G au lieu des valeurs R et B lors de la lecture. Je pense que ce serait la solution idéale, car il ne nécessite aucune copie de données ou des itérations excessives, mais je n'ai aucune idée de comment procéder. Aurai-je besoin d'écrire ce tampon en C? Est-il possible d'implémenter des tampons en python pur et de toujours manipuler la mémoire brute?

Alors, comment pensez-vous que je devrais améliorer mes performances? Dois-je essayer la solution numpy ou buffer, ou y a-t-il une solution plus facile qui me manque?

Je cherche principalement pour des idées/liens vers les documents pertinents ou des exemples, mais si quelqu'un veut écrire un code alors que va bien :)

Merci

Répondre

1

Vous pouvez essayer d'utiliser la Python Imaging Library (PIL) - c'est une bibliothèque pour manipuler des images.

Vous pouvez trouver des informations sur la conversion entre une image wxPython et une image PIL here, ou vous pouvez charger le fichier jpeg directement dans une image PIL.

Une fois que vous avez converti votre image WX en une image PIL Je pense que cela va faire ce que vous voulez (mais je l'ai pas testé):

r, g, b = im.split()    # split the image into separate color planes 
im = Image.merge("RGB", (g, g, g)) # merge them back, using the green plane for each 

convertir ensuite revenir à une image wxPython.

Cela devrait être des ordres de grandeur plus rapides que de le faire en Python, puisque PIL est implémenté en C et optimisé pour le traitement d'image.

1

Si vous avez besoin d'un traitement très rapide des images, je suggère d'écrire GLSL pixel shader et de l'interfacer avec OpenGL et PyGame. Rien ne vaut la vitesse de traitement des pixel shaders, car chaque pixel est traité en parallèle par GPU sur la carte vidéo. Si vous devez tester le code de pixel shaders (qui est écrit avec sous-ensemble de C), il est préférable de le faire avec RenderMonkey - il est IDE décent de développement de shaders!

Bonne chance!