LoginSignup
8
4

More than 5 years have passed since last update.

getUserMedia()のconstraintsでカメラデバイスおよび出力解像度の選択に使用されるfitness distanceアルゴリズムについて

Last updated at Posted at 2017-05-29

getUserMediaのConstraintsは、いまだブラウザーごとの実装に差異がありますが、W3CのMedia Capture and Streamsにconstraintsの値からカメラデバイスおよび解像度の選択において"fitness distance"というアルゴリズムが使用されると書かれています。
この"fitness distance"について説明したいと思います。
ただし、現在、このアルゴリズムをサポートしているのはFirefoxのみとなっています。

この"fitness distance"がどのようなアルゴリズムかというと、仕様にはアルゴリズムで使用する計算式が書かれています。

(actual == ideal) ? 0 : |actual - ideal|/max(|actual|,|ideal|)

actualにはカメラの解像度、idealにはconstraintsで設定した解像度が入ります。
解像度といっても、widthとheightの2つの値があります。ちょっと自信がないのですが、Firefoxのソースを見るとwidthとheightでそれぞれこの計算式で値を算出し、2つの値を足したものがそのカメラと解像度の組み合わせに対するConstraints設定とのdistance値としているようです。
接続されているカメラおよびカメラが対応している出力解像度分このdistance値を求め、distance値が最小となる組み合わせが選択されます。
例えば、constraintsを

{
  video: {
    width: 200,
    height: 200
  }
}

としたとき、解像度160x120のdistance値は

(160 == 200) ? 0 : Math.abs(160 - 200) / Math.max(160, 200) = 0.2
(120 == 200) ? 0 : Math.abs(120 - 200) / Math.max(120, 200) = 0.4
0.2 + 0.4 = 0.6

ということで0.6となります。

私が所有するカメラで検証してみました。
Logicool HD Webcam C615(以降Logicool) とノートPCに搭載されている BisonCam, NB Pro(以降Bison) というカメラです。
それぞれのカメラが提供している出力解像度は以下のようになっています。また既定デバイスはLogicool になっています。

Logicool(既定デバイス) BisonCam
160x120 160x120
176x144 176x144
320x240 320x240
352x288 352x288
432x240 -
640x360 640x360
640x480 640x480
800x448 -
864x480 -
800x600 -
1024x576 -
960x720 -
1280x720 1280x720
- 1280x1024
1600x896 -
1920x1080 1920x1080

ここで、Constraintsを以下のように設定してgetUsermedia()を実行してみます。

{
  video:{
    width: 300,
    height: 300
  }
}

すると、Logicoolで352x288の解像度が選択されてストリームが取得されました。
distanceの値を計算してみます。(小数点第3位四捨五入)

Logicool(既定デバイス) BisonCam distance値
160x120 160x120 1.07
176x144 176x144 0.93
320x240 320x240 0.26
352x288 352x288 ★0.19
432x240 - 0.51
640x360 640x360 0.7
640x480 640x480 0.91
800x448 - 0.96
864x480 - 1.03
800x600 - 1.13
1024x576 - 1.19
960x720 - 1.27
1280x720 1280x720 1.35
- 1280x1024 1.47
1600x896 - 1.48
1920x1080 1920x1080 1.57

distance値が最小となったのは352x288の解像度で、この解像度は両デバイスともに対応していますが、既定デバイスがLogicoolですのでLogicoolを選択、ということで計算による選択と実際の動作が一致しました。

次にConstraintsを以下のようにして、getUserMedia()を実行してみます。

{
  video:{
    width: 1000,
    height: 1000
  }
}

すると、Bisonで1280x1024の解像度が選択されてストリームが取得されました。
distanceの値を計算してみます。

Logicool(既定デバイス) BisonCam distance値
160x120 160x120 1.72
176x144 176x144 1.68
320x240 320x240 1.44
352x288 352x288 1.36
432x240 - 1.328
640x360 640x360 1
640x480 640x480 0.88
800x448 - 0.752
864x480 - 0.656
800x600 - 0.6
1024x576 - 0.4474375
960x720 - 0.32
1280x720 1280x720 0.5
- 1280x1024 ★0.24
1600x896 - 0.48
1920x1080 1920x1080 0.55

となり、解像度1280x1024がdistance値が最小となりますが、この解像度はBisonしかサポートしていませんので、Bisonで1280x1024を選択ということでこれも実際の動作と一致しました。

このように、デバイスを指定していない場合、既定のデバイスとは違うデバイスが選択される場合があることに注意しておいたほうがいいでしょう。

8
4
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
8
4