りんご, みかん, バナナ

「りんご, みかん, バナナ」の画像を認識します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

画像を認識

  1. 「りんご, みかん, バナナ」の三枚の画像を入力して、何の果物かを当てます。
    BMP 画像の横幅(Width)は【8の倍数】に合わせて下さい。
    画像認識の初歩の初歩で、人間では一目でわかる果物の種類もコンピュータでは一苦労です。
    果物は縦または横方向に置かれているものとします。
    事前に果物の画像も答えも知らされていて、これ以上簡単な問題はありません。
    ImageAI Class は Version-2 を使って下さい。
  2. ImageAI Class Version-2 の画像解析を利用して果物を当てます。
    1. 最初の階層として、色で判定してみましょう。
      赤いのは「りんご」で黄色いのは「みかん, バナナ」です。
      色の判定は背景色を削除して RGB が使われている度合いを求めます。
      見た目では「みかん」は黄色ですが R(赤)の値が最も大きいのは「みかん」です。
      果物 B(青) G(緑) R(赤)
      りんご 25 23 51
      みかん 8 27 63
      バナナ 22 38 39
      三種類とも R(赤)が多く使われています。
      「りんご」の決め手は B(青)とG(緑)の比率でしょうか?
    2. 次の階層として、形(丸いのはみかん)で判定してみましょう。
      形の判定は背景色を削除して、物体の幅と高さから求めます。
      幅と高さの比率が小さいと「丸い」ことが解ります。
      果物 高さ
      りんご 281 327
      みかん 282 334
      バナナ 341 169
    3. それ以外は「バナナ」です。
  3. Main.cpp の AppInit() から OpenFile() で画像ファイルを選択します。
    InitDib() で DibStruct を初期化して下さい。
    Show(ImageAI->Dib.hBmpDC, 0, 0) で入力した画像を Dib.hBmpDC に転送します。
    // 画像をロードして、24bit DIB を作成
    LRESULT  AppInit(HWND hwnd)
    {
        ImageAI= new IMAGEAI(hwnd);
        if (ImageAI->OpenFile()==false) return false;
        ImageAI->InitDib();
        ImageAI->Show(ImageAI->Dib.hBmpDC, 0, 0);
        return true;
    }
    
  4. WM_PAINT では ShowDib() で Dib.hBmpDC の画像を描画します。
            case WM_PAINT:          // Dib の画像を描画
                hdc = BeginPaint(hWnd,&ps);
                if (ImageAI)   ImageAI->ShowDib(hdc,30,20);
                EndPaint(hWnd, &ps);
                break;
    
  5. WM_LBUTTONDOWN: では、Del_Color(0,0,100) で背景色を削除します。
    座標 0,0 のピクセルで、閾値は 100 が適しているようです。
    Sum_Color() で画像全体の色調と Get_Size() で物体のサイズを調べます。
    画像の色調と果物の幅と高さで、果物の種類を判定します。
            case WM_LBUTTONDOWN:    // 左ボタンをクリック
                ImageAI->Del_Color(0,0,100);
                ImageAI->Sum_Color();
                ImageAI->Get_Size();
                // りんごを認識
                wk= (ImageAI->rgb[1]*100)/ImageAI->rgb[0];
                if (wk>80 && wk<120)    MessageBox(NULL,"「りんご」です","Message Box",MB_OK);
                else
                {   wk = (ImageAI->height * 100) / ImageAI->width;
                    if (wk > 80)  MessageBox(NULL, "「みかん」です", "Message Box", MB_OK);
                    else    MessageBox(NULL, "「バナナ」です", "Message Box", MB_OK);
                }
                InvalidateRect(hWnd,NULL,FALSE);
                break;
    
  6. WM_RBUTTONDOWN: では OpenFile() で別の画像を入力します。
    SetRGB(7) に代えて Show(ImageAI->Dib.hBmpDC, 0, 0) を使っても同じです。
            case WM_RBUTTONDOWN:    // 右ボタンをクリック
                if (ImageAI->OpenFile()==false) return false;
                ImageAI->InitDib();
                ImageAI->SetRGB(7);
                InvalidateRect(hWnd,NULL,FALSE);
                break;
    
  7. OpenFile() から「レモン」の画像を入力して下さい。
    レモンは「りんご」の決め手「B(青)とG(緑)の比率」には該当しません。
    また「みかん」の決め手「wk > 80」にも該当しません。
    従って「バナナ」と認識されてしまいます。
    課題として「レモン」が認識できるようにプログラムを改良して下さい。

[Next Chapter ↓] フルーツを色で覚える
[Previous Chapter ↑] 画像解析ガイド

超初心者のプログラム入門(Win32API C++)