🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2912閲覧

png画像の解析処理「文字認識とその位置、画像の認識とその位置」を知りたい

Yamamin

総合スコア18

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/03/10 01:05

編集2021/03/10 02:39

以下のような画像があります。

イメージ説明

認定済みか、申請中のどちらかに〇がついているのですが、どちらに〇がついているのか判別する実装方法はありますでしょうか?形式は「png」です。
C#で実装しているのですが、Pythonで実装して結果をC#に読み込んだりするやり方でも構いません。

C#で「Tesseract.Net SDK」使って文字読み取って認識する。ところまでは調べたのですが、〇がついているかまで解析するやり方ってあるんでしょうか?

C#やPythonで使用できるライブラリーなどはあったりしますでしょうか?

追記:
「認定済み」および「申請中」という文字の認識とその位置、〇の画像の認識とその位置がわかれば、組めるかもしれません。
今、Pythonの「OpenCV、pyocr/Tesseract-OCR」あたりで出来るのではないかと調べています。質問の内容も曖昧だったようで失礼しました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yamamin

2021/03/10 01:23

かしこまりました。もう少し編集します。
fana

2021/03/10 02:26

相手にする画像がどんなものか?という話の前提がどこまでなのか? を示す必要があるかと思います. 例えば, 【「認定済」と「申請中」は四角い枠で囲まれていて,前者は枠内の左側に,後者は枠内の右側に位置する】といった前提を設けて良いならば,文字を認識する必要は無く,丸が左右のどっち側にあるかだけから判断すればよいかもしれません.
Yamamin

2021/03/10 02:37

ご回答ありがとうございます。紙をスキャンしたデータで、他の情報も入っているので位置だけでは心もとないかもしれません。「認定済み」および「申請中」という文字の認識とその位置、〇の画像の認識とその位置がわかれば、組めるかもしれません。 今、Pythonの「OpenCV、pyocr/Tesseract-OCR」あたりで出来るのではないかと調べています。質問の内容も曖昧だったようで失礼しました。
hoshi-takanori

2021/03/10 02:55

認定済と申請中の文字は印刷で、⚪︎は手書きか判子で、紙をスキャンしたものを認識したいということでしょうか? 印刷なら文字の場所を探すのは何とかなりそうな気もしますが、スキャンの時に傾いたり上下が逆だったり濃さが違ったり、いろいろあるのでしょうね…。
Yamamin

2021/03/10 03:35

ご回答ありがとうございます。 >⚪︎は手書きか判子で、紙をスキャンしたものを認識したいということでしょうか? その通りです。今、Pythonで出来ないか試しています。
fana

2021/03/10 03:39

利用可能ないくつかの前提知識を用いて 最終的な判断処理(どっちに〇がついているかを判断する)をシンプルにするための前処理を用意できないか?を考えてみてはどうでしょう. 例えば, 特定のフォーマットの用紙をスキャンする状況で,「認定済」のような文字が手書きではなく印刷なのであれば, 前述した「丸が左右のどっち側にあるかだけから判断」といったようなシンプルな形に持っていくことは不可能ではないように思えます. 用紙のフォーマットが既知であれば,見るべき箇所が画像のどのあたりにあるハズなのかはわかっています. 用紙にある程度の罫線が存在するならば,それを利用することで,スキャン時の用紙の傾きを補正することもできるでしょう. 「認定済」「申請中」が印刷されたものであるならば,OCRを持ち出して文字を認識せずとも,画像パターンの探索で済むように思えます.
fana

2021/03/10 03:47 編集

…といったことが可能であれば,最終的には,「質問に提示されたような画像から〇がどこについているかを判断する」という話に持っていけるでしょう. (着目範囲が絞り込めている=用紙の他の部分は見なくて良く,スキャンの傾きは概ね解消されており,範囲内の「認証済」「申請中」の位置も概ね分かっている状況) この段では,〇がハンコ(サイズや形のブレが少ないと期待できる)なのか手書き(サイズや形のブレが大きいかもしれない)なのか,どちらの場合もあり得るのか,といった前提によって,考えるべきことは変わるかもしれません.
YAmaGNZ

2021/03/10 04:12

なんらかの印のついているものを検出するのであれば、印の付いていない画像と比較してその差異の量で判断できたりしませんかね?
guest

回答1

0

ベストアンサー

とりあえず,質問に提示された画像から,その〇の位置を探すとしたら,
下記に示すような,あきれるほど単純な処理でも十分であろうと思います.

(下記コードはOpenCVを使用しており,C#でOpenCVを使ったことが無いのでC++で書いていますが)

C++

1int main() 2{ 3 //(ここは画像の読み込み処理です) 4 cv::Mat Img = cv::imread( "Check.png", cv::IMREAD_GRAYSCALE ); 5 if( Img.empty() )return 0; 6 7 //円の半径[pixel](太いので2種類) 8 const int r1 = 30; 9 const int r2 = 33; 10 //↑の2乗値 11 const int Sq_r1 = r1*r1; 12 const int Sq_r2 = r2*r2; 13 14 //画像内を走査し, 15 //各着目画素位置(cx,cy)において,(cx,cy)からの距離が r1~r2 である画素の色を調べて, 16 //黒い画素の個数をカウントする. 17 //最もカウント数が多い箇所を〇の中心だと判定する. 18 int BestCx = -1; 19 int BestCy = -1; 20 int BestScore = 0; 21 22 for( int cy=r2; cy+r2<Img.rows; ++cy ) 23 { 24 for( int cx=r2; cx+r2<Img.cols; ++cx ) 25 { 26 int score = 0; //黒い画素個数カウンタ 27 for( int dy=-r2; dy<=r2; ++dy ) 28 { 29 const int Sq_dy = dy*dy; 30 const int y = cy + dy; 31 const unsigned char *pI = Img.ptr<unsigned char>( y ); 32 for( int dx=-r2; dx<=r2; ++dx ) 33 { 34 const int Sq_dx = dx*dx; 35 const int Sq_r = Sq_dx + Sq_dy; 36 if( Sq_r < Sq_r1 || Sq_r2 < Sq_r )continue; 37 38 if( pI[ cx+dx ]<128 ){ ++score; } //画素(x,y)が黒いかどうか 39 } 40 } 41 42 if( score > BestScore ) 43 { 44 BestScore = score; 45 BestCx = cx; 46 BestCy = cy; 47 } 48 } 49 } 50 51 {//結果表示:赤〇を描画して示す 52 cv::Mat ShowImg( Img.size(), CV_8UC3 ); 53 cv::cvtColor( Img, ShowImg, CV_GRAY2BGR ); 54 55 cv::circle( ShowImg, cv::Point(BestCx,BestCy), (r1+r2)/2, cv::Scalar(0,0,255), 2 ); 56 cv::imshow( "Result", ShowImg ); 57 if( cv::waitKey() == 's' ) 58 { cv::imwrite( "Result.png", ShowImg ); } 59 } 60 61 return 0; 62}

結果:
イメージ説明

投稿2021/03/10 04:14

fana

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yamamin

2021/03/10 14:02

ご回答ありがとうございます。上記の方法でPythonのOpenCVがあったので出来ました。文字は同じくPythonを使って「tesseract + pyocr」の組み合わせで文字認識と、文字を位置を取得することが出来ました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問