LinuxでUSBビデオカメラを使用します。 パート1

今日のビデオカメラの人気は、マイクとヘッドフォンに匹敵します。 オブジェクト認識、拡張現実、ビデオ会議など、さまざまな方法で使用されます。 しかし、これらの複雑なプログラムの内部には何が隠されていますか? ビデオカメラから写真を取得するにはどうすればよいですか? この一連の記事では、低レベルでビデオカメラを操作し、結果の画像を処理する簡単さを確認できます。



手始めに、Linuxシステム上のデバイスの操作に関するいくつかの情報。 nixシステム上のデバイスはファイルです。 一部のデバイスファイルでは、通常のファイルのように作業できます。 例:



~$ cat /dev/sda
      
      



このコマンドは、sdaドライブ全体を表示します。



直接操作できないデバイスがあり、ビデオカメラはそれらに属します。これを実行しようとすると、次のシステム応答が返されます。



 ~$ cat: /dev/video0:  
      
      



* / dev / video0は、ビデオカメラのファイルデバイスです。



これを使用するには、ioctlシステム関数が必要になります;これについて詳しく知ることができます[1] 。 それを適用してみましょう。 以下は、デバイスから情報を読み取るためのコードです(ビデオデバイスのcatコマンドの代替)。



ここにコード
 #include <fcntl.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <linux/videodev2.h> int main (int argc,char* argv[]) { /*Read Params*/ char *device_name; if(argc > 1) {  device_name = argv[1]; } else {  device_name = "/dev/video0"; } /*Open Device*/ int file_device = open(device_name, O_RDWR, 0); if (file_device == -1) {  printf ("%s error %d, %s\n",device_name, errno, strerror(errno));  exit(EXIT_FAILURE); } /*Read Params From Device*/ struct v4l2_capability device_params; if (ioctl(file_device, VIDIOC_QUERYCAP, &device_params) == -1) {  printf ("\"VIDIOC_QUERYCAP\" error %d, %s\n", errno, strerror(errno));  exit(EXIT_FAILURE); } printf("driver : %s\n",device_params.driver); printf("card : %s\n",device_params.card); printf("bus_info : %s\n",device_params.bus_info); printf("version : %d.%d.%d\n",     ((device_params.version >> 16) & 0xFF),     ((device_params.version >> 8) & 0xFF),     (device_params.version & 0xFF)); printf("capabilities: 0x%08x\n", device_params.capabilities); printf("device capabilities: 0x%08x\n", device_params.device_caps); /* Close Device */ if (-1 == close (file_device)) {  printf ("\"close\" error %d, %s\n", errno, strerror(errno));  exit(EXIT_FAILURE); } file_device = -1; return 0; }
      
      











コードの最初の行は、アプリケーションの実行元のパラメーターを読み取ります。 パラメーターがない場合、device_nameは標準値「/ dev / video0」を取ります。



「デバイスを開く」ブロックでは、デバイスはオープンシステム関数で開かれます(ヘッダーfcntl.hを接続する必要があります)。 必須パラメーターO_RDWRは、リーダー/ライターを開く役割を果たします。 接続中にエラーが発生した場合、open関数は-1を返します。



Read Params From Deviceブロックは、小さなプログラムの中心です。 それを使用するには、ライブラリを接続する必要があります
 <linux/videodev2.h>
      
      



インストールする必要があります。各ディストリビューションには、このライブラリ用の独自のパッケージがあります

ioctlシステム関数には3つのパラメーターがあります。

file_device-デバイスのハンドル

VIDIOC_QUERYCAPは、デバイスに使用するカーネル関数です。

device_params-関数「VIDIOC_QUERYCAP」の結果がダンプされるメモリ領域。



device_paramsは、次のフィールドで構成される構造です。



 struct v4l2_capability {  __u8  driver[16]; //    -     __u8  card[32]; //    __u8  bus_info[32]; //      (   usb-)  __u32 version; //     __u32 capabilities; // (/)    __u32 device_caps; //      __u32 reserved[3]; //   };
      
      





エラーが発生した場合、ioctlは-1を返します



「デバイスを閉じる」ブロックは、デバイス記述子を閉じます。



実行中のプログラムを見てみましょう。



コンパイルする

 gcc catvd.c -o catdv
      
      







走りましょう

 ./catvd /dev/video0 /dev/video0 error 2, No such file or directory
      
      





デバイスがカーネルによって検出されなかったか、 クリーナーが再び接続されていなかったため、 不要なワイヤが引かました

接続して再起動します。 次の情報を取得します。

 ./catvd /dev/video0 driver : uvcvideo card : UVC Camera (046d:0804) bus_info : usb-0000:00:12.2-3 version : 3.11.10 capabilities: 0x84000001 device capabilities: 0x04000001
      
      







videodev2.hファイルの定数のおかげで、ケーパビリティとデバイスケーパビリティのフィールドを解読できます:



 V4L2_CAP_DEVICE_CAPS 0x80000000 //      . V4L2_CAP_STREAMING 0x04000000 //    i/o ioctls. V4L2_CAP_VIDEO_CAPTURE 0x00000001 //    .
      
      







これで入門記事は終わりです。 以下のレビューでは、メモリマッピング、画像ビデオ形式、カメラ設定、テクスチャへの画像の出力、複数のカメラの操作などのトピックを扱います。



この記事で使用されているリソース:



  1. ioctlの作業記事
  2. Linux用のビデオの操作について(少し古い情報)


記事で使用されているプログラムのソースコード



All Articles