• 締切済み

図形の重心を取るプログラムを教えてください

現在プログラミングで困っています。 そのプログラミングというのは、 「二値化した画像を二次元配列に置き換えそこから重心を求めよ」 というプログラムです。 重心を求めたい画像は、以下の特徴を持っています。 ・形はほぼ楕円。 ・輝度は0と255で二値化。重心を求める部分の輝度は0となっています この図形の重心を求めるには、どのようにプログラムを組めば良いのでしょうか。 みなさんのアドバイスをよろしくお願い致します。 また、私はプログラミングについてはほぼ初心者なので、詳しい説明をして頂けると助かります。 お手数なのですが、よろしくお願い致します。

みんなの回答

  • KEIS050162
  • ベストアンサー率47% (890/1879)
回答No.4

失礼、 sx += (float)x; sy += (float)y; これは、間違い。floatの演算は最後にまとめたので、キャストが不要でした。 単純に、 sx += x; sy += y; でOKです。 あと説明が不足していましたが、値が”0”の方が重心を求める輝度と書かれているので、 if ( img[ x ][ y ] == 1 ) { は、 if ( img[ x ][ y ] == 0 ) { としてください。

  • KEIS050162
  • ベストアンサー率47% (890/1879)
回答No.3

重心の計算方法としては下記などを参考にしてみてください。 http://www.gifu-nct.ac.jp/elec/yamada/iwata/cyu/ これを実際にプログラムするとこんな感じになるはずです。 5x5の二値画像を対象にしていますが、適当にアレンジしてみてください。 #include<stdio.h> int main( void ) { int sx = 0; int sy = 0; int mm = 0; int img[ 5 ][ 5 ] = { { 1, 1, 1, 0, 0, }, { 1, 1, 1, 1, 0, }, { 0, 1, 1, 0, 0, }, { 0, 1, 1, 0, 0, }, { 1, 1, 0, 0, 0 } }; int x, y; float gpx, gpy; for( x = 0; x < 5 ; x++ ) { for ( y = 0 ; y < 5 ; y++ ) { if ( img[ x ][ y ] == 1 ) { sx += (float)x; sy += (float)y; ++mm; } } } gpx = (float)sx/(float)mm; gpy = (float)sy/(float)mm; printf( "Total = %d, Gravity Center( x, y) = %f, %f\n", mm, gpx, gpy ); return( 0 ); }

  • ROKABAURA
  • ベストアンサー率35% (513/1452)
回答No.2

考えてみました。 重心座標をx,yとして 対称図形の座標をU(x(a),y(a))として それぞれを順に計算していく。 つまり a=1 から 例えば a=100 まで。 初期値は x=x(1) y=y(1) でその後は a=2 から 100 で x=x+((x(a)-x)/a y=y+((y(a)-y)/a これをa=100までやれば重心が出ると思います。 形は何でもいいですが 精度を落としてドット数を減らした所で座標を得れば計算できると思います。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

重心を求めることそれ自体は定義通りやればいいのだが, 「二次元配列に置き換え」の意味がわからん. なにをさせたいんだろう.

関連するQ&A

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

    現在プログラミングで困っています。 そのプログラミングというのは、 『ビットマップ画像(640×480pixel)中に表示された図形の中心を求める』 というプログラムです。 中心を求めたい図形は、以下の特徴を持っています。 ・大きさは一定ではない。10×10~20×20pixelの大きさ。 ・形はほぼ正方形。厳密に言うと、台形や平行四辺形に近い形。 ・輝度は255。 この図形の中心を求めるには、どのようにプログラムを組めば良いのでしょうか。 みなさんのアドバイスをよろしくお願い致します。 また、私はプログラミングについてはほぼ初心者なので、詳しい説明をして頂けると助かります。 お手数なのですが、よろしくお願い致します。

  • n角形の重心を求めるアルゴリズム

    平面2次元のn角形の頂点のデータがあります。n点の座標ですから(x,y)がn個並んでいます。そのような図形の図心(重心)の座標を計算するアルゴリズムがないでしょうか。最終的にはプログラムとして離散的な処理をするため、1%ぐらいの誤差は許容範囲です。n角形と言ってもせいぜいn=3,4,5,6程度です。 欲を言うと、3次元も考えており、平面に含まれることが分かっているn個の点(3次元空間内)を平面の2次元空間に変換して重心を求め、それを3次元空間に引き戻せば3次元での重心となります。そのためにも2次元での重心の座標を求めるアルゴリズムが必要なのです。 よろしくお願いします。

  • 重心点の求め方

     長方形の長い辺に小さい長方形がくっついた図形の重心点の求め方を教えてください。           ↓こんな形(■の部分) □□□□□□□□□ □□■■■■■■□ □□■■■■■■□ □■■■■■■■□ □■■■■■■■□ □■■■■■■■□ □□□□■■■■□ □□□□■■■■□ □□□□□□□□□    

  • 重心が下がるとは?

    ゴルフ超初心者です。 クラブの重心が下がるとはどういう事でしょうか? 例えばアイアンで言うと ソール部分が分厚くなると、重心が垂直方向に下がって それに伴いスイートスポットの位置も下がり 打球が上がりやすくなる、ということでしょうか? どなたか超初心者の私にも分かり易く 教えて頂けないでしょうか。 宜しくお願い致します。

  • Excel2003で簡単な図形の表示と非表示のプログラムを作成したので

    Excel2003で簡単な図形の表示と非表示のプログラムを作成したのですが上手く出来ません UserForm1に Private Sub OptionButton1 Click() ActiveSheet.Shapes("Oval 1").Visible=True 'ワークシート1に楕円の図形1表示 ActiveSheet.Shapes("Oval 2").Visible=False 'ワークシート1に楕円の図形2非表示 End Sub Private Sub OptionButton2 Click() ActiveSheet.Shapes("Oval 1").Visible=False 'ワークシート1に楕円の図形1非表示 ActiveSheet.Shapes("Oval 2").Visible=True 'ワークシート1に楕円の図形2表示 End Sub 上記の記述では上手くいくのですが、下記の様に ワークシート2の図形3と4も同様に表示・非表示したいため追加するとエラーになります。 UserForm1に Private Sub OptionButton1 Click() ActiveSheet.Shapes("Oval 1").Visible=True 'ワークシート1の楕円図形1表示 ActiveSheet.Shapes("Oval 2").Visible=False 'ワークシート1の楕円図形2非表示 ActiveSheet.Shapes("Oval 3").Visible=True 'ワークシート2の楕円図形3表示 ActiveSheet.Shapes("Oval 4").Visible=False 'ワークシート2の楕円図形4非表示 End Sub Private Sub OptionButton2 Click() ActiveSheet.Shapes("Oval 1").Visible=False 'ワークシート1の楕円図形1非表示 ActiveSheet.Shapes("Oval 2").Visible=True 'ワークシート1の楕円図形2表示 ActiveSheet.Shapes("Oval 3").Visible=False 'ワークシート2の楕円図形3非表示 ActiveSheet.Shapes("Oval 4").Visible=True 'ワークシート2の楕円図形4表示 End Sub VBAの勉強中の初心者です。教えて頂けないでしょうか。

  • プログラム内描画図形をdrawImageで出力

    やりたい事のおおまかなイメージは以下です。 1)プログラム初期時にある図形を数種類描画。(オフラインで)   種類とは、たとえば、長方形と円と楕円というようなもの。 2)あるボタンクリックにより、数種類ある図形の何れかを   ある条件により、種類を判定し、数秒間隔で描画。   (という事で毎回図形を描画するよりもイメージで保持しておきたい。) 既に、1)の部分がgifイメージを読み込んだものとして、描画まで完成しております。 出力部分はdrawImageメソッドを使用しています。 そこで、2)の出力部分はそのままで、1)の様な修正を施したいのです。 (図形ファイルロードの部分を図形描画及&イメージ化?) ComponentクラスのcreateImageを使用するのかな?くらいしかわかっておりません。 以上、よろしくお願いします。

    • ベストアンサー
    • Java
  • 図形内の面積の求め方。

    エクセル上で自分で式を組んで計算させようと試みてるのですが、途中で考えにいきづまってしまいました。分かる方お願いします。 半径1の円があり、その内側に接する形で同じ大きさの2つの楕円が直角にクロスしているとします。 その2つの楕円の重なった部分(曲線で囲まれた四角)の面積を求めたいのですが、公式等求め方ってあるのでしょうか? それか、もしフリーソフトなどで、図形も描けて、その中の求めたい部分の面積が算出出来るようなものがありましたら、参考にしたいので、知っている方がいましたら、そちらも教えていただけないでしょうか?(なかなか検索しても見つからずに困っております)

  • とあるプログラムを教えてほしいのですが

    はじめましてこんばんは hommado と申します。 じつは先週の授業でこんな問題を出されたんですがもしできたらとあるプログラムを教えてほしいのです。 問題は 「キーボードから何階調にするのかを読み込むことで、入力画像LAX.bmpを任意の階調数に変換する」という プログラムです。 一応下に素体のプログラムをおいたんで、其のプログラムに何か付け足す感じでお願いします。「/*******↓基本的には、この範囲に画像処理プログラムを書く****/」から 「 /********↑**************************************************/」の中にプログラムを書くかんじなのでもし分かったら教えてください。お願いします。 あと何か他の所に付け足すようなところがあったら教えてください ここから元のプログラム // Bitmapファイルを読み込んで, // 別のファイルに出力するだけのプログラムです #include<stdio.h> #define XSIZE 256 /* 画像の横サイズ*/ #define YSIZE 256 /* 画像の縦サイズ*/ void main(void) { int x,y; char fni[40],fno[40]; /* 入力ファイルと出力ファイルの名前を格納するための配列*/ unsigned char head[1078],buf[YSIZE][XSIZE]; /* 入力ファイル(ビットマップファイル)のヘッダ情報と輝度値情報を格納するための配列*/ unsigned char in_image[YSIZE][XSIZE]; /* 入力画像の画素の輝度値を格納するための配列*/ unsigned char out_image[YSIZE][XSIZE]; /* 出力画像の画素の輝度値を格納するための配列*/ FILE *fp,*fp2; /* ファイルポインタ*/ printf("ファイル名を入れてください:"); scanf("%s",fni); fp=fopen(fni,"rb"); /* 読み込み& バイナリモードでオープンする*/ /* 配列head にビットマップファイルのヘッダ情報が格納されます*/ fread(head,sizeof(unsigned char),1078,fp); /* unsigned char 型のデータ×個を配列head に読み込む*/ /* 配列buf にビットマップファイルの輝度値情報が格納されます*/ fread(buf,sizeof(unsigned char),XSIZE*YSIZE,fp); for(y=0;y<YSIZE;y++){ for(x=0;x<XSIZE;x++){ in_image[y][x]=buf[y][x]; /* 画像の左下の画素が座標buf[0][0] です*/ } } printf("読み込み終了しました!\n"); printf("出力ファイル名を入れてください:"); scanf("%s",fno); /*******↓基本的には、この範囲に画像処理プログラムを書く****/       ここにプログラムを書いてください!      (もしここ以外で、他の所で付け足すプログラムがあったら何行目に       何を書くのかも教えてください) /********↑**************************************************/ fp2=fopen(fno,"wb"); /* 書き込み& バイナリモードでオープンする*/ /* 配列head の内容を出力ファイルに書き込む*/ fwrite(head,sizeof(unsigned char),1078,fp2); /* 配列out_image の内容を出力ファイルに書き込む*/ fwrite(out_image,sizeof(unsigned char),XSIZE*YSIZE,fp2); fclose(fp); /* ファイルをクローズする*/ fclose(fp2); /* ファイルをクローズする*/ printf("作業完了!\n"); }

  • クロスワードパズルを解くプログラムについて。

    学校の授業で独学でプログラミングを学ぶ授業があり、 現在授業の一環としてSWI-prologを学んでいます。 そこで、prologを用いて キー無しのクロスワードパズルを解くプログラムを組むことになりました。 キー無しのクロスワードパズルとは、 単語群から空白に文字数の合う単語を入れて埋めていくパズルです。 今回は英単語でやろうとしています。 自力でやってみようと思ったのですが、全く手が付けられず、 先生にアドバイスをいただきましたが、自分の理解力不足なのかよくわかりませんでした。 先生がおっしゃっていたことは ・prologの辞書を用いる ・1次元配列でつくる といったようなものでしたが、よくわかりません。 自分で本を購入し、自分なりに噛み砕きながらやってみましたができませんでした。 辞書はどこからか入手するのでしょうか。 また、1次元配列をprolog上でどうやって書けばいいのでしょうか。 C言語で配列はやっているので概念はわかっています。 そして、クロスワードパズルを解くプログラムを教えていただけないでしょうか。 文章が長くなり、申し訳ありません。 よろしくお願い致します。

  • VC++プログラムをつかったBMP画像の拡大縮小について

    現在VC++をつかった画像を扱うプログラミングを学習中なのですが、画像データの取り扱いについてわからないことがあるため教えていただきたいです。 BMP画像をバッファに取り込んだあとで、画像の縦横を拡大縮小したデータを新たなバッファに格納したいのですが、画像を拡大縮小する方法がわかりません。いくつかのプログラムのソースを見させていただいたのですが、BITMAPINFOHEADER構造体の中のbiWidthやbiHeightの値を変えているだけのようなのです。 これらの値を変えるだけで、指定した幅と高さに変換された画像データが得られるのでしょうか? また、それで拡大縮小されるならば、変換された画像データは輝度情報が滑らかになるように何かしらの補正が加えられていたりするのでしょうか?それとも、途中途中の輝度を単純に抜いていたりするだけなのでしょうか。 その辺の原理についても教えていただけるとうれしいです。 お手数をかけますが、よろしくお願いします。