出産前後の痔にはご注意!

OpenCVによる面積算出

現在OpenCVを使用して、2値化した画像を取得し保存。そして取得した画像を読み込み白い部分の面積を求めるプログラムを作成中なのですが、正直分かりません;;

どのように作ればいいのか、OpenCvのプログラミングブックやGoogleで検索しても、自分で作成するに至れない状況です。もしよろしければ、アドバイス等をいただけると幸いです;;

A 回答 (2件)

こんばんは.



「白い部分の面積」というのは,「(連結している)白い部分の(個別の)面積」であると
仮定して回答させて頂きます.
(でなければ,単純にカウンタ変数を用意した上で,画像を左上の画素から右下の画素まで読んでいって,値が0だったら無視,255だったらカウントアップ,で済む話です)

それで,「連結している白い部分の個別の面積」を求める処理はラベリング処理といいます.
わかりやすい概念図が下記ページに載っています.
http://imagingsolution.blog107.fc2.com/blog-entr …

また,OpenCV用のラベリング関数を自作して公開してくれている人が居ます.
http://oshiro.bpe.es.osaka-u.ac.jp/people/staff/ …
勉強のためではなく,急ぎならこちらを利用させてもらっても良いでしょう.

以上,参考になれば幸いです.
    • good
    • 0

単純に画像全体の中から白い部分の面積(輝度値が0で無い部分の面積)を求めるのなら、cvCountNonZero関数を使うと一発で求められます。


ただし、OpenCV.jpにも書かれているように、この関数はシングルチャンネル(モノクロ画像)か、COI(処理するチャンネルが指定)されたマルチチャンネル(カラー画像)に対応なので、ご注意下さい。

それとも、IplImageの輝度データを直接参照したいのなら、過去に同じ様な質問があったので、そちらが参考になると思います。
http://okwave.jp/qa/q4743115.html

もしくはkirinomaさんの回答のように、連結成分(ラベリングした領域)の面積を求めたいのなら、Googleで『cvFindContours 面積』で検索してもらうと参考になるページが見つかると思います。
http://www.google.co.jp/search?hl=ja&rlz=1B3GGGL …

以上、参考まで。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q【OpenCV】二値画像後、白の部分の面積を求める

OpenCVで二値画像後、白の部分の面積を求めたいのですがどのようにしたらよいでしょうか?

OS : Linux FedoraCore7

Aベストアンサー

 こんにちは。
 当方はwindowsなのですが、openCVと言う事で、一応お話だけでも。
 iplのimageDataがグラフィックスを示す配列ですので、二値化した後、imageDataを走査しながら、ビットが立っていればカウントアップすれば白い面積が取れる様な気がします。
 以下参考程度に。

typedef struct
{
int dim;//総面積
int white;//白の面積
int black;//黒の面積
}MONOSPACE;
MONOSPACE space = {0};

//ファイルからイメージを読み込む
IplImage* img = ::cvLoadImage("TestImage.bmp", 0);

//二値化する(127以上で1を出力する)
::cvThreshold(img, img, 255 / 2, 1, CV_THRESH_BINARY);

for(int y = 0; y < img->height; y++)
{
for(int x = 0; x < img->width; x++)
{
const int val = img->imageData[y * img->widthStep + x];
if(val & 1)++space.white;//白色なのでカウントする
}
}

//総面積
space.dim = img->width * img->height;

//黒い面積
space.black=space.dim - space.white;

//iplの開放
::cvReleaseImage(&img);

 こんにちは。
 当方はwindowsなのですが、openCVと言う事で、一応お話だけでも。
 iplのimageDataがグラフィックスを示す配列ですので、二値化した後、imageDataを走査しながら、ビットが立っていればカウントアップすれば白い面積が取れる様な気がします。
 以下参考程度に。

typedef struct
{
int dim;//総面積
int white;//白の面積
int black;//黒の面積
}MONOSPACE;
MONOSPACE space = {0};

//ファイルからイメージを読み込む
IplImage* img = ::cvLoadImage("TestImage.bmp", 0);

/...続きを読む

QOpenCV でのROIの指定方法について

いつもお世話になっております.
OpenCVに関する質問です.
FastFeatureDetectorやGoodFeaturesToTrackDetector等の特徴点検出器を入力画像の特定の部分に対して行うために,入力画像に対してROIを設定したのですが上手くいかない場合があって困っています.

たとえば,
入力画像(640*480)に対して,
左上(0,0)右下(640,480)や左上(0,0)右下(320,240)を矩形領域を指定すれば上手くいくのですが,
左上(10,10)右下(640,480)や左上(320,240)右下(640,480)だと,結果がズレてしまいます.

下記のソースコードで
---------------------------------------------------------------
cv::Rect* roi = new cv::Rect(roi_x, roi_y, roi_w, roi_h);
cv::Mat* InuptImage = new cv::Mat(640, 480, CV_8UC1, data);//dataはbyte型
InuptImage = new cv::Mat(*InuptImage, *roi);
---------------------------------------------------------------
(roi_x, roi_y, roi_w, roi_y)が
(0, 0, 640, 480)や(0, 0, 320, 240)の場合は上手くいくのですが,
(10, 10, 630, 470)や(320, 240, 320, 240)の場合には,特徴点の位置がずれたり,全体的に縮小されたりします.

どこに問題があるのでしょうか?

OpenCVは2.3で,言語はC++です.
アドバイス宜しくお願い致します.

いつもお世話になっております.
OpenCVに関する質問です.
FastFeatureDetectorやGoodFeaturesToTrackDetector等の特徴点検出器を入力画像の特定の部分に対して行うために,入力画像に対してROIを設定したのですが上手くいかない場合があって困っています.

たとえば,
入力画像(640*480)に対して,
左上(0,0)右下(640,480)や左上(0,0)右下(320,240)を矩形領域を指定すれば上手くいくのですが,
左上(10,10)右下(640,480)や左上(320,240)右下(640,480)だと,結果がズレてしまいます.

下記のソースコードで
---...続きを読む

Aベストアンサー

オフセットは必ず必要です。ROIを指定する前の画像の全体のサイズと、本来の画像の左上から、ROIの左上の座標のオフセットは、locateROI メソッドで取得することができます。

実際には、オフセットを考慮して点群座標を変換するか、特徴点を描画したい場合などでは、元の画像ではなく ROI で切り取った画像に対して描画を行います。


参考まで。



// okwave01.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>

int main(int argc, char argv[])
{
const std::string FILE_PATH("lena.jpg");
//sample.bmpは640*480のRGBの画像

cv::Mat rgb_img = cv::imread(FILE_PATH);
// 画像読み込み

cv::Mat gray_img;
cv::cvtColor(rgb_img, gray_img, CV_BGR2GRAY);
// グレースケール画像に変換

const cv::Point ROI_TL(rgb_img.rows * 0.25, rgb_img.cols * 0.25);
const cv::Rect RECT(
rgb_img.rows * 0.25, rgb_img.cols * 0.25,
rgb_img.rows * 0.5, rgb_img.cols * 0.5);
// 中心 だけを切り取る ROI を作成。

cv::Mat rgbimage_roi = rgb_img(RECT);
cv::Mat grayimage_roi = gray_img(RECT);
// ROI による切り取り。


std::vector<cv::KeyPoint> corners;
// FAST 頂点座標の保存用変数

cv::FAST(grayimage_roi, corners, 10, true);

for (auto it = corners.begin(); it != corners.end(); ++it) {
cv::circle(grayimage_roi, it->pt, 1, cv::Scalar(255), 2);
// ROI を通してグレイスケール画像に書き込む

cv::circle(rgb_img, ROI_TL + cv::Point2i(it->pt), 1, cv::Scalar(0, 0xff, 0), 2);
// オフセットを考慮して直接RGB画像に書き込む
}

cv::imshow("RGB IMAGE", rgb_img);
cv::imshow("GRAY IMAGE", gray_img);
return cv::waitKey();
}

オフセットは必ず必要です。ROIを指定する前の画像の全体のサイズと、本来の画像の左上から、ROIの左上の座標のオフセットは、locateROI メソッドで取得することができます。

実際には、オフセットを考慮して点群座標を変換するか、特徴点を描画したい場合などでは、元の画像ではなく ROI で切り取った画像に対して描画を行います。


参考まで。



// okwave01.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>

int main(int argc...続きを読む

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Qエクセル STDEVとSTDEVPの違い

エクセルの統計関数で標準偏差を求める時、STDEVとSTDEVPがあります。両者の違いが良くわかりません。
宜しかったら、恐縮ですが、以下の具体例で、『噛み砕いて』教えて下さい。
(例)
セルA1~A13に1~13の数字を入力、平均値=7、STDEVでは3.89444、STDEVPでは3.741657となります。
また、平均値7と各数字の差を取り、それを2乗し、総和を取る(182)、これをデータの個数13で割る(14)、この平方根を取ると3.741657となります。
では、STDEVとSTDEVPの違いは何なのでしょうか?統計のことは疎く、お手数ですが、サルにもわかるようご教授頂きたく、お願い致します。

Aベストアンサー

データが母集団そのものからとったか、標本データかで違います。また母集団そのものだったとしても(例えばクラス全員というような)、その背景にさらならる母集団(例えば学年全体)を想定して比較するような時もありますので、その場合は標本となります。
で標本データの時はSTDEVを使って、母集団の時はSTDEVPをつかうことになります。
公式の違いは分母がn-1(STDEV)かn(STDEVP)かの違いしかありません。まぁ感覚的に理解するなら、分母がn-1になるということはそれだけ結果が大きくなるわけで、つまりそれだけのりしろを多くもって推測に当たるというようなことになります。
AとBの違いがあるかないかという推測をする時、通常は標本同士の検証になるわけですので、偏差を余裕をもってわざとちょっと大きめに見るということで、それだけ確証の度合いを上げるというわけです。

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

QOpenCVを使った画像の切り抜き

添付画像のように、サイズ(X,Y)の画像があったとします。
その画像のある座標(X',Y')とサイズを指定してできた短形領域を、IplImageとして保存するにはどうすればいいのでしょうか?
OpenCVを使ってるのですが、そういった関数はなかったでしょうか?
よろしくお願いします。

Aベストアンサー

 こんにちは。

 cvSetImageROI()で領域指定です。以下参考程度に。
 http://opencv.jp/sample/initialization.html

int main()
{
//イメージをロード
IplImage* ipl = ::cvLoadImage("test.bmp", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);

//x=10, y=10から64x32でROIを設定
::cvSetImageROI(ipl, ::cvRect(10, 10, 64, 32));

//ROIを設定した状態でセーブ
::cvSaveImage("result.bmp", ipl);

//ROIの解除
::cvResetImageROI(ipl);

//イメージの解放
::cvReleaseImage(&ipl);

return 0;
}

Q画像の座標取得

c言語を使って,
画像を読み込んできて,
画像上のクリックした画像の座標を取得する
プログラムを作りたいのですが,
どうすればよいでしょうか.

画像の読み込み→画像の表示→画像をクリック→画像の座標を取得
といった流れのものを作りたいです.

最初は保存されている静止画像を読み込んで座標を取得することをやり,
最終的にはUSBカメラなどを使って動画の座標の取得を目指しています.

使用OSはWindows7,
コンパイラはVisual Studio 2008をつかっております.

Aベストアンサー

OpenCVという画像処理ライブラリを使うといいでしょう。
クリックした座標の取得や、USBカメラからの動画取り込みのための関数も用意されているので、割と素早くできると思いますよ。

サンプルコード:
http://opencv.jp/sample/simple_gui.html

Q1ピクセルって何ミリですか?

1ピクセルって何ミリなのでしょう?
至急、お答えお待ちしております。
かなり急いでます。よろしくお願いいたします。

Aベストアンサー

1ピクセルが何ミリかという質問の答えになるかどうか分かりませんが、
WEB制作上に限って言えば、横100ピクセルの画像を作りたい場合、
Photoshop等では単位をピクセルで作れますが、Illustrator等の場合は、
100pointで作ります。
1pointは、0.35277ミリです。

Q透視投影された平面を正面から見たように変換したい

透視投影で撮影された平面を、正面から撮影したように投影変換する処理を教えてください。
または、射影ひずみの補正といわれるものでしょうか?
私なりにいろいろと調べまして、
「画像の平面内の四頂点の座標を求めることができれば、平面の傾きを求めることができる。」
というところまでたどり着きまして、平面の角度を求めるところまではいきました。
しかし、その後の行列変換がわかりません。
単に回転であれば、

1    0    0
0 cosθ -sinθ
0 sinθ cosθ


cosθ 0 sinθ
0   1    0
-sinθ 0 cosθ

をかければよいかと思っていましたが、奥行きの収縮などの関係がわかりません。
どの様な行列をかければ求めることができるのか教えてください。
このような研究をしていますが、行列は苦手なので、簡単な質問でしたらすみません。

Aベストアンサー

アフィン変換と透視投影の座標変換は以下のURLに詳しく載っていると思いますので、勉強してください。
中に座標変換の式も載っていると思います。
アフィン変換や透視投影の理解に役立つようにイメージ図のあるHPも余分にあげておきました。参考になるかと思います。

アフィン変換と透視投影
http://nis-lab.is.s.u-tokyo.ac.jp/nis/CG/cgtxt/index2.htm
http://www.geocities.co.jp/Hollywood/5174/td.html
http://www-antenna.ee.titech.ac.jp/~hira/hobby/edu/afin_trans/math_html/index.html
http://hawk.ise.chuo-u.ac.jp/makino-lab/person/itot/cg2003/cg-lecture5.pdf
http://kawanobe.rs.sanno.ac.jp/~matsunaga_y/rinkou2.pdf
http://navi.cs.kumamoto-u.ac.jp/lecture/computergrahics/2007/8.pdf

プログラムでの座標変換
http://www.saturn.dti.ne.jp/~npaka/xna/PrimitiveEx/index.html

アフィン変換と透視投影の座標変換は以下のURLに詳しく載っていると思いますので、勉強してください。
中に座標変換の式も載っていると思います。
アフィン変換や透視投影の理解に役立つようにイメージ図のあるHPも余分にあげておきました。参考になるかと思います。

アフィン変換と透視投影
http://nis-lab.is.s.u-tokyo.ac.jp/nis/CG/cgtxt/index2.htm
http://www.geocities.co.jp/Hollywood/5174/td.html
http://www-antenna.ee.titech.ac.jp/~hira/hobby/edu/afin_trans/math_html/index.html
http:/...続きを読む

Q図形の中心の取り方を教えてください。

現在プログラミングで困っています。
そのプログラミングというのは、
『ビットマップ画像(640×480pixel)中に表示された図形の中心を求める』
というプログラムです。

中心を求めたい図形は、以下の特徴を持っています。
・大きさは一定ではない。10×10~20×20pixelの大きさ。
・形はほぼ正方形。厳密に言うと、台形や平行四辺形に近い形。
・輝度は255。

この図形の中心を求めるには、どのようにプログラムを組めば良いのでしょうか。
みなさんのアドバイスをよろしくお願い致します。

また、私はプログラミングについてはほぼ初心者なので、詳しい説明をして頂けると助かります。
お手数なのですが、よろしくお願い致します。

Aベストアンサー

#1 さんの方法では重心は求まりません.

> 1.水平線を引き、したから上に移動する。上下の図形のピクセル数が等しくなったらとめる。
> 2.垂直線を引き、左から右に移動する。左右の図形のピクセル数が等しくなったらとめる。

これらは重心を求めているのではなく,面積を縦横それぞれについて2等分しているだけです.

重心は面積を2等分する点ではなくて,そのまわりの1次モーメントが釣り合う (0になる) 点です.

重心を求める (物理のかぎしっぽ)
http://www12.plala.or.jp/ksp/mechanics/CG/

2次元での一般的な重心 (Xg, Yg) の定義は,
位置 (x, y) の密度を ρ(x, y) とすると,

・質量
 M = ∫∫ρ(x, y) * dx * dy

・Xの (つまりY軸まわりの) 1次モーメント
 Ix = ∫∫ρ(x, y) * x * dx * dy

・Yの (つまりX軸まわりの) 1次モーメント
 Iy = ∫∫ρ(x, y) * y * dx * dy

・重心
 Xg = Ix / M
 Yg = Iy / M

画像処理でいう「重心」は,密度の代わりに輝度 (画素値) p(x, y) を使うので,

 M = Σ{x} Σ{y} p(x, y)
 Ix = Σ{x} Σ{y} p(x, y) * x
 Iy = Σ{x} Σ{y} p(x, y) * y

質問文中の「輝度は255」というのは,たぶん二値画像で
「輝度は0または255」ということだと思います.
その場合には次のようにすれば無駄な計算をせずに重心が求められます.

 M = (輝度=255の画素数)
 Ix = Σ{輝度=255の画素} x
 Iy = Σ{輝度=255の画素} y

今は時間がないのでこの辺で.
あとは自分で考えるか,他の方の回答を待ってください.


QNo.3233875:濃淡画像の縦方向のゆがみを求めたいのですが・・
http://okwave.jp/qa3233875.html

#1 さんの方法では重心は求まりません.

> 1.水平線を引き、したから上に移動する。上下の図形のピクセル数が等しくなったらとめる。
> 2.垂直線を引き、左から右に移動する。左右の図形のピクセル数が等しくなったらとめる。

これらは重心を求めているのではなく,面積を縦横それぞれについて2等分しているだけです.

重心は面積を2等分する点ではなくて,そのまわりの1次モーメントが釣り合う (0になる) 点です.

重心を求める (物理のかぎしっぽ)
http://www12.plala.or.jp/ksp/mechanics/CG...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング