Manipulation des pixels d'image en Python

Résumé de l'exécution du traitement d'image (manipulation des pixels) en Python. Pour l'apprentissage du traitement d'image, les performances et la qualité sont secondaires et la clarté est importante.

environnement

L'environnement est Mac. En termes d'approche académique, le langage est Python et la version 2.7.x.

Environnement d'utilisation

Installation

Python

Mac est livré avec Python depuis le début.

python --version

S'il vous plaît essayez. Si non,

brew install python

Je vais y entrer.

On suppose que l'infusion est incluse. .. ..

installation de pip

Installez pip, un outil de gestion de packages Python, pour faciliter l'installation de la bibliothèque.

easy_install pip

Installation de modules (bibliothèque)

Cette fois, nous utiliserons numpy et Pillow (PIL). numpy comprend des outils pratiques pour les calculs et Pillow comprend des outils liés au traitement d'image.

pip install numpy
pip install pillow

Essayez de manipuler l'image

Pour le moment, je vais charger l'image et l'afficher.

from PIL import Image

im = Image.open("./achan.jpg ")
im.show()

Il est juste affiché, alors faisons-le pivoter et affichons-le.

py01

from PIL import Image

im = Image.open("./achan.jpg ")
im.rotate(30).show()

Je pense qu'il a été tourné de 30 degrés dans le sens antihoraire autour du centre de l'image.

py01

En pratique, c'est bien, mais je ne sais pas ce que ça fait en interne. Donc, ici, je voudrais écrire un programme qui traite et fait pivoter chaque pixel.

Essayez de manipuler les pixels

Maintenant, travaillons avec les pixels individuels.

Essayez de retourner le négatif et le positif

Maintenant, effectuons un traitement d'inversion négatif-positif, qui est un traitement d'opération de pixel typique et simple.

#coding:utf-8
from PIL import Image

#Chargement des images
im = Image.open("./achan.jpg ")

#Convertir en RVB
rgb_im = im.convert('RGB')

#Obtenir la taille de l'image
size = rgb_im.size

#Créer une nouvelle image vide avec la même taille que la taille acquise
im2 = Image.new('RGBA',size)

#loop
#x
for x in range(size[0]):
    #y
    for y in range(size[1]):
        #Obtenez des pixels
        r,g,b = rgb_im.getpixel((x,y))

        #Traitement d'inversion
        r = 255 - r
        g = 255 - g
        b = 255 - b

        #set pixel
        im2.putpixel((x,y),(r,g,b,0))

#show
im2.show()

Il a été retourné à un négatif.

py01

niveaux de gris

L'échelle de gris est grise lorsque r, g et b ont la même valeur. Cependant, il est au cas par cas de déterminer s'il faut faire la même valeur selon une telle règle. Ici, nous allons obtenir la valeur moyenne de r, g et b et utiliser cette valeur (ci-après, seule l'opération de pixel est extraite).

#loop
#x
for x in range(size[0]):
    #y
    for y in range(size[1]):
        #Obtenez des pixels
        r,g,b = rgb_im.getpixel((x,y))

        #Moyenne
        g = (r + g + b)/3

        #set pixel
        im2.putpixel((x,y),(g,g,g,0))

#show
im2.show()

Il est devenu gris pour le moment.

py01

Essayez de tourner

Il existe plusieurs façons de faire pivoter une image, mais la plus primitive consiste à utiliser une matrice de rotation.

Matrice de rotation

La matrice de rotation est exprimée par la formule suivante. Si vous donnez à θ l'angle que vous souhaitez faire pivoter en radian, vous pouvez faire pivoter un siège (x2, y2) de cet angle.

\begin{equation}

\begin{pmatrix}
x_{2} \\
y_{2}
\end{pmatrix}

=

\begin{pmatrix}
\cos \theta & -\sin \theta \\
\sin \theta & \cos \theta
\end{pmatrix}

\begin{pmatrix}
x_{1} \\
y_{2}
\end{pmatrix}


\end{equation}

En Python, en utilisant le module numpy, la matrice de rotation ci-dessus peut être modifiée.

m_matrix = np.matrix([
            [np.cos(rad),-1*np.sin(rad)],
            [np.sin(rad),np.cos(rad)]
        ])

Il est très pratique car il peut être exprimé intuitivement, et la somme et le produit peuvent être obtenus en le décrivant comme une opération normale à quatre règles.

J'utilise matrice ici, mais à moins que vous n'ayez une raison spécifique, il semble préférable d'utiliser array.

Ecrire le code

Maintenant, écrivons un code qui tourne à l'aide d'une matrice de rotation. Dans le code ci-dessous, le coin supérieur gauche est traité comme l'axe de rotation, et non comme le centre de l'image. De plus, comme putpixel, qui ne peut gérer que int, est utilisé, des irrégularités se produisent dans l'image (bien que cette méthode soit utilisée ici par souci de clarté).

#coding:UTF-8
from PIL import Image
import numpy as np

#Chargement des images
im = Image.open("./achan.jpg ")

#Convertir en RVB
rgb_im = im.convert('RGB')

#Obtenir la taille de l'image
size = rgb_im.size

#Créer une nouvelle image vide avec la même taille que la taille acquise
im2 = Image.new('RGBA',size)

#loop
#x
for x in range(size[0]):
	#y
	for y in range(size[1]):

		#Obtenez des pixels
		r,g,b = rgb_im.getpixel((x,y))

		#En traitement

		#30 degrés
		rad = np.pi/6

		#Matrice de rotation
		m_matrix = np.matrix([
			[np.cos(rad),-1*np.sin(rad)],
			[np.sin(rad),np.cos(rad)]
		])

		#Coordonnées applicables (coordonnées d'origine)
		p_matrix = np.matrix([
				[x],
				[y]
			])

		#Fonctionnement de la matrice
		p2_matrix = m_matrix * p_matrix

		#Travaillez après avoir déménagé(Seul int peut être mis, alors convertissez-le en int)
		x2 = int(p2_matrix[0,0])
		y2 = int(p2_matrix[1,0])

		#S'il est dans la taille de l'image
		if 0 < x2 < size[0] and 0 < y2 < size[1]:
			#Spécifiez le RVB d'origine pour les coordonnées après le déplacement
			im2.putpixel((x2,y2),(r,g,b,0))

#show
im2.show()

py01

Essayez de retourner

L'inversion par rapport à l'axe x, l'axe y, l'axe arbitraire, etc. peut également être effectuée avec une matrice. Il s'agit de la première conversion des mathématiques du secondaire. Par exemple, l'inversion de l'axe y est donnée ci-dessous.

Matrice d'inversion (axe y)

\begin{equation}

\begin{pmatrix}
x_{2} \\
y_{2}
\end{pmatrix}

=

\begin{pmatrix}
-1 & 0 \\
0 & 1
\end{pmatrix}

\begin{pmatrix}
x_{1} \\
y_{2}
\end{pmatrix}


\end{equation}

Cette matrice est en Python

#cible de l'axe y
y_matrix = np.matrix([
    [-1,0],
    [0,1]
])

Peut être exprimé comme.

Essayez d'écrire du code

Maintenant écrivons le code. Si vous inversez normalement l'axe y, tous les points se déplaceront dans la direction négative et ne seront pas dessinés. Par conséquent, déplacez-le en parallèle de la largeur (axe des x) de l'image.

#coding:UTF-8
from PIL import Image
import numpy as np

#Chargement des images
im = Image.open("./achan.jpg ")

#Convertir en RVB
rgb_im = im.convert('RGB')

#Obtenir la taille de l'image
size = rgb_im.size

#Créer une nouvelle image vide avec la même taille que la taille acquise
im2 = Image.new('RGBA',size)

#loop
#x
for x in range(size[0]):
    #y
    for y in range(size[1]):

        #Obtenez des pixels
        r,g,b = rgb_im.getpixel((x,y))

        #En traitement

        #cible de l'axe y
        y_matrix = np.matrix([
        	[-1,0],
        	[0,1]
        ])

        #Coordonnées applicables (coordonnées d'origine)
        p_matrix = np.matrix([
                [x],
                [y]
            ])

        #Fonctionnement de la matrice
        p2_matrix = y_matrix * p_matrix

        #Travaillez après avoir déménagé(Seul int peut être mis, alors convertissez-le en int)
        x2 = int(p2_matrix[0,0]) + size[0] #Mouvement parallèle de la coordonnée x par la taille horizontale de l'addition
        y2 = int(p2_matrix[1,0])

        #S'il est dans la taille de l'image
        if 0 < x2 < size[0] and 0 < y2 < size[1]:
            #Spécifiez le RVB d'origine pour les coordonnées après le déplacement
            im2.putpixel((x2,y2),(r,g,b,0))

#show
im2.show()

py01

C'était inversé. Inversion dite gauche-droite. On a l'impression que c'est un pixel supplémentaire. .. .. Je m'en fiche ici.

Traitement de proximité

Comme pour le calcul matriciel, nous allons essayer le traitement de voisinage, qui est un traitement essentiel dans le traitement d'image. Le traitement de proximité est utile pour le «traitement de flou» et «l'extraction de contours».

Brouiller

Ici, nous allons essayer un "processus de flou" relativement simple. Il existe différents algorithmes, mais ici nous allons essayer la méthode la plus simple pour obtenir la valeur moyenne du voisinage de 8 et la définir.

Huit quartiers sont huit zones qui entourent les coordonnées de référence.

py01

Obtenez les valeurs r, g, b de chacune de ses coordonnées et faites leur moyenne.

Une mise en garde est que x-1 n'existe pas ou que x + 1 s'étend au-delà des coordonnées des bords de l'image, de sorte qu'un traitement est nécessaire. Maintenant écrivons le code.

#coding:utf-8
from PIL import Image

#Chargement des images
im = Image.open("./achan.jpg ")

#Convertir en RVB
rgb_im = im.convert('RGB')

#Obtenir la taille de l'image
size = rgb_im.size

#Créer une nouvelle image vide avec la même taille que la taille acquise
im2 = Image.new('RGBA',size)

#loop
#x
for x in range(size[0]):
    #y
    for y in range(size[1]):

        #Obtenez des pixels des coordonnées de la cible
        r0,g0,b0 = rgb_im.getpixel((x,y))

        #Initialisation (pour le moment, définissez les valeurs de coordonnées actuelles sur toutes les valeurs voisines)
        r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r0;
        g1 = g2 = g3 = g4 = g5 = g6 = g7 = g8 = g0;
        b1 = b2 = b3 = b4 = b5 = b6 = b7 = b8 = b0;

        #Obtenez la valeur des coordonnées du quartier

        #1
        if x-1 > 0 and y+1 < size[1]:
        	r1,g1,b1 = rgb_im.getpixel((x-1,y+1))

        #2
        if y+1 < size[1]:
        	r2,g2,b2 = rgb_im.getpixel((x,y+1))

        #3
        if x+1 < size[0] and y+1 < size[1]:
        	r3,g3,b3 = rgb_im.getpixel((x+1,y+1))

        #4
        if x-1 > 0:
        	r4,g4,b4 = rgb_im.getpixel((x-1,y))

        #5
        if x+1 < size[0]:
        	r5,g5,b5 = rgb_im.getpixel((x+1,y))

        #6
        if x-1 > 0 and y-1 > 0:
        	r6,g6,b6 = rgb_im.getpixel((x-1,y-1))

        #7
        if y-1 > 0:
        	r7,g7,b7 = rgb_im.getpixel((x,y-1))

        #8
        if x+1 < size[0] and y-1 > 0:
        	r8,g8,b8 = rgb_im.getpixel((x+1,y-1))


        #Averize RVB à proximité
        r = (r0 + r1 + r2 + r3 + r4 + r5 + r6 + r7 + r8)/9
        g = (g0 + g1 + g2 + g3 + g4 + g5 + g6 + g7 + g8)/9
        b = (b0 + b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8)/9

        #dessin
        im2.putpixel((x,y),(r,g,b,0))

#show
im2.show()

C'est un peu déroutant, mais c'est flou. Divers flous sont possibles en élargissant davantage le voisinage et en concevant l'algorithme.

py01

C'est encore un long chemin pour le rendre pratiquement utilisable, comme la correction des pixels, mais pour le moment, le contenu de base est à la hauteur.

Recommended Posts

Manipulation des pixels d'image en Python
Débarrassez-vous des images DICOM en Python
Manipulation de chaîne en python
Manipulation de date en Python
Se débarrasser des images DICOM avec Python Partie 2
Encodage base64 des images en Python 3
Jugement d'équivalence d'objet en Python
Accélérer le chargement des images Python
Manipulation de la date des chaînes en Python
Implémentation du tri rapide en Python
[Python] Manipulation des éléments dans la liste (tableau) [Ajouter / Supprimer]
Reconnaissance des nombres dans les images avec Python
Résumé de base des opérations de données dans Python Pandas - Deuxième moitié: agrégation de données
Manipulation de chemin de fichier / dossier en Python
Comment collecter des images en Python
Diviser timedelta dans la série Python 2.7
Échappement automatique des paramètres MySQL en python
Gestion des fichiers JSON en Python
Implémentation du jeu de vie en Python
Affichage de la forme d'onde audio en Python
Extraire du texte d'images avec Python
La loi des nombres en python
Implémentation du tri original en Python
Brouillage réversible d'entiers en Python
Travailler avec des images DICOM en Python
Conversion de la chaîne <-> date (date, datetime) en Python
Vérifiez le comportement du destroyer en Python
Pratique d'utilisation de ceci en Python (mauvais)
Théorie générale de la relativité en Python: Introduction
Appliquer diverses formes de mosaïques aux images (Python, OpenCV)
Arborescence de sortie des fichiers en Python
Afficher une liste d'alphabets en Python 3
Comparaison des modules de conversion japonais en Python3
Résumé de diverses instructions for en Python
Le résultat de l'installation de python sur Anaconda
Modèles Gang of Four (GoF) en Python
Télécharger des images à partir de la liste d'URL en Python
Principes de base pour exécuter NoxPlayer en Python
Remplacement en bloc des chaînes dans les tableaux Python
Projet Euler # 16 "Somme des pouvoirs" en Python
Traffic Safety-kun: Reconnaissance des panneaux de signalisation en Python
Résumé des méthodes intégrées, etc. de la liste Python
Utilisation d'opérateurs non logiques de ou en python
À la recherche du FizzBuzz le plus rapide en Python
Exemple pratique d'architecture hexagonale en Python
Projet Euler # 17 "Nombre de caractères" en Python
Equation de mouvement à double pendule en python
Lire des caractères dans des images avec Python OCR
Statut de chaque système de traitement Python en 2020
Projet Euler # 1 "Multiple de 3 et 5" en Python
Quadtree en Python --2
CURL en Python
Métaprogrammation avec Python
Python 3.3 avec Anaconda
Géocodage en python
SendKeys en Python
Manipulation de chaînes de syntaxe Python
Méta-analyse en Python
Unittest en Python