4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Pepperのカメラ映像をディスプレイに描画する

Last updated at Posted at 2018-12-22

実践したこと

QRコードカメラプレビューの記事を参考に、Pepperのカメラの映像をディスプレイで確認出来るようにしました。ソースコードの一部を書き換えただけなので、GitHubからサンプルコードを入手して来ることをおすすめします。

手法

詳しいことは先程のリンクに丁寧に記載されているので、ここではざっくりとした手法の解説をしたいと思います。

  1. ALTabletServiceからindex.htmlを表示しqimessageingを使用
  2. ALVideoDeviceで値を引き出すハンドラ(self.subscriberId)をALMemoryに格納
  3. ALMemoryに格納したハンドラを用いてALVideoDeviceから画像の値を取得
  4. 値をディスプレイに描画

コードの書き換え部分

まずchoregraphe/QR Preview/Subscribe Cameraの一部を書き換えます。

def onInput_onStart(self):
        fps = 10
        if self.subscriberId is None:
            self.subscriberId = self.videoDevice.subscribeCamera("QRPreview",
                    0, # TopCamera
                    7, # AL:kQQQVGA
                    0, # AL::kYuvColorSpace 
                    fps)
        self.memory.raiseEvent("ProgrammingPepperSample/PreviewMode", self.subscriberId)
        self.onSubscribed(self.subscriberId)

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

この3つ目の数値をPepperの2Dカメラ-公式ドキュメントのリンクを参考に変更します。今回は画像のRGB値が欲しいので11とします。(サンプルコードだと0)



次にhtml/scripts/main.jsを書き換えていきます。

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);
            console.log(image);

            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)
        }
    })
}

取得する画像情報がモノクロからRGB値に変更になりました。image[6]のimageBuf配列に格納されている一次元配列にR値、G値、B値の3つの値が順に格納されています。そこでfor文を用いてそれぞれの値を取得出来るように変更します。

main.js
for (var i = 0, len = imageHeight * imageWidth; i < len; i++) {
                var r = imageBuf[3*i];
                var g = imageBuf[3*i+1];
                var b = imageBuf[3*i+2];
                data[i * 4 + 0] = r;
                data[i * 4 + 1] = g;
                data[i * 4 + 2] = b;
                data[i * 4 + 3] = 255;
            }

その他、ディスプレイに描画される範囲をもう少し大きくしたかったので`html/main.css`の`canvas`の値を変更しました。
main.css

#canvas {
    position: relative;
    display: inline-block;
    width: 960px;
    height: 820px;
    margin: 10px 10px;
    padding: 0;
}
.canvas-background {
    position: static;
    display: inline-block;
    width: 980px;
    height: 840px;
    margin: 0;
    padding: 0;
    background-color: #555555;
}

実行結果

色付きでディスプレイに描画することができました!!
IMG_6231.JPG
IMG_6232.JPG

雑談

Pepperのディスプレイに色付きでカメラ画像を描画するためには、画像の解像度をかなり落としてあげないと動作しません。色付きで見るか、モノクロでもう少し高解像度で見てあげるかのどちらがいいのかは正直難しいところがありますね...

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?