Hatena::Grouptechmemo

USBカメラを使って色々遊ぶ日記(仮)

2008-05-27最近ほとんど何も進展がない…そりゃ進めてないから仕方がない

Fedora 8でluvcviewは動いた

| 22:53 | Fedora 8でluvcviewは動いた - USBカメラを使って色々遊ぶ日記(仮) を含むブックマーク はてなブックマーク - Fedora 8でluvcviewは動いた - USBカメラを使って色々遊ぶ日記(仮)

最初v4l-infoコマンドが入っていなかったので適当に入れてみたらいつの間にか使えるようになっていた。(何の参考にもならないな)

ARToolKitのSEGV問題に悩んでいたが、私の最初のV4L2動作実績であるluvcviewを入れて確認してみることに。

おや、これはちゃんと動作するようだ。

しかし、ボタンなどを押すとエラーが発生。

そして相変わらずARToolKitではSegmentation Fault。うぐぅ。

infinityinfinity2008/05/28 12:04はじめまして。
私も今月頭からFedora8でARToolKitを動かそうと試みています。
ネット上にLinuxでARToolKitを動かした例と詳細な情報が少なく、このブログを見つけてからはお世話になりっぱなしです(笑
先週から管理人さんが私と同じ環境で試されているようでしたので、何か力になれたらと思い、書き込みさせて頂きました。

さて、私の方の現状としては、
ARToolKit2.71.3の方で外人さんのパッチを当てた後に、simpleLite.cの421行目を
"-dev=/dev/video0 -channel=0 -palette=YUV422P -width=320 -height=240";
に変えて試すと、正常な動作ではないものの一応動いてマーク検出もされました。
パラメータは使っているカメラによりけりだとは思いますが、一度試しみてはいかがでしょうか?

ARToolKit2.72.1は2.73.1と同じ箇所を変更したり、色々試しているのですが、Segmentation Faultで動いていません。
その前に出ている
 ar2VideoCapNext:Error calling VIDIOC_QBUF:22
が怪しいと思って調べているんですが、まだ解決できていません…

ということで今後も色々試してみます。お互い頑張りましょう!
何か進展しましたらまた書き込みさせていただきますね ^^

emergentemergent2008/05/30 00:36>infinityさん
はじめまして、コメントありがとうございます。
頂いたアドバイスの方も、時間が取れ次第試してみようと思います。
今は少し仕事が立て込んでいる時期で、更新が遅めになっていますが、
少しでも何かやったらここのブログに書くようにしますね。
infinityさんはブログなどお持ちでしょうか?
そちらでも進展ありましたら、またよろしくお願いします。
頑張りましょうね!

2008-05-01

SDLとかDirectFBとか

| 01:18 | SDLとかDirectFBとか - USBカメラを使って色々遊ぶ日記(仮) を含むブックマーク はてなブックマーク - SDLとかDirectFBとか - USBカメラを使って色々遊ぶ日記(仮)

USBカメラで撮影した映像を画面に出力するためのライブラリが必要なはず。

聞いたことのあるものだとタイトルにあるようなものかなぁ、とか思ってる。

SDLはWikipediaに載っていたけどDirectFBはないな。

あとは、ARToolKitでも使っているOpenGLの知識も必要か。

やばい、なんか分散してきたな。

用語もわからないのが多いし、勉強しなくては。

2008-04-11飲んだ

今日はちょっと

| 01:48 | 今日はちょっと - USBカメラを使って色々遊ぶ日記(仮) を含むブックマーク はてなブックマーク - 今日はちょっと - USBカメラを使って色々遊ぶ日記(仮)

色々調べたりするのは無理っぽい。

一緒に飲んだ会社の先輩に今の遊びを話すと絶賛奨励してくれたのでうれしい限り。

もっと頑張って楽しもう。

2008-04-10ちょっとだけコードを書いてみる

USBカメラのcapability

| 01:40 | USBカメラのcapability - USBカメラを使って色々遊ぶ日記(仮) を含むブックマーク はてなブックマーク - USBカメラのcapability - USBカメラを使って色々遊ぶ日記(仮)

luvcviewのヘルプを見たところ、-Lオプションでカメラの能力を調べられるようだ。

頑張って書く必要なかったかも。

$ ./luvcview -L
luvcview version 0.2.3
Video driver: x11
A window manager is available
video /dev/video0
/dev/video0 does not support read i/o
{ pixelformat = 'MJPG', description = 'MJPEG' }
{ discrete: width = 160, height = 120 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 176, height = 144 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 320, height = 240 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 352, height = 288 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 640, height = 480 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 800, height = 600 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 960, height = 720 }
        Time interval between frame: 1/15, 1/10, 1/5,
{ pixelformat = 'YUYV', description = 'YUV 4:2:2 (YUYV)' }
{ discrete: width = 160, height = 120 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 176, height = 144 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 320, height = 240 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 352, height = 288 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 640, height = 480 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 800, height = 600 }
        Time interval between frame: 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 960, height = 720 }
        Time interval between frame: 1/10, 1/5,
{ discrete: width = 1600, height = 1200 }
        Time interval between frame: 1/5,

いきなり見てもよくわからないんだけどね。

v4l2_capabilityの取得

| 00:58 | v4l2_capabilityの取得 - USBカメラを使って色々遊ぶ日記(仮) を含むブックマーク はてなブックマーク - v4l2_capabilityの取得 - USBカメラを使って色々遊ぶ日記(仮)

昨日VIDIOC_QUERYCAPまで見たので、とりあえずそれでデバイスに問い合わせて結果を表示するだけのプログラムを書いた。

#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <linux/videodev.h>

#define p(...) printf("  " __VA_ARGS__)

void print_v4l2_cap(struct v4l2_capability *cap)
{
    p("driver\t:\t%s\n", cap->driver);
    p("card    \t:\t%s\n", cap->card);
    p("bus_info\t:\t%s\n", cap->bus_info);
    p("version\t:\t%d\n", cap->version);
    p("capabilities\t:\t%d\n", cap->capabilities);
}

int main(int argc, char *argv[])
{
    int fd;
    int ret;
    char* videodevice = "/dev/video0";
    struct v4l2_capability cap;

    if ((fd = open(videodevice, O_RDWR)) == -1) {
        printf("open error: fd=%d\n", fd);
        return -1;
    }
    
    ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
    if (ret < 0) {
        printf("querycap error: ret=%d\n", ret);
        return -1;
    }

    print_v4l2_cap(&cap);

    return 0;
}

出力結果はこんな感じ。

$ ./v4l2test_querycap
  driver        :       uvcvideo
  card          :       UVC Camera (046d:0990)
  bus_info      :       0000:00:1d.7
  version       :       256
  capabilities  :       67108865

次は、video_capabilityを取得してみたい。

追記

と思ったらvideo_capabilityはv4l2_capabilityに置き換えられた古い構造体らしい。

(参考)http://www.linuxtv.org/downloads/video4linux/API/V4L2_API/spec-single/v4l2.html

2008-04-08Video4Linuxアプリをいくつか試す

ffmpegで録画してみる

| 00:03 | ffmpegで録画してみる - USBカメラを使って色々遊ぶ日記(仮) を含むブックマーク はてなブックマーク - ffmpegで録画してみる - USBカメラを使って色々遊ぶ日記(仮)

昨日は、純粋に画面にリアルタイムでキャプチャした映像を映したかったのでluvcviewを利用したが、録画ならばffmpegでできるらしい。

$ ffmpeg -s 320x240 -f audio_device -i /dev/audio1 -f video4linux2 -i /dev/video0 out.mpg

このコマンドを実行すると、録画モードに入り、qボタンで終了するまで録画してくれる。

これは見事なまでに簡単。ただし、-sで指定する動画サイズは、

大きくしても解像度がよくなるということはないようだ。残念。

もうちょっと画質をよくする方法はないだろうか。

Video4Linuxについて調べてみる

| 00:10 | Video4Linuxについて調べてみる - USBカメラを使って色々遊ぶ日記(仮) を含むブックマーク はてなブックマーク - Video4Linuxについて調べてみる - USBカメラを使って色々遊ぶ日記(仮)

そんなに深く追究したわけではないけれど。

Linux上でビデオキャプチャーカード(主にBT8x8)を制御するためのAPI

Video4Linuxとは - はてなダイアリー

あら、あっさり。

どうやらVideo4Linux(v4l)と、Video4Linux2(v4l2)の2種類があるらしい。

v4l

is the original video capture/overlay API of the linux kernel. It appeared late the 2.1.x development cycle in the linux kernel.

v4l2

is the second generation of the video4linux API which fixes a number of design bugs of the first version. It was integrated into the standard kernel in 2.5.x.

Althrough v4l2 is integrated into the standard kernel a number of drivers don't support the new v4l2 API yet, so we'll likely see v4l and v4l2 coexist for some time.

video4linux

組み込まれるベースとなるカーネルのバージョンが違うのね。2.5以降のカーネルではv4l2が入っていると考えていいのかしら。要調査。

v4lのリンク集みたいなのもあった。

Synapticで検索して出てくるものをインストールしてみる

| 00:28 | Synapticで検索して出てくるものをインストールしてみる - USBカメラを使って色々遊ぶ日記(仮) を含むブックマーク はてなブックマーク - Synapticで検索して出てくるものをインストールしてみる - USBカメラを使って色々遊ぶ日記(仮)

  • camorama: エラーダイアログが出て起動しない
  • gqcam: 起動はするが「Error reading image...」が繰り返し出力され映像が出ない。

xawtvも出ないし、デバイスの読み込みに難があるのかな?

luvcviewのソースを読んでみる(1)

| 23:22 | luvcviewのソースを読んでみる(1) - USBカメラを使って色々遊ぶ日記(仮) を含むブックマーク はてなブックマーク - luvcviewのソースを読んでみる(1) - USBカメラを使って色々遊ぶ日記(仮)

(1)とか付けてみたけど続くかどうかは不明。

まずは、初期化や設定はさておいて、どこでカメラから取得したデータを読んでいるのかを追ってみる。

メインのループは、luvcview.cの485行目付近。

    /* main big loop */
    while (videoIn->signalquit) {
	currtime = SDL_GetTicks();
	if (currtime - lasttime > 0) {
		frmrate = 1000/(currtime - lasttime);
	}
	lasttime = currtime;
	if (uvcGrab(videoIn) < 0) {
	    printf("Error grabbing\n");
	    break;
	}

    /* if we're grabbing video, show the frame rate */
    if (videoIn->toggleAvi)
        printf("\rframe rate: %d     ",frmrate);

	SDL_LockYUVOverlay(overlay);
	memcpy(p, videoIn->framebuffer,
	       videoIn->width * (videoIn->height) * 2);
	SDL_UnlockYUVOverlay(overlay);
	SDL_DisplayYUVOverlay(overlay, &drect);

	if (videoIn->getPict) { 
		switch(videoIn->formatIn){
		case V4L2_PIX_FMT_MJPEG:
			get_picture(videoIn->tmpbuffer,videoIn->buf.bytesused);
			break;
		case V4L2_PIX_FMT_YUYV:
			get_pictureYV2(videoIn->framebuffer,videoIn->width,videoIn->height);
			break;
		default:
		break;
		}
		videoIn->getPict = 0;
		printf("get picture !\n");
	}

	SDL_LockMutex(affmutex);
	ptdata.frmrate = frmrate;
	SDL_WM_SetCaption(videoIn->status, NULL);
	SDL_UnlockMutex(affmutex);
	SDL_Delay(10);

    }

さらに、実際に読んでいるのはuvcGrabという関数(v4l2uvc.c)のようだ。

デバイスを制御するのにはioctl関数を使い、なおかつVIDIOC_で始まるコマンドでvideoデバイス関連のコマンドを実行している。

    ret = ioctl(vd->fd, VIDIOC_DQBUF, &vd->buf);

これが、デバイスのバッファにある撮影したフレームを取り出す部分のようだ。

本関数の最後の方に、

    ret = ioctl(vd->fd, VIDIOC_QBUF, &vd->buf);

とバッファをエンキューしている部分があるので、複数あるバッファに対して、フレームを読み出す→空いたバッファを再度エンキューする、という繰り返しかと想像。

時間のあるときにもうちょっと頑張る。