AVRでLEDを点滅させるプログラム

前回の記事で無事にマイコンを経由してLEDを点灯させる事ができた。
その時に利用したプログラムはサンプルをコピペしただけだったので、2つ接続したLEDを交互にランダム点灯させるプログラムに変更したいと思う。

最初にサンプルコードで意味が分からない変数や関数があったので、それを調べることにしてみた。サンプルコードは以下のような感じだ。

#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRD = 1 << 4;           /* make the LED pin an output */
for(;;){
char i;
for(i = 0; i < 10; i++){
_delay_ms(30);  /* max is 262.14 ms / F_CPU in MHz */
}
PORTD ^= 1 << 4;    /* toggle the LED */
}
return 0;               /* never reached */
}

定義済みグローバル変数

DDRDとPORTDにビット演算の結果を代入しているようだけど、まずここが謎だった。

DDRD = 1 << 4;
PORTD ^= 1 << 4;

DDRD変数の中身が気になったので、宣言元である「avr/io.h」を覗いてみたところ、マイコンの種類判定後に「iotn2313.h」をインクルードしているようだ。

#elif defined (__AVR_ATtiny2313__)
#  include <avr/iotn2313.h>

「iotn2313.h」の中にDDRDの宣言があったけどマクロを呼んでいるようだ…。

#define DDRD    _SFR_IO8(0x11)

_SFR_IO8マクロの宣言元は「sfr_defs.h」にあった。どうやらアセンブラとCからの呼び出しでマクロの内容も変化するようだ。

// アセンブラ
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
// C
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)

uint8_t型でアクセスできるようで、__SFR_OFFSETは、0x20のアドレスになっているようだ。

AVRのSFRは基本的にメモリ空間にマッピングされているが、低位の64バイトはI/O空間にもマッピングされていて、どちらでもアクセスできる。 しかし、メモリ空間の最初の32バイトには汎用レジスタがマッピングされているのに対し、I/O空間にはそれがないのでアドレスが32バイトずれている。 つまり、メモリ空間で0x20~0x5Fのレジスタが、I/O空間で0x00~0x3Fに見える。 これらのレジスタはIN命令やOUT命令などでアクセスが可能だが、io.h ではレジスタ名がメモリ空間のアドレスで定義されいているので変換が必要になる。 このズレ(0x20)を示すマクロが__SFR_OFFSETで、メモリ空間からI/O空間に変換するためのマクロが_SFR_IO_ADDR。 _SFR_MEM_ADDRというのもあり、こちらは何も変換しない。

このサイトで詳しく解説されていた。
AVR libcを使ってみる you/junkbox

0x11をデータシートで確認してみると、DDRDレジスタ(0x31)となっていた。DDD0〜6とビット位置は同じになっているようだ。
そもそもDDRDレジスタってなんだろって事なんだけど、実は先生に概ね教わっていた。
DDR○は入力・出力を決定するレジスタらしい。この場合、ポートDを入力にする場合は「0」、出力にする場合は「1」に設定するようだ。
同じようにPORTDは、ポートDの出力をHで出す場合は「1」、Lで出す場合は「0」にするらしい。HはHigh、LはLowを表すようで、Hにした場合にプルアップになり、電流が流れるようだ。

これで変数の意味はだいたい分かった。「iotn2313.h」にはこの他にも定義されている変数があるようだ。

関数

続いて関数について調べてみた。今回使用されているのは一つで、_delay_msという関数だ。
調べなくともだいたい分かるが、指定ミリ秒遅延させるものだろう。
気になるのはコメントの「max is 262.14 ms / F_CPU in MHz」というもの。
今回クロック周波数は8MHzに設定していたので、262.14ms / 8Mhz = 32.7675ms になる。最大32msまで設定可能という事だと思う。
32ms以上遅延させたい場合は複数回呼び出す必要があるようで、forループなどで指定回数呼び出す。

for(i = 0; i < 10; i++){
_delay_ms(30);  /* max is 262.14 ms / F_CPU in MHz */
}

30ms * 10 = 300ms(0.3秒遅延させている)

ランダム点滅させるプログラムを組む

お勉強はこのくらいで実際にプログラムを組んでみた。LEDは2つ接続していて、PD3とPD4に接続している。
DDRDのビット3と4を「1(出力)」に設定した。ランダム点滅は、rand関数を呼び出す事で遅延時間を調整する。
定義済み定数・マクロをフル活用するために、指定ビットを立てる_BVマクロ、PD3・PD4定数を利用した。

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdbool.h>
int main(void) {
DDRD = 0b00011000;
bool flag = false;
for (;;) {
char i;
int r = rand() % 10 + 1;
for(i = 0; i < r; i++) {
_delay_ms(30);
}
PORTD = flag ? _BV(PD3) : _BV(PD4);
flag = !flag;
}
return 0;
}

今回のコードとMakefileはGitHubにも上げてみた。
pontago/avr-LedTest · GitHub

アセンブラで書いてみるのもいいかな。。。
次に作るものは温度計・湿度計になると思うけど、一気にハードルも上るから苦労しそうだ。

AVRでLEDを点滅させてみた

前回LEDを点灯させる所まで何とかできた。と言っても、電池ボックスとLEDを接続しただけ…。
今回はいよいよマイコン(AVR)を使って、LEDをコントロールしてみようと思う。

まず、ライターであるAVRISPmkIIとマイコンを接続しなくてはいけない。パソコンとの接続はUSB経由で接続するだけなので簡単。
AVRISPmkIIのコネクタはISPコネクタ(6ピン)のため、このままだとブレッドボードに接続するのに大変なようだ。
そこで、共エレで販売されている「AVRWRT用ブレッドボードISPケーブル」のコネクタに付け替えた。

色々なサイトを参考にしつつ、マイコンに接続してみた。
続いて、マイコンに書き込むためのソフトをインストールするが、Mac環境だったため、正規のソフト(AVR Studio)が使えないようなので、CrossPack for AVR Developmentを使うことにした。
CrossPack – A Development Environment for Atmel’s AVR Microcontrollers

/usr/local配下にインストールされるようで、/usr/local/CrossPack-AVRというシンボリックリンクが作成される。
CrossPackインストール後に、avr-projectコマンドを実行することで、XCodeのプロジェクトファイルが生成されるようだ。

$ avr-project avr-LedTest

かなりシンプル…XCodeからいじるのも面倒なので、直接ファイルをいじることにした。
firmwareディレクトリにMakefile、main.cの2つのファイルが生成された。大事なのはこの2つのようだ。

Makefileでライターとマイコンの種類を書き換える必要があるようで、以下のように書き換えた。

DEVICE = attiny2313
PROGRAMMER = -c avrispmkII -P usb -p t2313

makeでプログラムのコンパイル、make flashでマイコンにプログラムを転送させるようだ。make fuseでヒューズの書き換えも可能とのこと。
とりあえず、マイコンにプログラムを転送してみようと思い、デフォルトのままmain.cをコンパイルし、make flashを実行してみたがエラーになってしまう。

// firmwareディレクトリで実行
$ make
avr-gcc -Wall -Os -DF_CPU=8000000 -mmcu=attiny2313 -c main.c -o main.o
avr-gcc -Wall -Os -DF_CPU=8000000 -mmcu=attiny2313 -o main.elf main.o
rm -f main.hex
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
avr-size --format=avr --mcu=attiny2313 main.elf
AVR Memory Usage
----------------
Device: attiny2313
Program:      58 bytes (2.8% Full)
(.text + .data + .bootloader)
Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)
$ make flash
avrdude -c avrispmkII -P usb -p t2313  -U flash:w:main.hex:i
avrdude: stk500v2_command(): command failed
avrdude: stk500v2_program_enable(): bad AVRISPmkII connection status: Target not detected
avrdude: initialization failed, rc=-1
Double check connections and try again, or use -F to override
this check.
avrdude done.  Thank you.
make: *** [flash] Error 1

調べまくった結果、マイコンへの接続の仕方が間違っていたようで、一からコネクタを接続し直してみた。もともと付いていたコネクタと、付け替えたコネクタをよく見比べて繋いでいくと、やはり間違えていた…。
参考サイトを見ながらコネクタの色だけで判断して接続したのがいけなかったようで、しっかり仕様を把握して進めていかなくちゃいけないと反省。
トリパマ Toripama: AVRISPmkII ライタのピンの配列
サンプル・プログラムで学ぶAVRの実践【2/4回目】マイコン書き込み環境の構築 (PIC,78K,R8,HC(S)08/RS08,AVR,MSP430などのマイコン活用)

f:id:happytar0:20120714033630j:plain
こんな感じで接続すると上手くいった。

$ make flash
avrdude -c avrispmkII -P usb -p t2313  -U flash:w:main.hex:i
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e910a
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "main.hex"
avrdude: writing flash (670 bytes):
Writing | ################################################## | 100% 0.28s
avrdude: 670 bytes of flash written
avrdude: verifying flash memory against main.hex:
avrdude: load data flash data from input file main.hex:
avrdude: input file main.hex contains 670 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.20s
avrdude: verifying ...
avrdude: 670 bytes of flash verified
avrdude: safemode: Fuses OK
avrdude done.  Thank you.

ひゃっほー、悩んだ末に解決した時の嬉しさはたまらない!

肝心のLEDを点灯させるプログラムを書いてみることにした。
マイコンを経由してLEDを接続するにはどうすればいいんだと少し考えたが、PD4(ポート8)にLEDと抵抗を接続することで解決。思ったより簡単だった。
サンプルコードはCrossPackのサイトに書いてあったので、それをコピペすればいいだけだ。

#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRD = 1 << 4;           /* make the LED pin an output */
for(;;){
char i;
for(i = 0; i < 10; i++){
_delay_ms(30);  /* max is 262.14 ms / F_CPU in MHz */
}
PORTD ^= 1 << 4;    /* toggle the LED */
}
return 0;               /* never reached */
}

f:id:happytar0:20120714050150j:plain
LEDが点滅してる…肝心の点滅箇所はいともあっさり出来てしまった。
しかしながら、コピペして終わりというのはあまりにもつまらない。
実際はLEDを2つ接続してランダムに交互に点滅を繰り返す、というプログラムを組んだのだが、謎の変数やら関数が出現しているので、次回に詳しく掘り進めていきたいと思う。

電子工作はじめました

ついに電子工作に手を出してみた。やるやる詐欺をすること1年…はじめるまで長かったです。
三日坊主にならないようにコツコツやっていきたいと思う。

電子工作やらマイコンなんてまったく知らない人間なので、まずはLEDを点灯させてみようという事で以下の部品を購入。

  • プログラマ(ライター?) AVR ISP MKII
  • ブレッドボード EIC-108J
  • AVR ATTINY2313-20PU
  • 3mm赤色LED LT3U31P 250mcd
  • カーボン抵抗 1/4W 200Ω
  • カーボン抵抗 1/4W 150Ω
  • 電池ボックス 単3×3本
  • AVRWRT用ブレッドボードISPケーブル

f:id:happytar0:20120704201002j:plain

まずブレッドボードの使い方を覚えるためにLEDを電池ボックスと接続して点灯させてみた。
さすがにこれが出来なかったらやばいよな…と思いつつ、あっさり点灯して安心した。そしてブレッドボードも案外簡単な仕組みだった。

ブレッドボードに150Ωの抵抗とLED、そして電源を接続しただけ。
必要な抵抗は以下の式で求められるようだ。というかオームの法則ってやつだ。
中学の時に習ったけど勉強に熱心ではなかったのですっかり忘れてしまった…。

R(抵抗) = V(電圧) / A(電流)

LEDのスペックは以下のようだ。

Vf=1.85V〜2.5V If=20mA

そして電圧については、電池ボックスに単三乾電池3本ということなので以下になる。

1.5V x 3本 = 4.5V

これをもとに抵抗を計算してみると、

(4.5V - 1.85V) / 0.02A = 132.5Ω

どうやら132Ωくらいの抵抗でちょうどいいようだ。今回は適当なものがなかったので150Ωと念のために200Ωの抵抗を買ってみた。

f:id:happytar0:20120708151644j:plain
無事に点灯した!!全然むずかしい事してないのに嬉しい。
やっぱり形があるものを触って思い通りに動かせると、ソフトをいじるのと違った喜びを感じる。

20mAを越えた電流を流すと壊れると聞いたので、興味本位で抵抗を外してそのまま電源と接続してみた。
f:id:happytar0:20120708151803j:plain
あれ…壊れない。でも弱々しい光り方でなんかおかしい。

とにかく無事?に成功出来てよかった。困った事があれば詳しい先生が居るので心強い。
次はマイコンと接続してLEDの点灯を制御してみたいです。

OpenCVをいじってみた【後編】

前回の記事ではサンプル画像を集めるところまで書いた。
ポジティブサンプルをコツコツ処理するのは面倒なので、opencv_createsamplesコマンドを使って大量のサンプル画像を作ってみた。

opencv_createsamplesを使う

opencv_createsamplesコマンドの使い方は簡単だ。引数なしで実行すると以下のような引数の説明が表示される。

$ opencv_createsamples
Usage: opencv_createsamples
[-info <collection_file_name>]
[-img <image_file_name>]
[-vec <vec_file_name>]
[-bg <background_file_name>]
[-num <number_of_samples = 1000>]
[-bgcolor <background_color = 0>]
[-inv] [-randinv] [-bgthresh <background_color_threshold = 80>]
[-maxidev <max_intensity_deviation = 40>]
[-maxxangle <max_x_rotation_angle = 1.100000>]
[-maxyangle <max_y_rotation_angle = 1.100000>]
[-maxzangle <max_z_rotation_angle = 0.500000>]
[-show [<scale = 4.000000>]]
[-w <sample_width = 24>]
[-h <sample_height = 24>]

「-info」と「-img」はどちらか一方を指定するようで、ネガティブサンプルとポジティブサンプルを組み合わせる場合は「-img」を使用する。
サンプルデータは「-vec」引数で指定したファイルに出力されて、この出力されたサンプルダータをもとに学習処理をおこなう。
「-bg」で指定するネガティブサンプルは、画像ファイルのパスをリスト化したものを指定する。

findコマンドを利用することで簡単に画像ファイルのパスをリスト化することができる。

$ find negative_images/ -name '*.jpg' > negative_images.txt

以下のような引数を指定してサンプルデータを作成した。
「-num」が生成するサンプルデータ数になり、「-bgcolor」は背景とみなす色を指定するようだ。今回は255(白)を指定した。また、「-bgthresh」は背景色とみなす範囲?ということで5を指定してみた。

$ opencv_createsamples -vec positive.vec -img positive_images/1.jpg -bg negative_images.txt -num 7000 -bgcolor 255 -bgthresh 5 -w 24 -h 24

無事にポジティブサンプルの生成に成功したはいいが、これをもとに学習させてみてもいい結果を出すことは出来なかった。
たぶんこの方法でポジティブサンプルを用意する場合、文字など検出対象物として認識しやすいようなものではないとだめなのかもしれない。

地道にポジティブサンプルを集める

やっぱり地道に集めるしかないと思いつつ、なるべく楽に集められないか色々調べてみることにした。
あれこれ調べていると以下のサイトを見つけた。どうやらOpenCVでアニメの顔や目を認識させる、ということをやっているようだ。
anime.udp.jp

ここで公開されている便利な加工ツール「SC」を見つけたので使ってみることにした。ちなみにWindowsアプリのみのようだ。
加工元の画像はネガティブサンプルを集める時と同じように、Yahoo画像検索のAPIを利用して集めた。ひたすらカレーライスだけ切り出すのは正直しんどかった。
そして、色々なカレーライスの画像を見ていくうちに、これを認識させるのはかなり難しいのではないかと思い始めた…。

意外にカレーライスの画像は少なくて、どれも同じような画像が多いので結局800枚ほどしか用意することはできなかった。
これも同じようにopencv_createsamplesコマンドを利用してサンプルデータ化する。先ほどと違うのは、「-img」ではなく、「-info」引数を利用することだ。
「-info」には、「-bg」と同じくリスト化したファイルを指定する。この時に注意したいのは、単純に画像ファイルのパスを指定するだけではなく、「その画像に含まれる検出対象物の数」と「座標」、「大きさ」も書き出す必要があるようだ。

ImageMagickに含まれる「identify」コマンドを使うことで画像の大きさが分かるので、findコマンドと組み合わせて書き出してやればいいようだ。

$ find positive_images/ -name '*.png' -exec identify -format '%i 1 0 0 %w %h' \{\} \; > positive_images.txt
$ opencv_createsamples -vec positive.vec -info positive_images.txt -num 800 -bgcolor 255 -bgthresh 5 -w 24 -h 24

サンプルデータから学習させる

opencv_haartrainingコマンドか、opencv_traincascadeコマンドを利用してサンプルデータを学習させる。opencv_traincascadeコマンドの方が新しいようで、マルチコア対応やLBPにも対応しているのでこちらを利用するのがいいようだ。しかし、学習後に生成されるファイルも新しいフォーマットになるため、opencv_preformanceコマンドで利用することができないようなので注意。

opencv_traincascadeコマンドを引数なしで実行した結果は以下のようになる。

Usage: opencv_traincascade
-data <cascade_dir_name>
-vec <vec_file_name>
-bg <background_file_name>
[-numPos <number_of_positive_samples = 2000>]
[-numNeg <number_of_negative_samples = 1000>]
[-numStages <number_of_stages = 20>]
[-precalcValBufSize <precalculated_vals_buffer_size_in_Mb = 256>]
[-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb = 256>]
[-baseFormatSave]
--cascadeParams--
[-stageType <BOOST(default)>]
[-featureType <{HAAR(default), LBP, HOG}>]
[-w <sampleWidth = 24>]
[-h <sampleHeight = 24>]
--boostParams--
[-bt <{DAB, RAB, LB, GAB(default)}>]
[-minHitRate <min_hit_rate> = 0.995>]
[-maxFalseAlarmRate <max_false_alarm_rate = 0.5>]
[-weightTrimRate <weight_trim_rate = 0.95>]
[-maxDepth <max_depth_of_weak_tree = 1>]
[-maxWeakCount <max_weak_tree_count = 100>]
--haarFeatureParams--
[-mode <BASIC(default) | CORE | ALL
--lbpFeatureParams--
--HOGFeatureParams--

「-data」で指定したパスに分類器が生成される。「-featureType」で学習方法を指定できるが、今回はLBPを利用することにした。

以下のような引数を指定して分類器を作成してみた。
「-numPos」でポジティブサンプルの数を指定するが、バグがあるようできっちり実際の数を指定すると途中で失敗してしまうようだ。実際の数より少なめに指定することで、失敗せずに実行できる。
OpenCV2.4.0でHAAR分類器を学習させるときの問題と対策 (ゆめ技:ゆめみスタッフブログ)

$ opencv_traincascade -data ./data -vec positive.vec -bg negative_images.txt -numPos 750 -numNeg 3000 -numStages 20 -mode ALL -w 24 -h 24 -precalcValBufSize 5000 -precalcIdxBufSize 1000 -featureType LBP

「-data」引数で指定したパスに「cascade.xml」が生成されるので、これが分類器となる。

作った分類器を試してみる

さっそく作った分類器を試してみた。結果からお伝えするとかなり認識率が低い…というかほぼ認識しない。
学習データが少ないのか、やり方が間違っているのか分からない。

OpenCVのサンプルプログラムを利用して作った分類器を試してみた。
引数に認識させたい画像ファイルを指定すると、認識された部分が緑の線で囲われて表示されるものだ。

#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
Mat image = imread(argv[1]);
String cascadeName = "cascade.xml";
CascadeClassifier cascade;
cascade.load(cascadeName);
vector<Rect> komas;
cascade.detectMultiScale(image, komas);
for (vector<Rect>::iterator it=komas.begin(); it!=komas.end(); ++it) {
rectangle(image, Rect( it->x, it->y, it->width, it->height),
Scalar(0,255,0));
}
cout << "count: " << komas.size() << endl;
namedWindow("result", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO);
imshow("result", image);
waitKey(0);
return 0;
}

以下のコマンドでコンパイルして実行した。

$ g++ -I/opt/local/include -L/opt/local/lib -lm -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_objdetect -g -o sample sample.cpp
$ ./sample test.jpg // 実行

結果はというと…。
f:id:happytar0:20120708193503j:plain
一応成功したっぽいけど、もう少し認識率を上げていかないと使いものにならなそう。というか、何に使い道があるんだろ…。

参考サイト
Haar状特徴に基づくブースト分類器のカスケードを利用する高速物体検知 – penny
Tutorial: OpenCV haartraining (Rapid Object Detection With A Cascade of Boosted Classifiers Based on Haar-like Features) – Naotoshi Seo

OpenCVをいじってみた【前編】

しばらくぶりの更新となってしまった…少しずつでも書いていかなきゃだめですね。
物体認識を試してみたかったので有名なOpenCVを使ってみた記録。

OpenCVのインストール

Mac環境なのでMacPortsを利用して、OpenCVとObjectMakerをインストールした。ObjectMarkerは画像から必要な部分を切り出せるツールらしい。

# port install opencv objectmarker

ちなみにWindows環境にもインストールしてみたが少し面倒だった。
ここのインストールガイドを参考にするといいようだ。
InstallGuide – OpenCV Wiki

まず、OpenCVをコンパイルする環境が何も入っていなかったので、
VisualStudioC++ 2010 Expressってのをインストール。
Microsoft Visual Studio Express

CMakeも必要なようなので、以下のサイトからCMakeをインストール。
CMake – Cross Platform Make

CMakeGUIでOpenCVのパスを指定して、Configureを実行することで、VisualStudioで開けるファイルが生成されるようだ。
コンパイラにVisualStudio2010 Win64を指定したところ、Expressバージョンには64bitのコンパイラが含まれていないようで、Windows SDK 7.1のインストールも必要になった。
この際、マルチコア環境ならばTBBを有効化した方がいいと思う。(「USE TBB: ON」にする)

あとは、VisualStudioでOpenCVのプロジェクトファイルを開いてコンパイルするだけ。

物体検出するための分類器を作る

人間の顔や目などを検出するための分類器は、サンプルとしてもう用意されているようで、それらをそのまま使えばいいだけのようだ。
それだと面白くないので、カレーライスを検出する分類器を作ってみることにした。

分類器を作る流れをおおまかに説明すると以下のようになる。

  1. ネガティブサンプル(検出対象物が写っていない画像)を用意する。3000枚ほどあると効率的らしい。
  2. ポジティブサンプル(検出対象物が写っている画像)を用意する。こちらは7000枚ほどあると効率的とのこと…多いな。
  3. opencv_traincascadeコマンドを使って分類器を作る。

ここで問題になってくるのは学習させるための画像をどうやって集めてくるかだ。
あまりよくないかもしれないが、Google画像検索などを利用すればそれほど苦労しないと思う。
他には、opencv_createsamplesコマンドを利用する方法があるようで、ネガティブサンプルと一つのポジティブサンプル画像を組み合わせることで、ポジティブサンプル画像をたくさん作り出すことができるようだ。

サンプル画像を集める

あまり大きい声では言えないが、画像検索を使ってサンプル画像を集めることにした。
さすがに手作業では面倒なため、簡易的なスクリプトを組んで一気に処理しようと思ってAPIがあるか調べて見ることに。

Google Image Search APIというのを見つけたが、ずいぶん昔に廃止されたようだ。
Custom Search APIというのもあるようだが、こちらは使用用途が違うようだし、一日100リクエスト?までのようでだめっぽい。

Yahooを調べたところ、画像検索用のAPIを公開していた。
検索:画像検索API – Yahoo!デベロッパーネットワーク
通常は一日1000リクエストまでだが、プレミアム会員だと5万リクエストに緩和されるらしい。プレミアム会員であったのでこれを利用することにした。
(他にはFlickrAPIを利用するのもアリだと思う)

“風景 -カレーライス”
こんな感じのクエリを投げれば、カレーライスを含まないネガティブサンプル画像を集めることが出来るはずなので、
作ったスクリプトを回して3000枚ほど用意することができた。

ポジティブサンプルの用意が少しむずかしい。
検出対象物を含んだものを用意するのは同じ手順でいいはずだが、対象物のみを切り出す必要があるはずで、それが非常にめんどくさい…。
こういう時のためにopencv_createsamplesコマンドがあるのか?と思って使ってみることにした。

長くなりそうなので今回はこのへんで終わり。。。次回へつづく。