Nach einem Beispiel mit MNIST in der Einführung in Deep Learning gibt es möglicherweise Leute, die etwas Angewandtes tun möchten, sich aber kein gutes Beispiel vorstellen können.
Dieses Mal möchte ich solchen Menschen helfen, und ich werde versuchen, etwas zu machen, das die auf der Webkamera reflektierten Zahlen unterscheidet.
Lassen Sie uns zunächst das Bild von der Webkamera anzeigen. Es scheint einfach mit OpenCV zu tun.
Dieses Mal verwende ich die "HD Webcam C270" von Logitech.
#!/usr/bin/python
#coding: utf-8
import cv2
def main():
#Bildanzeige der Webkamera
capture = cv2.VideoCapture(0)
if capture.isOpened() is False:
raise("IO Error")
while True:
#Webkamera-Videoaufnahme
ret, image = capture.read()
if ret == False:
continue
#Bildanzeige der Webkamera
cv2.imshow("Capture", image)
k = cv2.waitKey(10)
#Schließen Sie den Aufnahmebildschirm mit der ESC-Taste
if k == 27:
break
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
Wenn Sie gefragt werden, ob Ihre Sicherheitssoftware zur Laufzeit den Zugriff auf Ihre Webcam zulassen soll, lassen Sie dies zu.
Referenzartikel: Venus ☆ Channel: Holen Sie sich Webkamerabilder mit der Python-Version OpenCV
Anstatt ständig Zahlen zu unterscheiden, möchte ich das Bild zu diesem Zeitpunkt abrufen und verarbeiten, wenn ich eine beliebige Taste drücke. Am Ende möchte ich es an den Nummernunterscheidungsprozess übergeben, aber vorerst werde ich nur eine Nachricht zur Funktionsprüfung anzeigen.
Bitte lesen Sie im Referenzartikel nach, welcher Schlüssel welcher Nummer zugeordnet ist.
#!/usr/bin/python
#coding: utf-8
import cv2
def main():
#Bildanzeige der Webkamera
capture = cv2.VideoCapture(0)
if capture.isOpened() is False:
raise("IO Error")
while True:
#Webkamera-Videoaufnahme
ret, image = capture.read()
if ret == False:
continue
#Bildanzeige der Webkamera
cv2.imshow("Capture", image)
k = cv2.waitKey(10)
#Verarbeitung mit E-Taste ausführen
if k == 101:
print("Verarbeitung ausführen")
#Schließen Sie den Aufnahmebildschirm mit der ESC-Taste
if k == 27:
break
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
Referenzartikel: Highgui-Schlüsselcodeliste - Verschwendungshinweis
Ich dachte, es wäre groß, das gesamte aufgenommene Bild als Eingabe zu übergeben, also möchte ich den 100x100-Teil in der Mitte ausschneiden.
Überprüfen Sie zunächst die Größe des von der Webkamera aufgenommenen Bildes.
if k == 101:
print(image.shape)
Wir werden den Verarbeitungsteil des E-Schlüssels ändern. In OpenCV ist das Bild ein Numpy-Array, sodass Sie hogehoge.shape verwenden können, um die Länge des Elements zu ermitteln. In diesem Beispiel wird (480, 640, 3) ausgegeben, sodass Sie sehen können, dass die Größe 480 (vertikal) x 640 (horizontal) beträgt.
Nachdem wir die Größe kennen, ist der Prozess des Ausschneidens der Mitte 100 x 100 wie folgt. Speichern wir das Bild und prüfen, ob der Zuschnitt funktioniert.
if k == 101:
img = image[190:290,270:370]
cv2.imwrite("img.jpg ",img)
Jetzt müssen Sie nur noch dieses zugeschnittene Bild mit demselben Eingabeformat wie für MNIST abgleichen. Insbesondere ist die Verarbeitung wie folgt.
Kombinieren Sie es früher mit dem Ausschnitt im Mittelteil und setzen Sie es in der Vorverarbeitungsfunktion zusammen.
import numpy as np
def preprocessing(img):
#Ausschnitt in der Mitte
img = img[190:290,270:370]
#Umstellung auf Graustufen
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#Bild auf 28x28 reduzieren
img = cv2.resize(img, (28, 28))
#Führen Sie im Folgenden die gleiche Verarbeitung wie beim Lernen durch
img = 255 - img
img = img.astype(np.float32)
img /= 255
img = np.array(img).reshape(1,784)
return img
Für dieses Lesen von Zahlen werde ich das einfache MLP verwenden, das auch in der Einführung in Chainer verwendet wird.
from chainer import Chain, serializers
import chainer.functions as F
import chainer.links as L
#Mehrschichtige Perceptron-Modelleinstellungen
class MyMLP(Chain):
#Eingabe 784, Zwischenschicht 500, Ausgabe 10 Dimensionen
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),
)
#Neuronale Netzstruktur
def __call__(self, x):
h1 = F.relu(self.l1(x))
h2 = F.relu(self.l2(h1))
y = self.l3(h2)
return y
Da die Anzahl mehrmals ermittelt wird, laden wir zuerst das trainierte Modell (in diesem Beispiel my.model2).
- Hinzugefügt am 10. Juli 2017 Dieses Mal verwende ich das oben definierte Ergebnis (my.model2) des Trainings-MLP unter Verwendung von MNIST-Daten. Wenn der Leser die von ihm selbst erstellten trainierten Daten verwendet, ist es problemlos möglich, den Inhalt der Klasse My MLP auf den gleichen Wert umzuschreiben, wie er für das Training verwendet wurde.
Wenn Sie dann die E-Taste drücken, fügen Sie einen Prozess hinzu, um die Nummer mithilfe des trainierten Modells zu bestimmen und das Ergebnis anzuzeigen.
def main():
#Geladenes trainiertes Modell laden
net = MyMLP()###Zusätzlicher Teil###
serializers.load_npz('my.model2', net)###Zusätzlicher Teil###
#Bildanzeige der Webkamera
capture = cv2.VideoCapture(0)
if capture.isOpened() is False:
raise("IO Error")
while True:
#Webkamera-Videoaufnahme
ret, image = capture.read()
if ret == False:
continue
#Bildanzeige der Webkamera
cv2.imshow("Capture", image)
k = cv2.waitKey(10)
#Verarbeitung mit E-Taste ausführen
if k == 101:
img = preprocessing(image)
num = net(img)###Zusätzlicher Teil###
print(num.data)###Zusätzlicher Teil###
print(np.argmax(num.data))###Zusätzlicher Teil###
#Schließen Sie den Aufnahmebildschirm mit der ESC-Taste
if k == 27:
break
cv2.destroyAllWindows()
Sie sollten jetzt alles haben, was Sie brauchen.
Es gibt kein Problem bei der Verarbeitung, aber es ist praktisch zu wissen, wo sich der Ausschnitt beim Bedienen der Webkamera befindet. Daher wird der Teil, der im Bild der Webkamera ausgeschnitten werden soll, im roten Rahmen angezeigt.
Videoanzeigeteil der Webkamera von main ()
cv2.imshow("Capture", image)
Hier
cv2.rectangle(image,(270,190),(370,290),(0,0,255),3)
cv2.imshow("Capture", image)
Mach das einfach.
Wenn Sie es ausführen, wird auf der Webkamera ein roter Rahmen in der Bildmitte angezeigt. Geben Sie also die Nummer in den Rahmen ein und drücken Sie die E-Taste.
Ich denke jedoch nicht, dass es als 2 beurteilt wird!
Betrachten Sie, was während der Vorverarbeitung mit dem Bild passiert.
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)###Zustand während der Vorverarbeitung###
img /= 255
img = np.array(img).reshape(1,784)
return img
前処理中の状態
Es scheint, dass die Extraktion des Zahlenteils aufgrund des dunklen Hintergrunds nicht gut verläuft.
Versuchen Sie, einen Schwellenwert festzulegen und nur den dunkelschwarzen Teil zu extrahieren.
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)###Verarbeitung nach Schwellenwert hinzugefügt###
img = 255 - img
img = img.astype(np.float32)
cv2.imwrite("img.jpg ",img)
img /= 255
img = np.array(img).reshape(1,784)
return img
Referenz [Bildschwellenwertverarbeitung - OpenCV-Python-Tutorials 1-Dokumentation](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_thresholding/py_thresholding. html)
Durch Hinzufügen der Schwellenwertverarbeitung kann der numerische Teil extrahiert und gut beurteilt werden.
前処理中の状態(閾値処理追加後)
Ich schrieb andere Zahlen und probierte sie aus, aber einige waren schwer zu lesen, ohne die Position und Größe anzupassen. Es kann interessant sein, darüber nachzudenken, wie wir es im nächsten Schritt besser machen können.
Ich denke auch, dass der Spielbereich durch die Verknüpfung mit einer Webkamera erweitert wird, und ich hoffe, dass Sie die Möglichkeit haben, etwas auszuprobieren.
Schließlich werde ich den gesamten Code von dem veröffentlichen, was ich dieses Mal gemacht habe.
#!/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
#Mehrschichtige Perceptron-Modelleinstellungen
class MyMLP(Chain):
#Eingabe 784, Zwischenschicht 500, Ausgabe 10 Dimensionen
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),
)
#Neuronale Netzstruktur
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():
#Geladenes trainiertes Modell laden
net = MyMLP()
serializers.load_npz('my.model2', net)
#Bildanzeige der Webkamera
capture = cv2.VideoCapture(0)
if capture.isOpened() is False:
raise("IO Error")
while True:
#Webkamera-Videoaufnahme
ret, image = capture.read()
if ret == False:
continue
#Bildanzeige der Webkamera
cv2.rectangle(image,(270,190),(370,290),(0,0,255),3)
cv2.imshow("Capture", image)
k = cv2.waitKey(10)
#Verarbeitung mit E-Taste ausführen
if k == 101:
img = preprocessing(image)
num = net(img)
#cv2.imwrite("img.jpg ",img)
print(num.data)
print(np.argmax(num.data))
#Schließen Sie den Aufnahmebildschirm mit der ESC-Taste
if k == 27:
break
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
Recommended Posts