深層学習対応バージョンの認識メソッド
以下の点を改良した。
なお、深層学習パラメータは、旧OCRエンジンのシステム辞書と同じフォルダにあるものとする。
また、深層学習対応認識だけを使う場合も、言語辞書やユーザーパターン辞書への登録の関係で旧OCRの辞書は必要となる。
- 旧エンジン+深層学習対応エンジンハイブリッド認識
フラグ指定によってハイブリッド認識を行います。
今までの運用中に登録したユーザーパターン辞書を利用することができます。
- 深層学習対応エンジン認識
旧OCRエンジンは使いません。
今までの運用中に登録したユーザーパターン辞書を利用することはできません。
- 深層学習対応言語処理(リリース時期は2023年第1四半期予定)
旧OCRエンジンの言語処理は継続利用できます。
深層学習を使わない旧OCRエンジン認識、旧エンジンとのハイブリッド認識でも使うことができます。
- グレイスケール対応認識
msetdocument8()メソッドでグレイスケールドキュメントを設定することができます。
深層学習対応認識を使うにはグレイスケールあるいはカラードキュメントの設定を推奨します。
モノクロ2値画像でも深層学習対応認識を使うことはできます。
- カラー画像対応認識
msetdocument24()メソッドで24bitカラードキュメントを設定することができます。
深層学習対応認識を使うにはグレイスケールあるいはカラードキュメントの設定を推奨します。
- ハイブリッド認識
CJocrBlockクラスで msetsprecognizeflag2によって、BLOCK_DNNASSISTを設定する。
まず旧OCRエンジンで認識して、認識結果の第1候補の確信度がmsetminscoreで設定した値以上の場合は旧OCRエンジンの結果をそのまま利用する。
確信度がmsetminscore未満の場合は、深層学習によって再認識して、その結果を採用する。
msetminscore APIで設定しない場合の、再認識する確信度は90となっている。90より増やすと旧OCRエンジンの結果の採用が減り、深層学習エンジンの結果の採用が増える。
また、旧OCRエンジンの方が高速なので、90より増やすと認識速度は遅くなる。精度は深層学習エンジンの方が高いので向上する。
90より減らすと旧OCRエンジンの結果の採用が増え、深層学習エンジンの結果の採用が減り、認識速度は速くなるが精度が下がる。
- 深層学習対応エンジンのみで認識
CJocrBlockクラスで msetsprecognizeflag2によって、BLOCK_DNNONLYを設定する。全て深層学習によって認識して、その結果を採用する。
msetsprecognizeflag2で深層学習を利用すると設定した後に、msetdocument/msetdocument8/msetdocument24によってドキュメントを設定する。深層学習認識にはグレイスケールドキュメントが必要となる。
msetdocumentでモノクロ2値ドキュメントが設定された場合は、CJocrBlockクラス内部でグレイスケールドキュメントが生成される。
msetdocument24でカラードキュメントが設定された場合も、CJocrBlockクラス内部でグレイスケールドキュメントが生成される。
また、旧OCRエンジンを使う場合は、モノクロ2値画像が必要となるため、msetdocument8/msetdocument24を使っている場合、グレイスケールドキュメントからモノクロ2値画像が生成される。
// フラグ設定(msetsprecognizeflag/mgetsprecognizeflagがオーバーフローしたため)
// 入力
// int flag; // ( in)flag BLOCK_TATEGAKIGYU(cjocrblock.h)
// // BLOCK_DNNONLY(ocrdef.h) 深層学習エンジンのみで認識する
// // BLOCK_DNNASSIST(ocrdef.h) 旧エンジンでまず認識。確信度が低いものだけ深層学習エンジンで認識
void msetsprecognizeflag2(int flag = 0) {msprecognizeflag2 = flag;}
int mgetsprecognizeflag2() {return msprecognizeflag2;}
// 深層学習と旧エンジンを切り替えるしきい値の設定
// int score; // ( in)score BLOCK_DNNASSISTの場合にscore以下の確信度の場合だけ深層学習エンジンで再認識
// scoreの範囲は75〜95くらいを推奨(デフォルト値は85)
void msetmindnnscore(int score)
{
mindnnscore = score;
}
// 深層学習と旧エンジンを切り替えるしきい値の取得(BLOCK_DNNASSISTの場合だけ
int mgetmindnnscore() {return mindnnscore;}
// 注意:msetdocument8/msetdocument24は必ずBLOCK_DNNONLY/BLOCK_DNNASSISTを設定していから呼び出すこと
// unsigned char* pdata; // ( in)1画素8bitグレイスケール画像バッファ
// pdataは呼び出し側(アプリケーション側)で確保。一連の処理が完了するまで解放してはならない
// int width; // ( in)画像の幅(単位ピクセル)
// int scanlinesize; // ( in)画像の1行のバイト数(単位バイト)
// int height; // ( in)画像の高さ(単位ピクセル)
// 戻り値
// 0.....正常終了
// 負....エラーコード(エラー種別は errcode.h 参照)
int msetdocument8(unsigned char* pdata,int width,int scanlinesize,int height);
// unsigned char* pdata; // ( in)1画素24bitカラー画像バッファ
// pdataは呼び出し側(アプリケーション側)で確保。一連の処理が完了するまで解放してはならない
// int width; // ( in)画像の幅(単位ピクセル)
// int scanlinesize; // ( in)画像の1行のバイト数(単位バイト)
// int height; // ( in)画像の高さ(単位ピクセル)
// 戻り値
// 0.....正常終了
// 負....エラーコード(エラー種別は errcode.h 参照)
int msetdocument24(unsigned char* pdata,int width,int scanlinesize,int height);
例
#include "ocrdef.h"
#include "ocrco.h"
#include "cjocrstock.h"
#include "cjocrdict98.h"
#include "cjocrpat98.h"
#include "cjocrrec98.h"
#include "cjocrline98.h"
#include "cjocrlang.h"
#include "cjocrblock.h"
#include "errcode.h"
...
....
// パターンクラス作成
CJocrPattern* pattern = new CJocrPattern;
int ret = pattern->mallocmemory();
if(ret < 0) {
printf("パターンクラスメモリ確保エラー");
delete pattern;
exit(1);
}
// 辞書クラス作成
CJocrDict* pjocrdict = new CJocrDict;
// 深層学習のパラメータもシステム辞書と同じフォルダに格納されていることが前提となる
pjocrdict->msetsystemdict("c:\\dic\\feature\\system");
pjocrdict->msetsystemdict("c:\\dic\\feature\\systemfat");
pjocrdict->msetuserdict("c:\\dic\\feature\\user");
ret = pjocrdict->mloaddict();
if(ret < 0) {
printf("エラー");
delete pjocrdict;
delete pattern;
exit(1);
}
// 1文字認識クラス作成
CJocrRecognize* precognize = new CJocrRecognize;
precognize->msetpatter(pattern);
precognize->msetdict(pjocrdict);
// 1文字認識クラスの初期化
ret = precognize->mallocmemory();
if(ret < 0) {
printf("エラー");
delete precognize;
delete pjocrdict;
delete pattern;
exit(1);
}
// 言語処理付き1行認識クラス作成
CJocrLang* pjocrlang = new CJocrLang;
pjocrlang->msetpatter(pattern);
pjocrlang->msetrecognize(precognize);
// 1段落認識クラス作成
CJocrBlock* pjocrblock = new CJocrBlock;
pjocrblock->msetlang(pjocrlang);
pjocrblock->msetprocess(PREPROCESS_INSIDE); // 枠に接触するプリミティブを除く
// --------- 深層学習対応ここから ------------
pjocrblock->msetsprecognizeflag2(pjocrblock->mgetsprecognizeflag2() | BLOCK_DNNASSIST); // ハイブリッド認識
// pjocrblock->msetsprecognizeflag2(pjocrblock->mgetsprecognizeflag2() | BLOCK_DNNONLY); // 深層学習だけ使う認識
// 深層学習と旧エンジンを切り替えるしきい値の設定
// int score; // ( in)score BLOCK_DNNASSISTの場合にscore以下の確信度の場合だけ深層学習エンジンで再認識(初期値は85)
pjocrblock->msetmindnnscore(80);
// pjocrblock->msetgray2monoparameter(0,64,80.0); // アプリ側で2値化を行う場合(後でpjocrblock->msetdocument(pdata,mwidth,mheight)が必要) 第2、第3引数は適当
// pjocrblock->msetgray2monoparameter(1,64,80.0); // 初期値はこれ、ライブラリ内部で大津の方法で2値化を行う場合 第2、第3引数は適当
pjocrblock->msetgray2monoparameter(2,64,80.0); // ライブラリ内部でシェーディング補正2値化を行う場合
// ドキュメントの設定
pjocrblock->msetdocument8(mgraydata,mwidth,mgrayscanlinesize,mheight); // 8bitグレイスケールの場合
// pjocrblock->msetdocument24(mgraydata,mwidth,mgrayscanlinesize,mheight); // 24bitカラーの場合
// --------- 深層学習対応ここまで ------------
// ドキュメントの設定
// pjocrblock->msetdocument(mdata,mwidth,mheight); // アプリ側で2値化したものを使う場合はコメントを外す
pjocrblock->msetdpi(400); // 解像度400dpi
// 段落の設定
// ブロックの設定
OCRBlock ocrblock;
ocrblock.baseline.x1 = 100;
ocrblock.baseline.y1 = 100;
ocrblock.baseline.x2 = 300;
ocrblock.baseline.y2 = 200;
ocrblock.thickness = 100;
// ベースラインは(100,100)-(300,200)
// 行高は100
// 背景0
// 横書きのブロックを設定
pjocrblock->msetblock(ocrblock,atan2(ocrblock.baseline.y2 - ocrblock.baseline.y1,ocrblock.baseline.x2 - ocrblock.baseline.x1),0,0);
// 正規化画像の作成
ret = pjocrblock->mregularize();
if(ret < 0) {
printf("エラー");
delete pjocrblock;
delete pjocrlang;
delete precognize;
delete pjocrdict;
delete pattern;
exit(1);
}
// 1段落認識
pjocrblock->msetunderlineflag(1); // アンダーライン処理を行う場合
ret = pjocrblock->mrecognizecluster(CHAR_SET_ALL,0); // 全文字種を対象に認識
if(ret < 0) {
printf("エラー");
delete pjocrblock;
delete pjocrlang;
delete precognize;
delete pjocrdict;
delete pattern;
exit(1);
}
// 認識結果取得
int resultnum;
mgetresult(resultnum,NULL);
// result×sizeof(OCRResult)のバッファを確保する
OCRResult* pocrresult = malloc(sizeof(OCRResult) * resultnum);
if(pocrresult) {
pjocrblock->mgetresult(resultnum,pocrresult);
}
// pocrresult[i].cand[0].codeには各文字の認識結果あるいは
// 行区切りとしての改行コード0x0d,0x0aが入っている。
....
...
..
delete pjocrblock;
delete pjocrlang;
delete precognize;
delete pjocrdict;
delete pattern;