フルーツを色で覚える

コンピュータがフルーツの色を記憶して、果物の名前を当てます。

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

色を記憶

  1. ラーニングと呼ぶには「おこがましい」のですが、フルーツの色を記憶して、果物の名前を当てます。
    画像の色は三原色(RGB)の組み合わせで構成されています。
    Sum_Color(); 関数を実行すると、画像の色調が0%~100%で得られます。
    得られた RGB 毎のレベルを 0~9, 10~19, 20~29, ・・・ 90~99 の10段階に分けます。
    RGB のいずれかが 100%(そんな果物は無い)と思われるので、分割の都合で 100 は除外します。
    もしあれば「配列の範囲外」でプログラムがダウンするのでしょうか。 (^_^;)
        int     color_t[10][10][10];
    
  2. ImageAI Class は Version-2 を使って下さい。
    Main.cpp では、次の領域を定義して下さい。
    "c:\\data\\test\\fruit_list.bmp" はページ先頭の名前を選ぶ画像です。
    flag は fruit_list.bmp から正しい果物の名前を選ぶときのフラグです。
    r, g, b は color_t の Index です。
    HINSTANCE   g_hInst;
    HWND        g_hWnd;
    HDC         hdc;
    IMAGEAI     *ImageAI= NULL;     // IMAGE-AI Object Class
    BOOL        flag= false;
    char        ImgFile[]= "c:\\data\\test\\fruit_list.bmp";
    LPCTSTR str[]=
    { "★不明",  "りんご",  "みかん",  "バナナ",  "いちご",
      "パイナップル",  "キウイフルーツ",  "レモン",
    };
    int         color_t[10][10][10];
    int         r, g, b;
    WORD        yp;
    
  3. Main.cpp の AppInit() から OpenFile() で画像ファイルを選択します。
    InitDib() で DibStruct を初期化して下さい。
    color_t[10][10][10]; を初期化して「1 りんご, 2 みかん」を登録します。
    // 画像をロードして、24bit DIB を作成
    LRESULT  AppInit(HWND hwnd)
    {
        ImageAI= new IMAGEAI(hwnd);
        if (ImageAI->OpenFile()==false) return false;
        ImageAI->Adjust(false);
        ImageAI->InitDib();
        ImageAI->Show(ImageAI->Dib.hBmpDC, 0, 0);
        for (r = 0; r < 10; r++)
            for (g = 0; g < 10; g++)
                for (b = 0; b < 10; b++)    color_t[r][g][b] = 0;
        color_t[2][2][5] = 1;
        color_t[0][2][6] = 2;
        return true;
    }
    
  4. WM_PAINT では flag が true のときは果物の名前を選択する画像を、false のときは果物の画像を描画します。
            case WM_PAINT:          // Dib の画像を描画
                hdc = BeginPaint(hWnd,&ps);
                if (ImageAI)
                {   if (flag)   ImageAI->Show(hdc,0,0);
                    else    ImageAI->ShowDib(hdc,0,0);
                }
                EndPaint(hWnd, &ps);
                break;
    
  5. WM_LBUTTONDOWN: では flag が true のときはページ先頭の画像から果物の名前を選択します。
    1. yp= HIWORD(lp)/50; でクリックされた画像テーブルの Index を取得して color_t[b][g][r] に設定します。
    2. color_t に設定すると、次回から果物を認識できるようになります。
    3. OpenFile() で次のフルーツ画像を入力します。
    false のときは Sum_Color(); で画像の色調を取得して果物の種類を判定します。
    1. Del_Color() 関数で背景色を削除します。
    2. Sum_Color() 関数で画像の色調を調べます。
    3. RGB を「1/10 にした添え字」で color_t から果物の名前を取得します。
    4. MessageBox() で果物の名前を確認します。
    5. 名前が未定義(または間違い)のときは CANCEL を応答します。
    6. CANCEL が応答されると flag を true に設定して、果物の名前を選択する画像をロードします。
            case WM_LBUTTONDOWN:    // 左ボタンをクリック
                if (flag)
                {   yp= HIWORD(lp)/50;
                    DebugWORD("Y:", yp);
                    flag= false;
                    color_t[b][g][r] = yp;
                    if (ImageAI->OpenFile() == false)   return false;
                    ImageAI->InitDib();
                    ImageAI->SetRGB(7);
                    InvalidateRect(hWnd, NULL, FALSE);
                    break;
                }
                ImageAI->Del_Color(0,0,100);
                ImageAI->Sum_Color();
                b = (int)ImageAI->rgb[0]/10;
                g = (int)ImageAI->rgb[1]/10;
                r = (int)ImageAI->rgb[2]/10;
                id= MessageBox(hWnd, str[color_t[b][g][r]], (LPCSTR)"合ってますか", MB_OKCANCEL);
                if (id!=IDOK)
                {   flag= true;
                    ImageAI->LoadBmp(ImgFile);
                }
                InvalidateRect(hWnd,NULL,FALSE);
                break;
    
  6. WM_RBUTTONDOWN: では OpenFile() で次の画像を入力します。
            case WM_RBUTTONDOWN:    // 右ボタンをクリック
                if (ImageAI->OpenFile()==false) return false;
                ImageAI->InitDib();
                ImageAI->SetRGB(7);
                InvalidateRect(hWnd,NULL,FALSE);
                break;
    
  7. プログラムを起動して「りんご, みかん」の画像を入力して下さい。
    事前に登録されているので、正しく認識されるはずです。
  8. 「ばなな」の画像を入力すると、登録されていない果物なので「★不明」が表示されます。

    CANCEL を応答して、名前の画像から「ばなな」をクリックします。
    次回からは「ばなな」が認識されます。
  9. 「レモン」の画像を入力すると「★不明」が表示されます。

    CANCEL を応答して、名前の画像から「レモン」をクリックします。
    次回からは「レモン」が認識されます。
  10. 「みかん, バナナ, レモン」の黄色い果物を3個用意したのですが、同じ黄色でも色調が異なり認識できるようです。
    また同じ果物でも画像が異なれば認識できないかも知れません。
    様々な画像を与えて覚えこませて下さい。
    果物を色だけで識別するには無理がありますが、候補を絞り込む役には立ちそうです。
    複数の候補があるときは、次の段階として「サイズ, 形, 特徴, つや, におい」などを利用することを考えます。

[Next Chapter ↓] クリックした果物を当てる
[Previous Chapter ↑] りんご, バナナ, みかん

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