[PYTHON] Vorschau der QR-Code-Kamera

Es wurde bestätigt, dass dieser Artikel in den folgenden Umgebungen funktioniert.

Ausführung
NAOqi 2.5.5.5
Choregraphe 2.5.5.5

Lassen Sie Pepper den QR-Code reibungslos lesen

Pepper verfügt über einen Mechanismus, mit dem der QR-Code leicht erkannt werden kann. Wenn der QR-Code erkannt wird, wird das Ereignis "BarcodeReader / BarcodeDetected" ausgelöst und das erkannte Ergebnis kann verwendet werden.

fig1.png Wählen Sie ein Speicherereignis aus und verbinden Sie es mit der Box, die Sie empfangen möchten

Die QR-Code-Erkennung ist einfach zu implementieren, aber Benutzer sind besorgt, ob sie sie gut halten, da sie nicht in Echtzeit sehen können, welchen QR-Code sie Peppers Augen vorhalten. Es sollte einfacher zu verwenden sein, wenn Sie das Bild der Kamera auf dem Display anzeigen und in Echtzeit überprüfen können, wie das Bild auf der Pfefferseite angezeigt wird. (Diese Methode wird häufig für Robo-Apps verwendet, die von Softbank Robotics erstellt wurden.) Im Gegensatz zur QR-Code-Erkennung ist die Kameravorschau jedoch nicht einfach zu erreichen. Ryutaro Murayama von Softbank Robotics, Satoshi Tanizawa, Kazuhiko Nishimura, "Pfefferprogrammierung von der Grundoperation bis zur Anwendungsplanung und -produktion", ich habe das relevante Teil extrahiert und ein vereinfachtes Beispiel erstellt, daher möchte ich den Mechanismus erläutern.

Beispielprogramm

Bitte laden Sie das Beispielprogramm von GitHub herunter.  https://github.com/Atelier-Akihabara/pepper-qrpreview-example

Wenn Sie das Beispiel ausführen, wird Folgendes angezeigt. fig2.png

--Wenn der QR-Code erkannt wird, wird die App geschlossen.

Programmstruktur

Das Programm hat den folgenden Ablauf.

1. Pfefferseite

a. Um die Anzeige zu verwenden, verwenden Sie [App anzeigen], um HTML anzuzeigen. b. Greifen Sie auf die Kamera von Pepper zu. c. Holen Sie sich die Abonnenten-ID, um die Daten zu empfangen. d. Übergeben Sie die empfangene Teilnehmer-ID über ALMemory an die Anzeigeseite.

2. Anzeigeseite

Erstellen Sie einen Handler, um die von der Pepper-Seite gesendete Abonnenten-ID zu empfangen. b. Empfangen Sie die Kamerabilddaten mit der vom erstellten Handler empfangenen Teilnehmer-ID. c. Zeichnen Sie die empfangenen Kamerabilddaten mit Canvas. Führen Sie d. B. C. so oft wie nötig aus.

Pfefferseite

Wir werden den Prozess von der Pfefferseite aus verfolgen. Auf der Pfefferseite geht es darum, die für die Bildaufnahme erforderliche Teilnehmer-ID an die Anzeigeseite zu übergeben.

1-a. Um die Anzeige zu verwenden, verwenden Sie [App anzeigen], um den folgenden HTML-Code (index.html) anzuzeigen.

index.html


<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="initial-scale = 1, minimum-scale = 1, maximum-scale = 1" />
    <link rel="stylesheet" type="text/css" href="main.css">
    <script src="/libs/qimessaging/2/qimessaging.js"></script>
    <script src="scripts/jquery-2.2.2.min.js"></script>
    <script src="scripts/adjust23.js"></script>
    <script src="scripts/main.js"></script>
      </head>
  <body onLoad="startSession();">
    <div class="container">
        <div id="camera" class="panel inactive">
            <div class="canvas-container">
                <div class="canvas-background">
                    <canvas id="canvas" width="80" height="60"></canvas>
                </div>
            </div>
        </div>
    </div>
    <div class="abort-container inactive" id="common">
        <div class="abort-button" id="abort">Suspension</div>
    </div>
  </body>
</html>

Was Sie hier beachten sollten, ist "<canvas id =" canvas "width =" 80 "height =" 60 "> </ canvas>". In diesem Bereich wird ein Kamerabild gezeichnet. <script src =" scripts / main.js "> </ script> enthält den nachfolgenden Zeichenvorgang. startSession () ist die Startfunktion des Zeichenprozesses. Der Punkt ist, dass Sie eine Box (Leinwand) benötigen, um es anzuzeigen.

1-b, c. Siehe [root / QR-Vorschau / Kamera abonnieren].

python


self.subscriberId = self.videoDevice.subscribeCamera("QRPreview",
                    0, # TopCamera
                    7, # AL:kQQQVGA
                    0, # AL::kYuvColorSpace
                    fps)

Aufruf von ALVideoDevice :: subscribeCamera, umsubscriberId zu erhalten. Die Argumente sind in der folgenden Reihenfolge angeordnet:

Name Inhalt
Name Name
CameraIndex Kameraindex (0 oder Stirnkamera)
Resolution Konstante (konstante AL), die die Auflösung der Kamera angibt:7 entsprechend kQQQVGA, QQQVGA ist 80x60 Pixel)
ColorSpace Von der Kamera erhaltenes Bildformat (Konstante AL::0 entspricht kYuvColorSpace, YuvColorSpace ist nur das Helligkeitssignal des YUV-Farbraums.
Fps Erforderliche Bildrate

Im Folgenden finden Sie die Konstanten, die in verschiedenen Parametern festgelegt wurden.  http://doc.aldebaran.com/2-5/family/pepper_technical/video_pep.html

Der Rückgabewert von "subscribeCamera" ist in "self.subscriberId". Sie können jetzt auf Ihre Kameradaten zugreifen.

Ergänzung: Da die Konstanten, die mit AL :: k beginnen, in der C ++ - Sprache ausgedrückt werden, müssen sie auf der Python-Seite konkrete Zahlen sein.

1-d. Bitte sehen Sie weiterhin [root / QR Preview / Subscribe Camera].

python


self.memory.raiseEvent("ProgrammingPepperSample/PreviewMode", self.subscriberId)

Übergeben Sie mit diesem Code die zuvor über "ALMemory" erhaltene "criberId "an die Anzeigeseite. Auf der Anzeigeseite wird diese "Abonnenten-ID" verwendet, um Daten zum Zeichnen von der Kamera zu extrahieren.

Anzeigeseite

Es ist endlich auf der Displayseite. Da die Zeichenverarbeitung nicht auf der Pfefferseite ausgeführt werden kann, ist auf der Anzeigeseite eine Pixelverarbeitung für JavaScript erforderlich.

2-a. Siehe main.js.

main.js


ALMemory.subscriber("ProgrammingPepperSample/PreviewMode").then(function(subscriber) {
    subscriber.signal.connect(function(subscriberId) {
        if(subscriberId.length > 0) {
            console.log("Subscribing...: " + subscriberId)
            previewRunning = true
            activatePanel("camera")
            activatePanel("common")
            getImage(ALVideoDevice, subscriberId)
        }else{
            previewRunning = false
            inactivatePanel("camera")
            inactivatePanel("common")
        }
    })
});

Hier geht es darum, getImage (ALVideoDevice ,criberId) verarbeiten zu lassen. Wenn "ProgrammingPepperSample / PreviewMode" fliegt, wird "getImage (ALVideoDevice ,criberId)" aufgerufen. Andere Funktionen, die intern aufgerufen werden, sind nur das Umschalten von Elementen im HTML.

2-b, c. Es ist endlich der Zeichenprozess. Es wird von der Funktion getImage () verarbeitet.

main.js


function getImage(ALVideoDevice, subscriberId) {
    ALVideoDevice.getImageRemote(subscriberId).then(function (image) {
        if(image) {
            var imageWidth = image[0];
            var imageHeight = image[1];
            var imageBuf = image[6];
            console.log("Get image: " + imageWidth + ", " + imageHeight);

            if (!context) {
                context = document.getElementById("canvas").getContext("2d");
            }
            if (!imgData || imageWidth != imgData.width || imageHeight != imgData.height) {
                imgData = context.createImageData(imageWidth, imageHeight);
            }
            var data = imgData.data;

            for (var i = 0, len = imageHeight * imageWidth; i < len; i++) {
                var v = imageBuf[i];
                data[i * 4 + 0] = v;
                data[i * 4 + 1] = v;
                data[i * 4 + 2] = v;
                data[i * 4 + 3] = 255;
            }

            context.putImageData(imgData, 0, 0);
        }
        
        if(previewRunning) {
            setTimeout(function() { getImage(ALVideoDevice, subscriberId) }, 100)
        }
    })
}

Empfangen Sie Bilddaten von Pepper mit "ALVideoDevice.getImageRemote". Bilddaten (Bild) werden in der folgenden Struktur übergeben.

Inhalt
[0] Horizontale Größe
[1] Vertikale Größe
[2] Anzahl der Schichten
[3] Farbraum
[4] Zeitstempel(seconds).
[5] Zeitstempel(microseconds).
[6] Binäres Array von Bilddaten
[7] Kamera-ID
[8] Informationen zum linken Winkel der Kamera(radian).
[9] Winkelinformationen auf der Kamera(radian).
[10] Informationen zum rechten Winkel der Kamera(radian).
[11] Winkelinformationen unter der Kamera(radian).

Die erforderlichen Informationen sind die Informationen in [6], dh die Bilddaten.

Hier wird die Initialisierung (Erstellen eines leeren Bildes) zum Zeichnen auf der Leinwand durchgeführt.

python


if (!context) {
    context = document.getElementById("canvas").getContext("2d");
}
if (!imgData || imageWidth != imgData.width || imageHeight != imgData.height) {
    imgData = context.createImageData(imageWidth, imageHeight);
}

Zeichnen Sie dann die Daten über putImageData.

python


context.putImageData(imgData,x,y);

x und y sind die Koordinaten, um mit dem Zeichnen zu beginnen. Da der Startpunkt 0, 0 ist, geben Sie 0 für x und y an. In imageData wird das zu zeichnende Datenarray in der Reihenfolge RGBA in das Array eingefügt. R ist rot, G ist grün, B ist blau und A ist der Alpha-Kanal. Bei den von Pepper erhaltenen Kameradaten handelt es sich um Helligkeitsinformationen. Wenn Sie also für jedes RGB denselben Wert eingeben, erhalten Sie ein monochromes Bild. Da A ein Alpha-Kanal ist, geben Sie 255 ein, damit er nicht transparent ist.

python


for (var i = 0, len = imageHeight * imageWidth; i < len; i++) {
    var v = imageBuf[i];
    data[i * 4 + 0] = v;
    data[i * 4 + 1] = v;
    data[i * 4 + 2] = v;
    data[i * 4 + 3] = 255;
}

Sie können jetzt oben ein Standbild zeichnen. 2-d. Bilder müssen ständig aktualisiert werden.

python


setTimeout(function() { getImage(ALVideoDevice, subscriberId) }, 100)

Es arbeitet rekursiv und zeichnet.

Schließlich

Haben Sie den Ablauf der Anzeige der Kameravorschau auf dem Pepper-Display erfasst? Der Punkt ist, die criberId zu erhalten und den Zeichenvorgang auf der Anzeigeseite durchzuführen. Das Beispiel hat eine sehr niedrige Auflösung von QQQVGA (80x60), aber Sie können auch Bilder mit höheren Auflösungen erhalten. Obwohl das Beispiel monochrom war, können Sie auch ein Farbbild erhalten, indem Sie das Format und die Zeichenroutine ändern. Es ist jedoch JavaScript in HTML, das den Zeichenprozess ausführt. Wenn Sie mit hoher Auflösung zeichnen oder eine Farbverarbeitung durchführen, kann die Verarbeitung möglicherweise nicht mithalten. Versuchen Sie, eine Einstellung zu finden, die in der erstellten App problemlos funktioniert.

Recommended Posts

Vorschau der QR-Code-Kamera
QR-Code-Anzeige
Befehl zum Generieren von QR-Code
Generieren Sie QR-Code in Python
QR-Code mit CNN entschlüsseln
[Python] Generiert QR-Code im Speicher
Generieren Sie QR-Code mit Pythons "qrcode"