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

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

新規登録して質問してみよう
ただいま回答率
85.48%
OpenCV

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

C++

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

Q&A

2回答

1333閲覧

画像処理(形状検出)

despell

総合スコア10

OpenCV

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

C++

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

0グッド

0クリップ

投稿2018/02/20 09:32

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

c++

1//=================================================================== 2// ヘッダ・ファイル 3//=================================================================== 4#include<stdio.h> 5#include<stdlib.h> 6#include<math.h> 7 8#include<iostream> 9#include<memory> 10#include<vector> 11 12#include<opencv2/opencv.hpp> 13#include<opencv2/highgui.hpp> 14 15//=================================================================== 16// 関数プロトタイプ 17//=================================================================== 18int getsrcArea(cv::Mat src); 19long getsrcPer(cv::Mat src); 20 21std::vector< std::vector<int> > grayData; // グレイデータ 22 23//=================================================================== 24// mainエントリーポイント 25//=================================================================== 26int main(int argc, const char* argv[]) 27{ 28 int hr = -1; 29 30 cv::Mat src1, src2, src3; // 原画像 31 cv::Mat dst1, dst2, dst3; 32 33 int src1Area, src2Area, src3Area; // 面積 34 long src1Per, src2Per, src3Per; // 周囲長 35 36 try 37 { 38 //------------------------------------------------------ 39 // 画像読み込み 40 //------------------------------------------------------ 41 src1 = cv::imread("../image/Figure1.bmp", CV_LOAD_IMAGE_GRAYSCALE); 42 src2 = cv::imread("../image/Figure2.bmp", CV_LOAD_IMAGE_GRAYSCALE); 43 src3 = cv::imread("../image/Figure3.bmp", CV_LOAD_IMAGE_GRAYSCALE); 44 45 //------------------------------------------------------ 46 // 面積・周囲長取得 47 //------------------------------------------------------ 48 src1Area = getsrcArea(src1); 49 src2Area = getsrcArea(src2); 50 src3Area = getsrcArea(src3); 51 52 src1Per = getsrcPer(src1); 53 54 //------------------------------------------------------ 55 // 画像描画 56 //------------------------------------------------------ 57 cv::imshow("Source1", src1); // 原画像 58 cv::imshow("Source2", src2); // 原画像 59 cv::imshow("Source3", src3); // 原画像 60 61 cv::waitKey(0); 62 63 hr = 0; 64 } 65 66 //------------------------------------------------------ 67 // エラー処理(OpecvCV用) 68 //------------------------------------------------------ 69 catch (cv::Exception ex) 70 { 71 std::cout << ex.err << std::endl; 72 } 73 74 //------------------------------------------------------ 75 // ウィンドウ破棄 76 //------------------------------------------------------ 77 cv::destroyAllWindows(); 78 79 return hr; 80} 81 82//=================================================================== 83// 面積取得 84//=================================================================== 85int getsrcArea(cv::Mat src) 86{ 87 int Width, Height; 88 int areaCount = 0; 89 90 Height = src.rows; 91 Width = src.cols; 92 93 // 動的2次元配列確保 94 grayData.resize(Height); 95 for (int i = 0; i < Height; i++) { 96 grayData[i].resize(Width); 97 } 98 99 // グレイデータ画素値取得 100 for (int y = 0; y < Height; y++) { 101 for (int x = 0; x < Width; x++) { 102 grayData[y][x] = src.at<unsigned char>(y, x); 103 } 104 } 105 106 for (int y = 0; y < Height; y++) { 107 for (int x = 0; x < Width; x++) { 108 if (grayData[y][x] == 255) areaCount++; 109 } 110 } 111 112 return areaCount; 113} 114 115//=================================================================== 116// 周囲長取得 117//=================================================================== 118long getsrcPer(cv::Mat src) 119{ 120 long side = 0; // 縦・横 121 long slant = 0; // 斜め 122 long length; 123 124 int Width, Height; 125 126 Height = src.rows; 127 Width = src.cols; 128 129 for (int y = 1; y <= Height - 2; y++) { 130 for (int x = 1; x <= Width - 2; x++) { 131 if (grayData[y][x] == 255) { 132 if ((grayData[y][x - 1] = 255) || (grayData[y][x + 1] = 255) || (grayData[y - 1][x] = 255) || (grayData[y + 1][x] = 255)) { 133 side = side + 1; 134 } 135 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)) { 136 slant = slant + 1; 137 } 138 } 139 } 140 } 141 142 length = (int)(side + sqrt(2) * slant); 143 144 return length; 145}

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

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

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

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

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

guest

回答2

0

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

輪郭抽出(findContours)の後に、

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

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

投稿2018/03/01 07:23

yohhoy

総合スコア6191

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

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

0

※ 回答ではありません。

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

投稿2018/02/20 23:52

episteme

総合スコア16614

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問