[PYTHON] Bestimmen Sie die Zahlen in dem mit der Webkamera aufgenommenen Bild

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.

Projizieren Sie das Bild der Webkamera

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

Bilder abrufen und verarbeiten

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

Vorverarbeitung des aufgenommenen Bildes

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.

  1. Webkamerabilder sind farbig, also machen Sie sie zuerst grau.
  2. Reduzieren Sie das Bild auf 28x28
  3. Führen Sie die gleiche Verarbeitung wie für MNIST durch

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

MLP-Einstellungen zur Bestimmung von Zahlen

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.

Anzeige des auszuschneidenden Teils

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.

Ausprobieren

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.

ca65d9ec37ef3523fd80340fc1235bfa.png

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

img.jpg 前処理中の状態

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.

img.jpg前処理中の状態(閾値処理追加後)

d99b548adc6fb7541dbda4e6726280e2.png

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

Bestimmen Sie die Zahlen in dem mit der Webkamera aufgenommenen Bild
[Python] Holen Sie sich die Zahlen im Diagramm mit OCR
Bildanzeige mit dem eingebauten ISIGHT
Erkennen Sie Ordner mit demselben Bild in ImageHash
Konvertieren Sie das Bild in .zip mit Python in PDF
Beurteilung von Primzahlen mit Python
Tweet mit Bild in Python
Testen mit Zufallszahlen in Python
Erkennen Sie Mosaikpunkte im Bild
Versuchen Sie, das Bild mit opencv2 zu verwischen
Ich habe versucht, das Bild mit OpenCV im "Skizzenstil" zu verarbeiten
Ich habe versucht, das Bild mit OpenCV im "Bleistift-Zeichenstil" zu verarbeiten
Verhalten bei der Rückkehr in den with-Block
Zeigen Sie Python 3 im Browser mit MAMP an
Klicken Sie mit der rechten Maustaste auf das Bild → Realisieren Sie "Mit TinyPNG komprimieren"
Ich habe versucht, mit Pillow mit dem Bild zu spielen
Verarbeiten Sie Bilder in Python ganz einfach mit Pillow
Ordnen Sie die Zahlen spiralförmig an
Extrahieren Sie die Farbe des Objekts im Bild mit Mask R-CNN und K-Means Clustering
So zeigen Sie im gesamten Fenster an, wenn Sie das Hintergrundbild mit tkinter einstellen
Ich habe versucht, das Bild mit Python + OpenCV zu "glätten"
Melden Sie sich mit SSH bei einem Remote-Server an
[Python] Holen Sie sich die Dateien mit Python in den Ordner
Schneiden Sie das Bild mit Pythonista auf abgerundete Ecken
Ich habe versucht, das Bild mit Python + OpenCV zu "differenzieren"
Was ist im Docker Python-Image pfeifend?
[Automatisierung] Extrahieren Sie die Tabelle als PDF mit Python
Ich habe versucht, das Bild mit Python + OpenCV zu "binarisieren"
Erstellen Sie ein Bild mit Zeichen mit Python (Japanisch)
[Python] Bestimmen Sie den Typ der Iris mit SVM
Die Geschichte, die zur Installation von Pip passt
Zeigen Sie das Bild nach der Datenerweiterung mit Pytorch an
Das Problem, dass das Bild beim Laden mit PandasTools.LoadSDF nicht in ROMol angezeigt wurde, wurde behoben.
Extrahieren Sie die Tabelle der Bilddateien mit OneDrive & Python
Ändern Sie die Zeitzone in Oracle Database Docker
Ergänzen Sie die Bibliothek in Anakonda mit jedi-vim
Bestimmen Sie den Schwellenwert mithilfe der P-Tile-Methode in Python
Identifizieren Sie den Namen aus dem Blumenbild mit Keras (Tensorfluss)
Crawlen Sie die im Twitter-Tweet enthaltene URL mit Python
Mit Python psycopg2 erhalten Sie Ergebnisse im Diktatformat
Lesen Sie die Linkliste im CSV-Format mit dem Graph-Tool
Zeigen Sie die Zeilennummer des VIM-Editors an (mit Standardeinstellungen).
Schreiben Sie mit OpenCV-Python Zeichen in die Kartenillustration
Versuchen Sie, das Bild in einen separaten Thread zu laden (OpenCV-Python).
Laden Sie das gleichnamige Modul an einer anderen Stelle
Bestimmen Sie, ob im Objekt ein Attribut definiert ist
Visualisieren Sie Zahlenschwankungen auf Websites mit Datadog
POST das Bild mit json und erhalte es mit der Flasche
Teilnahme an der ersten ISUCON mit dem Team "Ranchu" # ISUCON10 Qualifying
Python Open CV hat versucht, das Bild im Text anzuzeigen.
Mische die Bilder in einem beliebigen Verzeichnis mit Python und speichere sie in einem anderen Ordner mit Seriennummern.
Beim Lesen eines Bildes mit SimpleITK tritt ein Problem auf, wenn sich Japanisch im Pfad befindet