Après avoir fait un exemple en utilisant MNIST dans l'introduction à l'apprentissage en profondeur, il peut y avoir des gens qui veulent faire quelque chose d'application mais ne peuvent pas penser à un bon exemple.
Cette fois, je voudrais aider ces personnes, et je vais essayer de faire quelque chose qui distingue les chiffres reflétés sur la caméra Web.
Commençons par afficher l'image de la caméra Web. Cela semble facile à faire avec OpenCV.
Cette fois, j'utilise la "HD Webcam C270" de Logitech.
#!/usr/bin/python
#coding: utf-8
import cv2
def main():
#Affichage de l'image de la caméra Web
capture = cv2.VideoCapture(0)
if capture.isOpened() is False:
raise("IO Error")
while True:
#Capture vidéo de la caméra Web
ret, image = capture.read()
if ret == False:
continue
#Affichage de l'image de la caméra Web
cv2.imshow("Capture", image)
k = cv2.waitKey(10)
#Fermez l'écran de capture avec la touche ESC
if k == 27:
break
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
Lorsqu'on vous demande si vous souhaitez que votre logiciel de sécurité autorise l'accès à votre webcam au moment de l'exécution, autorisez-le.
Article de référence: Chaîne Venus ☆: Obtenez des images de la caméra Web avec OpenCV version Python
Plutôt que de discriminer constamment les nombres, je veux obtenir l'image à ce moment-là et la traiter lorsque j'appuie sur n'importe quelle touche. En fin de compte, je veux le passer au processus de discrimination des nombres, mais pour le moment, je vais simplement afficher un message pour vérifier le fonctionnement.
Veuillez vous référer à l'article de référence pour quelle clé est attribuée à quel numéro.
#!/usr/bin/python
#coding: utf-8
import cv2
def main():
#Affichage de l'image de la caméra Web
capture = cv2.VideoCapture(0)
if capture.isOpened() is False:
raise("IO Error")
while True:
#Capture vidéo de la caméra Web
ret, image = capture.read()
if ret == False:
continue
#Affichage de l'image de la caméra Web
cv2.imshow("Capture", image)
k = cv2.waitKey(10)
#Exécuter le traitement avec la touche E
if k == 101:
print("Exécuter le traitement")
#Fermez l'écran de capture avec la touche ESC
if k == 27:
break
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
Article de référence: Liste des codes clés Highgui --Wasting Note
Je pensais que ce serait important de transmettre toute l'image acquise en entrée, alors j'aimerais découper la partie 100x100 au centre.
Vérifiez d'abord la taille de l'image acquise par la webcam.
if k == 101:
print(image.shape)
Nous allons changer la partie traitement de la touche E. Dans OpenCV, l'image est un tableau Numpy, vous pouvez donc utiliser hogehoge.shape pour connaître la longueur de l'élément. Dans cet exemple, (480, 640, 3) est sorti, vous pouvez donc voir que la taille est de 480 (vertical) x 640 (horizontal).
Maintenant que nous connaissons la taille, le processus de découpe du centre 100 x 100 est le suivant. Sauvegardons l'image et voyons si le recadrage fonctionne.
if k == 101:
img = image[190:290,270:370]
cv2.imwrite("img.jpg ",img)
Il ne vous reste plus qu'à faire correspondre cette image recadrée au même format d'entrée que pour MNIST. Plus précisément, le traitement est le suivant.
Combinez-le avec la découpe dans la partie centrale plus tôt et assemblez-le dans la fonction de prétraitement.
import numpy as np
def preprocessing(img):
#Découpe au centre
img = img[190:290,270:370]
#Conversion en échelle de gris
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#Réduire l'image à 28 x 28
img = cv2.resize(img, (28, 28))
#Ci-dessous, effectuez le même traitement que lors de l'apprentissage
img = 255 - img
img = img.astype(np.float32)
img /= 255
img = np.array(img).reshape(1,784)
return img
Pour cette lecture des nombres, j'utiliserai le simple MLP qui est également utilisé dans l'introduction au chainer.
from chainer import Chain, serializers
import chainer.functions as F
import chainer.links as L
#Paramètres du modèle Perceptron multicouche
class MyMLP(Chain):
#Entrée 784, couche intermédiaire 500, sortie 10 dimensions
def __init__(self, n_in=784, n_units=500, n_out=10):
super(MyMLP, self).__init__(
l1=L.Linear(n_in, n_units),
l2=L.Linear(n_units, n_units),
l3=L.Linear(n_units, n_out),
)
#Structure du réseau neuronal
def __call__(self, x):
h1 = F.relu(self.l1(x))
h2 = F.relu(self.l2(h1))
y = self.l3(h2)
return y
Puisque nous déterminerons le nombre plusieurs fois, nous chargerons d'abord le modèle entraîné (my.model2 dans cet exemple).
- Ajouté le 10 juillet 2017 Cette fois, j'utilise le résultat (my.model2) de l'entraînement MLP défini ci-dessus en utilisant les données MNIST. Si le lecteur utilise les données entraînées préparées par lui-même, il sera facile de réécrire le contenu de la classe My MLP sur le même que celui utilisé pour la formation.
Ensuite, lorsque vous appuyez sur la touche E, ajoutons un processus pour déterminer le nombre à l'aide du modèle entraîné et afficher le résultat.
def main():
#Chargement du modèle entraîné
net = MyMLP()###Partie supplémentaire###
serializers.load_npz('my.model2', net)###Partie supplémentaire###
#Affichage de l'image de la caméra Web
capture = cv2.VideoCapture(0)
if capture.isOpened() is False:
raise("IO Error")
while True:
#Capture vidéo de la caméra Web
ret, image = capture.read()
if ret == False:
continue
#Affichage de l'image de la caméra Web
cv2.imshow("Capture", image)
k = cv2.waitKey(10)
#Exécuter le traitement avec la touche E
if k == 101:
img = preprocessing(image)
num = net(img)###Partie supplémentaire###
print(num.data)###Partie supplémentaire###
print(np.argmax(num.data))###Partie supplémentaire###
#Fermez l'écran de capture avec la touche ESC
if k == 27:
break
cv2.destroyAllWindows()
Vous devriez maintenant avoir tout ce dont vous avez besoin.
Il n'y a pas de problème de traitement, mais il est pratique de savoir où se trouve la partie découpée lors de l'utilisation de la webcam. Par conséquent, la partie à découper dans l'image de la webcam est indiquée dans le cadre rouge.
Affichage vidéo d'une partie de la caméra Web de main ()
cv2.imshow("Capture", image)
Ici
cv2.rectangle(image,(270,190),(370,290),(0,0,255),3)
cv2.imshow("Capture", image)
Fais juste ça.
Lorsque vous l'exécutez, un cadre rouge apparaît au centre de l'image sur la caméra Web comme celui-ci, alors mettons le numéro dans le cadre et appuyez sur la touche E.
Cependant, je ne pense pas qu'il sera jugé comme 2!
En regardant ce qui arrive à l'image pendant le prétraitement,
def preprocessing(img):
img = img[190:290,270:370]
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.GaussianBlur(img, (3, 3), 0)
img = cv2.resize(img, (28, 28))
img = 255 - img
img = img.astype(np.float32)
cv2.imwrite("img.jpg ",img)###État pendant le prétraitement###
img /= 255
img = np.array(img).reshape(1,784)
return img
前処理中の状態
Il semble que l'extraction de la partie numérique ne se passe pas bien en raison du fond sombre.
Essayez de définir un seuil et d'extraire uniquement la partie noire foncée.
def preprocessing(img):
img = img[190:290,270:370]
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.GaussianBlur(img, (3, 3), 0)
img = cv2.resize(img, (28, 28))
res, img = cv2.threshold(img, 70 , 255, cv2.THRESH_BINARY)###Traitement ajouté par seuil###
img = 255 - img
img = img.astype(np.float32)
cv2.imwrite("img.jpg ",img)
img /= 255
img = np.array(img).reshape(1,784)
return img
Référence [Traitement des seuils d'image - documentation OpenCV-Python Tutorials 1](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_thresholding/py_thresholding. html)
En ajoutant un traitement de seuil, la partie numérique peut être extraite et bien jugée.
前処理中の状態(閾値処理追加後)
J'ai écrit d'autres nombres et les ai essayés, mais certains d'entre eux étaient difficiles à lire sans ajuster la position et la taille. Il peut être intéressant de réfléchir à la manière dont nous pouvons faire mieux à l'étape suivante.
De plus, je pense que la gamme de jeu sera élargie en se connectant à une caméra Web, j'espère donc que cela vous donnera l'occasion d'essayer quelque chose.
Enfin, je posterai l'intégralité du code de ce que j'ai réalisé cette fois.
#!/usr/bin/python
#coding: utf-8
import cv2
import numpy as np
from chainer import Chain, serializers
import chainer.functions as F
import chainer.links as L
#Paramètres du modèle Perceptron multicouche
class MyMLP(Chain):
#Entrée 784, couche intermédiaire 500, sortie 10 dimensions
def __init__(self, n_in=784, n_units=500, n_out=10):
super(MyMLP, self).__init__(
l1=L.Linear(n_in, n_units),
l2=L.Linear(n_units, n_units),
l3=L.Linear(n_units, n_out),
)
#Structure du réseau neuronal
def __call__(self, x):
h1 = F.relu(self.l1(x))
h2 = F.relu(self.l2(h1))
y = self.l3(h2)
return y
def preprocessing(img):
img = img[190:290,270:370]
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.GaussianBlur(img, (3, 3), 0)
img = cv2.resize(img, (28, 28))
res, img = cv2.threshold(img, 70 , 255, cv2.THRESH_BINARY)
img = 255 - img
img = img.astype(np.float32)
cv2.imwrite("img.jpg ",img)
img /= 255
img = np.array(img).reshape(1,784)
return img
def main():
#Chargement du modèle entraîné
net = MyMLP()
serializers.load_npz('my.model2', net)
#Affichage de l'image de la caméra Web
capture = cv2.VideoCapture(0)
if capture.isOpened() is False:
raise("IO Error")
while True:
#Capture vidéo de la caméra Web
ret, image = capture.read()
if ret == False:
continue
#Affichage de l'image de la caméra Web
cv2.rectangle(image,(270,190),(370,290),(0,0,255),3)
cv2.imshow("Capture", image)
k = cv2.waitKey(10)
#Exécuter le traitement avec la touche E
if k == 101:
img = preprocessing(image)
num = net(img)
#cv2.imwrite("img.jpg ",img)
print(num.data)
print(np.argmax(num.data))
#Fermez l'écran de capture avec la touche ESC
if k == 27:
break
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
Recommended Posts