takminの書きっぱなし備忘録 @はてなブログ

主にコンピュータビジョンなど技術について、たまに自分自身のことや思いついたことなど

javascriptでカメラの解像度を取得するとOSやブラウザで振る舞いが異なる

javascriptでカメラの解像度を取得する際、OSやブラウザによって振る舞いが異なるため、色々とはまったのでメモ。

まず、カメラの解像度を取得するコードは以下の通り

  let stream = await navigator.mediaDevices
    .getUserMedia({
      video: {
        facingMode: currentFacingMode
      },
      audio: false
    });

  // Get the video track of the camera stream
  const track = stream.getVideoTracks()[0];

  // Get the current settings of the video track
  const settings = track.getSettings();

  // Camera resolution
  let video_width = settings.width;
  let video_height = settings.height;

ここでvideo_widthが幅のピクセル数、video_heightが高さのピクセル数になります。

やっかいなのは、OSやブラウザによって、デバイスの自動回転をONにした状態で、スマホを横向きにした時にwidthとheightが入れ替わるケースとそうでないケースがあることです。 デバイスの回転に関係なく一定のケースでは、デバイスの向きによらず、width > heightでした。一方デバイスの回転が反映されるケースでは、スマホを縦に持った時はheight > width、横にした時はwidth > heightです。

僕がテストした範囲ではこんな感じです。

結局、navigator.userAgentなどを使用して、OSやブラウザを特定して場合分けすることで対応しました。

点群SegmentationのためのTransformerサーベイ

今回、主に点群に対してSemantic Segmentationを行うためにTansformerを適用した研究についてサーベイしてみたので、資料を公開します。

元々は、前回開催したコンピュータビジョン勉強会@関東「深層学習+3D論文読み会」で発表するために準備していたのですが、発表者が十分に集まったことと、ハイブリッド開催のため運営が大変になりそうだったので、発表は断念しました。

最初は画像と点群でのTransformerの適用方法の違いが気になって調べだしたので、PointTransformerとPointMixerあたりまでを発表するつもりだったのですが、発表を取りやめて調べる時間もできたので、色々と追加で調べているうちに分量が増えてしまいました。

調べてみて、果たしてTransformerは畳み込みと比べて点群処理に最適か?というのはよくわかりませんでした。ただ、PointBERTのように大規模事前学習モデルを作るのは世の流れなので、学習データの量の問題はありますが、点群に関してもいずれそうなるのではないかと思ってます。

また、点群に対してTransformerを適用する場合、計算リソースが大きな問題となるので、そこをどう工夫するか各手法が知恵を絞っている感じでした。 他にもAttentionの計算に、内積の代わりに差分を用いる等、画像とは違ったアプローチが多々見られました。

というわけでご参考になれば幸いです。また、抜けや誤り等コメント歓迎です。

第58回コンピュータビジョン勉強会@関東「深層学習+3D論文読み会」資料まとめ

本日、コンピュータビジョン勉強会@関東を「深層学習+3D論文読み会」というテーマで、深層学習で三次元を扱うならなんでもありという論文読み会をキャディ株式会社様の会場を借りて、オンラインとのハイブリッドで開催いたしました。 (結果、1件を除きすべてがNeRFがテーマでした。)

というわけで、資料やリンク等をまとめておきます。

登録サイト

kantocv.connpass.com

Togetter

togetter.com

Youtube

www.youtube.com

コンピュータビジョン勉強会@関東

sites.google.com

資料まとめ

発表者 発表内容 資料
dhirooka Instant Neural Graphics Primitives with a Multiresolution Hash Encoding https://speakerdeck.com/daigo0927/introducing-instant-neural-graphics-primitives-with-a-multiresolution-hash-encoding
pacifinapacific Instruct-NeRF2NeRF Editing 3D Scenes with Instructions https://www.docswell.com/s/pacifinapacific/5NR1PG-2023-04-30-224710
shnhrtkyk 点群深層学習に計測の気持ちを入れた研究の紹介 https://speakerdeck.com/shnhrtkyk/dian-qun-shen-ceng-xue-xi-niji-ce-noqi-chi-tiworu-retayan-jiu-noshao-jie
kzykmyzw VoxFormer: Sparse Voxel Transformer for Camera-based 3D Semantic Scene Completion https://speakerdeck.com/kzykmyzw/voxformer-sparse-voxel-transformer-for-camera-based-3d-semantic-scene-completion
inoichan マルチカメラによる自動運転の3D Occupancy Prediction https://speakerdeck.com/inoichan/cvguan-dong-3dmian-qiang-hui-tpvformer-marutikamerawoyong-itazi-dong-yun-zhuan-3d-occupancy-prediction
neka-nat Text-to-Imageを応用したNeRF論文の解説 https://speakerdeck.com/nekanat/zui-jin-qi-ninatuterutext-to-imagewoying-yong-sitanerflun-wen-nojie-shuo
peisuke Mip-NeRF 360: Unbounded Anti-Aliased Neural Radiance Fields https://speakerdeck.com/peisuke/mip-nerf-360-unbounded-anti-aliased-neural-radiance-fields
shade-tree Ego-Body Pose Estimation via Ego-Head Pose Estimation https://speakerdeck.com/forest1988/ego-body-pose-estimation-via-ego-head-pose-estimation
tomoaki_teshima Block-NeRF: Scalable Large Scene Neural View Synthesis (CVPR2022) https://speakerdeck.com/tomoaki0705/block-nerf

FastAPIをOpenCVと連携

FastAPIはPythonで簡単にAPIサーバーが立てられるライブラリです。

fastapi.tiangolo.com

今回これを利用して、HTTP POSTで送られた画像になんらかの認識処理をかけて、結果をjsonで返すようなプログラムを書いたのでメモしておきます。 その際、送られてきた画像はOpenCVで処理してます。

1. 必要なライブラリをインストール

FastAPIはuvicornというASGI(Asynchronous Server Gateway Interface)サーバーを使用しています。ASGIが何かはとりあえず知らなくても良いです。

他に、opencvやnumpyなどもインストールします。

$ pip install fastapi
$ pip install "uvicorn[standard]"
$ pip install python-multipart
$ pip install numpy
$ pip install opencv-python

2. FastAPIのコードを書く

ここでは単純に画像を受け取って、ローカルにpng形式で保存し、そのファイル名と画像サイズをjsonで返すプログラムを書きました。

以下のコードをmain.pyというファイルに記載します。

from fastapi import FastAPI, UploadFile, File, Form
from fastapi.responses import HTMLResponse
import cv2
import numpy as np
import os

# FastAPIのインスタンス生成
app = FastAPI()

# Http Postの処理
# 送付されてきた画像をフォーマットを指定して保存
@app.post("/api")
async def save_img(file:UploadFile = File(...), format:str=Form()):
    try:
        if file:
            #画像をメモリ上へ読み込み
            data = await file.read()

            #バイナリへ変換
            array = np.fromstring(data, np.uint8)

            #画像へ変換(OpenCV)
            img = cv2.imdecode(array, flags=cv2.IMREAD_COLOR)

            # ファイル名の拡張子を指定フォーマットのものへ変更
            basename, _ = os.path.splitext(file.filename)
            savename = basename + "." + format

            # 画像を保存(フォーマットはOpenCVが拡張子で判断)
            cv2.imwrite(savename, img)

            # 応答
            response = {"save filename":savename, "image size": str(img.shape)}
            return response

    except Exception as e:
        print(e)


# Top Page (Http Get)
# Formを表示
@app.get("/")
async def main():
    content = """
<body>
<form action="/api" enctype="multipart/form-data" method="post">
<input name="file" type="file" />
<br/>
<select name="format">
  <option value="jpg">jpg</option>
  <option value="png">png</option>
  <option value="bmp">bmp</option>
</select>
<input type="submit"/>
</form>
</body>
    """
    return HTMLResponse(content=content)

3. サーバーの起動と動作確認

以下のコマンドでサーバーを起動します。

$ uvicorn main:app --reload

main.pyのappというFastAPIオブジェクトが起動されます。

次に

http://localhost:8000

へアクセスすると、以下のようなWebフォームが開きます。

画像ファイル送信フォーム

ここで、ファイルを選択し、保存したいフォーマットを選択して「送信」ボタンを押すと、画像がHTTP Postで送信され、例えば以下のようなjsonを受け取ります。

{"save filename":"query.png","image size":"(1280, 871, 3)"}

FastAPIを起動したディレクトリ上に画像ファイルが指定フォーマットで保存されているのが確認できると思います。