名称 |
MIRS1202 OpenCVによる数字認識 |
番号 |
MIRS1202-PLAN-0002 |
最終更新・2012.10.20
版数 |
最終更新日 |
作成 |
承認 |
改訂記事 |
A01 |
2012.10.20 |
前川恵哉 |
|
初版 |
目次
1.目的
-
本ドキュメントは、MIRS1202の数字認識プログラムについて記したドキュメントである。
2.プログラム概要
-
数字認識プログラムはMIRS0901班の数字認識プログラムを改良して使用する。
以下に、数字認識プログラムのフローチャートを載せる
フローチャート
フローチャート(変更後)
この数字認識プログラムはROI走査法を使用している。
- 各関数の内容
cv_main.c(main関数)
img_update.c(標準)
(img_update関数)
threshold.c
(threshold関数)
labeling.c
(labeling関数、gettrim関数、triming関数)
noisecut.c
(noisecut関数)
select_number.c
(select_number関数)
3.改良点
-
0901班の数字認識プログラムだけでは画像内に数字が写っていてもラべリングを行う際に誤動作が起きる場合がある。
以下に誤動作の例と対処方法を述べる。
上の図では離れた場所の領域も同じ領域と判断してしまい数字と認識してしまっている。
これはラべリングが行われる際に振り分けられた番号が移動するときに起きてしまう。
これを改善するために、labeling.cの86行目に以下の3行のプログラムを追加した。
for(j=0;j<LABEL_MAX;j++){
if(table[j][1]==sousa[i])
table[j][1]=min;
}
元のプログラムでは、2番目と3番目に大きい面積の領域を数字と認識する。しかし上の図では数字の面積は3番目と4番目に大きい領域となっている。
これを改善するためにlabeling.cのgettrim関数に以下のプログラムを追加する。
また、gettrim関数をint型に変え、ラべリングした領域が枠に達している場合エラーの値が戻るようにした。
if(x1==0)
return -1;
if(y1==0)
return -1;
if(x2==319)
return -1;
if(y2==239)
return -1;
gettrim関数からエラー値が戻ってきた場合、以下のプログラムを追加してlabeling関数で4番目に大きい領域を数字として認識する仕様にした。
CvRect rect1,rect2;
if(gettrim(dst1,&rect1)==-1){
for(x=0;x<src->width;x++){//"ラベルイメージの初期化"
for(y=0;y<src->height;y++){
dst1->imageData[dst1->widthStep*y+x]=0;
}
}
for(y=0;y<src->height;y++){
for(x=0;x<src->width;x++){
if(label_true[x][y]==nnnmax_num)dst1->imageData[dst1->widthStep*y+x]=255;
}
}
}
if(gettrim(dst2,&rect2)==-1){
for(x=0;x<src->width;x++){//"ラベルイメージの初期化"
for(y=0;y<src->height;y++){
dst2->imageData[dst2->widthStep*y+x]=0;
}
}
for(y=0;y<src->height;y++){
for(x=0;x<src->width;x++){
if(label_true[x][y]==nnnmax_num)dst2->imageData[dst2->widthStep*y+x]=255;
}
}
}
班ごとの独自開発によりカメラを新しくしたのでそのために
4.改良点(カメラ変更後)
- カメラを変更するとuvccaptureで画像を取得できなくなったのでopencvライブラリの関数を使い画像を取得するプログラムを作成した。img_update.c
(画像取得関数)
(以下参考画像)
- 取得画像が大きく数字認識に10秒程度の時間を使うので、画像の上下をある程度、切り取りして画像のサイズを小さくした。(以下参考画像)
- 外枠に触れる領域を無視することでいらない領域を除外する。逆に数字の領域が外枠に触れていると数字認識を失敗する。(以下参考画像)
5. 関連文書
沼津工業高等専門学校 電子制御工学科