質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

90.50%

  • C++

    4501questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • OpenCV

    1551questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

画像処理(形状検出)

受付中

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,322

despell

score 2

現在2値化された円形・三角形・四角形の図形画像を読み込み, それぞれ円形・三角形・四角形であることを
識別し, 結果を出力するプログラムの課題を製作しています. 
以下のようにそれぞれ画素が255のものをカウントし面積と周囲長を取得しております.
これ以降のアルゴリズムが思いつきません. ご指導お願いします.

//===================================================================
//    ヘッダ・ファイル
//===================================================================
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

#include<iostream>
#include<memory>
#include<vector>

#include<opencv2/opencv.hpp>
#include<opencv2/highgui.hpp>

//===================================================================
//    関数プロトタイプ
//===================================================================
int getsrcArea(cv::Mat src);
long getsrcPer(cv::Mat src);

std::vector< std::vector<int> > grayData;    // グレイデータ

//===================================================================
//    mainエントリーポイント
//===================================================================
int main(int argc, const char* argv[])
{
    int hr = -1;

    cv::Mat    src1, src2, src3;        // 原画像
    cv::Mat dst1, dst2, dst3;

    int src1Area, src2Area, src3Area;    // 面積
    long src1Per, src2Per, src3Per;        // 周囲長

    try
    {
        //------------------------------------------------------
        //    画像読み込み
        //------------------------------------------------------
        src1 = cv::imread("../image/Figure1.bmp", CV_LOAD_IMAGE_GRAYSCALE);
        src2 = cv::imread("../image/Figure2.bmp", CV_LOAD_IMAGE_GRAYSCALE);
        src3 = cv::imread("../image/Figure3.bmp", CV_LOAD_IMAGE_GRAYSCALE);

        //------------------------------------------------------
        //    面積・周囲長取得
        //------------------------------------------------------
        src1Area = getsrcArea(src1);
        src2Area = getsrcArea(src2);
        src3Area = getsrcArea(src3);

        src1Per = getsrcPer(src1);

        //------------------------------------------------------
        //    画像描画
        //------------------------------------------------------
        cv::imshow("Source1", src1);    // 原画像
        cv::imshow("Source2", src2);    // 原画像
        cv::imshow("Source3", src3);    // 原画像

        cv::waitKey(0);

        hr = 0;
    }

    //------------------------------------------------------
    //    エラー処理(OpecvCV用)
    //------------------------------------------------------
    catch (cv::Exception ex)
    {
        std::cout << ex.err << std::endl;
    }

    //------------------------------------------------------
    //    ウィンドウ破棄
    //------------------------------------------------------
    cv::destroyAllWindows();

    return hr;
}

//===================================================================
//    面積取得
//===================================================================
int getsrcArea(cv::Mat src)
{
    int Width, Height;
    int areaCount = 0;

    Height = src.rows;
    Width = src.cols;

    // 動的2次元配列確保
    grayData.resize(Height);
    for (int i = 0; i < Height; i++) {
        grayData[i].resize(Width);
    }

    // グレイデータ画素値取得
    for (int y = 0; y < Height; y++) {
        for (int x = 0; x < Width; x++) {
            grayData[y][x] = src.at<unsigned char>(y, x);
        }
    }

    for (int y = 0; y < Height; y++) {
        for (int x = 0; x < Width; x++) {
            if (grayData[y][x] == 255)    areaCount++;
        }
    }

    return areaCount;
}

//===================================================================
//    周囲長取得
//===================================================================
long getsrcPer(cv::Mat src)
{
    long side = 0;        // 縦・横
    long slant = 0;        // 斜め
    long length;

    int Width, Height;

    Height = src.rows;
    Width = src.cols;

    for (int y = 1; y <= Height - 2; y++) {
        for (int x = 1; x <= Width - 2; x++) {
            if (grayData[y][x] == 255) {
                if ((grayData[y][x - 1] = 255) || (grayData[y][x + 1] = 255) || (grayData[y - 1][x] = 255) || (grayData[y + 1][x] = 255)) {
                    side = side + 1;
                }
                else if ((grayData[y - 1][x - 1] = 255) || (grayData[y - 1][x + 1] = 255) || (grayData[y + 1][x - 1] = 255) || (grayData[y + 1][x + 1] = 255)) {
                    slant = slant + 1;
                }
            }
        }
    }

    length = (int)(side + sqrt(2) * slant);

    return length;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

0

※ 回答ではありません。

面積と周囲長を求めたのはナゼなんです? 
そのふたつから形状が判別できる見込みがあったからじゃないんですか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

それぞれ円形・三角形・四角形であることを識別

輪郭抽出(findContours)の後に、

  • 最小円(minEnclosingCircle)面積と領域面積の比から「円形」を識別
  • 直線近似(approxPolyDP)適用後の最小矩形(minAreaRect)と輪郭頂点座標の比較から「三角形」ないし「四角形」を識別

ができる気がします。アルゴリズム素案の提案まで。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • C++

    4501questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • OpenCV

    1551questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。