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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OpenCV

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

C++

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

Q&A

解決済

4回答

10655閲覧

opencvの重心を求めるプログラムにopencvの関数ではない重心を求めるプログラムを入れたいです。

carnage0216

総合スコア194

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OpenCV

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

C++

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

0グッド

0クリップ

投稿2018/06/07 11:11

編集2018/06/09 15:34

<実行した環境>

  • Windows10 64bit
  • visual studio 2017
  • opencv 3.4.1

opencvの重心を求めるプログラムにopencvの関数ではない重心を求めるプログラムを入れたいです。
ただ質問するだけではただの投げやりなどと言われて嫌な気分になるので私なりに調べてきました。

#include <stdio.h> #include "opencv/cv.h" #include "opencv/highgui.h" using namespace cv; int main(){ Mat img = imread("sample.jpg", IMREAD_GRAYSCALE); Moments mu = moments( img, false ); Point2f mc = Point2f( mu.m10/mu.m00 , mu.m01/mu.m00 ); circle( img, mc, 4, Scalar(100), 2, 4); printf("x: %f y: %f", mc.x, mc.y); imshow("img",img); waitKey(0); return 0; }

以上のプログラムのmu.m10/mu.m00 , mu.m01/mu.m00の部分が重心を求める計算式であるとわかったので
この部分を以下の重心を求めるプログラムに置き換えたいのですが問題があります。

int count=0; double x_g=0.0,y_g=0.0,x_d=0.0,y_d=0.0,xy_d=0.0 for(int y=0; y<height; y++){ for(int x=0;x<width; x++){ if(img_src[y*width+x] == 255){ count++; x_g +=x; y_g +=y; } } } x_g /=conut; y_g/=count;

まず一つにMoments muのmuとPoint2f mcのmcが何を表しているか調べたのですがわかりませんでした。
また、Point2f( mu.m10/mu.m00 , mu.m01/mu.m00 ); と circle( img, mc, 4, Scalar(100), 2, 4);にmu、mcが入っていることからただ計算式を置き換えるだけでは意味がないと考えています。
しかし、どうやってmuとmcを考慮しながら計算式を置き換えてよいかわかりません。
どうか助言を頂けないでしょうか?
どうかよろしくお願いいたします。

<編集>
関数Point2fの使い方を調べようと本家の方で検索したのですが、例題としてPoint2f a(0.3f, 0.f), b(0.f, 0.4f);となり少なくともaとbの座標を二次元で表していることはわかるのですが、mcがなにを言っているのかわかりません。
調べたサイトはhttp://opencv.jp/opencv-2.1/cpp/basic_structures.htmlです。
できれば使い方のわからない関数がそのままの形で載っていればいいのですが、そうでない今回のような場合どのように調べればよいか教えていただけないでしょうか?

調べたサイトのようにPoint2f( m10/m00 , m01/m00 );と素直に座標だけ表せてくれればいいのですがなぜかmuが入ってPoint2f( mu.m10/mu.m00 , mu.m01/mu.m00 );となるので、どうやって座標のmuを考慮しながら計算のプログラムを入れるか悩みます。
多分muはPoint2f()より引数だと思うのですが、muが何を表しているのかわからず困り果てています。

編集6/10
<実行した環境>

  • Windows10 64bit
  • visual studio 2017
  • opencv 3.4.1

ベストアンサー後に申し訳ありません。asm様からのプログラムを読んで学習のために自分なりにプログラムを作りました。

以下のプログラムをVS2017でビルドしたところエラーが出ました。

#include <stdio.h> #include <opencv/cv.h> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgcodecs/imgcodecs.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/core/core.hpp> using namespace cv; int main() { Mat img = imread("sample.jpg", IMREAD_GRAYSCALE); int count = 0; int conut = 0; double x_g = 0.0, y_g = 0.0; for (int y = 0; y<height; y++) { for (int x = 0; x<width; x++) { if (img_src[y*width + x] == 255) { count++; x_g += x; y_g += y; } } } int a; int b; a= x_g / conut; b= y_g / conut; Point2f mc = Point2f(a, b);//x_g / conutとy_g / conutをaとbと置いた。 circle(img, mc, 4, Scalar(100), 2, 4); printf("x: %f y: %f", mc.x, mc.y); imshow("img", img); waitKey(0); return 0; }

こちらがエラーなのですが

1>------ ビルド開始: プロジェクト: Project18, 構成: Release x64 ------ 1>Source.cpp 1>c:\users\daito\source\repos\project18\project18\source.cpp(16): error C2065: 'height': 定義されていない識別子です。 1>c:\users\daito\source\repos\project18\project18\source.cpp(17): error C2065: 'width': 定義されていない識別子です。 1>c:\users\daito\source\repos\project18\project18\source.cpp(18): error C2065: 'img_src': 定義されていない識別子です。 1>c:\users\daito\source\repos\project18\project18\source.cpp(18): error C2065: 'width': 定義されていない識別子です。 1>c:\users\daito\source\repos\project18\project18\source.cpp(30): warning C4244: '引数': 'double' から 'float' への変換です。データが失われる可能性があります。 1>プロジェクト "Project18.vcxproj" のビルドが終了しました -- 失敗。 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========

インクルードしたヘッダファイルにheight、width、img_srcの定義は書いてあると思ったのですが、エラーが出るということは必要なヘッダファイルが入っていないのだと思います。
変数height、widthと関数img_srcの定義が書いてあるgithubはないでしょうか?
ヘッダファイルでも構いません。
どうかよろしくお願いいたします。

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

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

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

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

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

guest

回答4

0

ベストアンサー

回答依頼来たので駄文ながら

調べたサイトのようにPoint2f( m10/m00 , m01/m00 );と素直に座標だけ表せてくれればいいのですがなぜかmuが入ってPoint2f( mu.m10/mu.m00 , mu.m01/mu.m00 );となるので、どうやって座標のmuを考慮しながら計算のプログラムを入れるか悩みます。

もしかして、C言語の構造体をご存知ないのでしょうか?

くっつけるだけならば単純に

c++

1#include <stdio.h> 2#include "opencv/cv.h" 3#include "opencv/highgui.h" 4using namespace cv; 5 6int main(){ 7 8 Mat img = imread("sample.jpg", IMREAD_GRAYSCALE); 9 10 int count=0; 11 double x_g=0.0,y_g=0.0; 12 for(int y = 0 ; y < img.rows; y++){ 13 for(int x = 0 ; x < img.cols; x++){ 14 if(img.at<uchar>( y, x ) == 255){ 15 count++; 16 x_g += x; 17 y_g += y; 18 } 19 } 20 } 21 x_g /= conut; 22 y_g /= count; 23 24 Point2f mc = Point2f( x_g, y_g); 25 26 circle( img, mc, 4, Scalar(100), 2, 4); 27 28 printf("x: %f y: %f", mc.x, mc.y); 29 30 imshow("img",img); 31 waitKey(0); 32 return 0; 33}

とするだけですよ
修正: 指摘を受け、img.at( y, x )をimg.at<uchar>( y, x )に変更


追記
Mat1b つまり Mat_<uchar>を使うと

c++

1#include <stdio.h> 2#include "opencv/cv.h" 3#include "opencv/highgui.h" 4using namespace cv; 5 6int main(){ 7 Mat1b img = imread("sample.jpg", IMREAD_GRAYSCALE); 8 int count=0; 9 double x_g=0.0,y_g=0.0; 10 for(int y = 0, height = img.rows; y < height; y++){ 11 // パフォーマンス的には↓3行を置き換えた方が速い 12 // const uchar *_img = img[y]; 13 // for(int x = 0, width = img.cols ; x < width; x++){ //変化なし 14 // if(_img[x] == 255){ 15 for(int x = 0, width = img.cols ; x < width; x++){ 16 if(img( y, x ) == 255){ 17 count++; 18 x_g += x; 19 y_g += y; 20 } 21 } 22 } 23 x_g /= conut; 24 y_g /= count; 25 26 Point2f mc = Point2f( x_g, y_g); 27 28 circle( img, mc, 4, Scalar(100), 2, 4); 29 30 printf("x: %f y: %f", mc.x, mc.y); 31 32 imshow("img",img); 33 waitKey(0); 34 return 0; 35}

投稿2018/06/08 11:49

編集2018/06/12 02:14
asm

総合スコア15147

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

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

episteme

2018/06/08 12:27

...そなの? 構造体わかんないの?
carnage0216

2018/06/08 13:55 編集

ご親切にどうもありがとうございます。 えーと、構造体とはなにを引数として、なにを出力とするか、関数の使い方などのことでしょうか? 記憶が正しければ構造体の型を宣言する時は{}の中に「struct」を書いてデータ型メンバ型を書くことは読みました。(間違っていたら申し訳ありません。) しかし、まだうまく使いこなせていません。 構造体が完全にわかっているかと聞かれると自信をもってはいとは言えません。 ですが今回の問題が自分の力で解決できなかった以上構造体を理解していないと思われても仕方ありません。
carnage0216

2018/06/08 13:58

あ!なるほどプログラムは上から順番に処理していくのでmuを消して、重心を求めるプログラムの処理を書き込めばよかったのですね。こんなこともわからなかったとは…。恥ずかしいレベルではないですね。
asm

2018/06/08 15:41

Moments mu = moments( img, false ); muがcv::Moments型の構造体である事を理解できていないのならばC言語の学習に戻りましょう https://9cguide.appspot.com/16-01.html // 実際の定義を確認したところC++のclassだったが // パブリックメンバ変数とコンストラクタのみなので構造体として扱ってもまぁ問題なし
carnage0216

2018/06/08 18:03

ありがとうございます。 はい。C言語の学習に戻ります。 muが重心を求めるための計算に使われているので、 個人的には重心を求める計算式をcv::Moments型の構造体と言っているように思えました。
asm

2018/06/08 18:26

muは変数の集まりです。 この場合はmoments関数が複数の値を返すためにcv::Moments型の構造体を返しています。
episteme

2018/06/08 23:26

> 重心を求める計算式をcv::Moments型の構造体と言っているように思えました。 Moments はmoments()が値を格納するための器でしかない。 重心を求めるのに必要なモーメントはmoments()が計算している。
carnage0216

2018/06/09 14:35

どうもありがとうございました。
carnage0216

2018/06/10 17:52 編集

asmさんに質問したいことがあります。 せっかくasmさんにプログラムを書いていただきながら自分なりのプログラムに関して質問したいことがあります。決してasmさんのプログラムが嫌なわけではありません。ただ足りない頭で考えて書いたためどうしても原型に近い形でビルドしたいと思いました。 怒られることを承知で質問したいことがございます。どうかお答えしていただけると嬉しいです。 こちらがプログラムです。 #include <stdio.h> #include <opencv/cv.h> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgcodecs/imgcodecs.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/core/core.hpp> using namespace cv; int main() { Mat img = imread("sample.jpg", IMREAD_GRAYSCALE); int count = 0; int conut = 0; double x_g = 0.0, y_g = 0.0; int height = 400; int width = 300; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (img_src[x][y] == 255) { count++; x_g += x; y_g += y; } } } int a; int b; a = x_g / conut; b = y_g / conut; Point2f mc = Point2f(a, b);//x_g / conutとy_g / conutをaとbと置いた。 circle(img, mc, 4, Scalar(100), 2, 4); printf("x: %f y: %f", mc.x, mc.y); imshow("img", img); waitKey(0); return 0; } こちらがエラーです。 1>------ ビルド開始: プロジェクト: Project18, 構成: Release x64 ------ 1>Source.cpp 1>c:\users\daito\source\repos\project18\project18\source.cpp(21): error C2065: 'img_src': 定義されていない識別子です。 1>c:\users\daito\source\repos\project18\project18\source.cpp(30): warning C4244: '=': 'double' から 'int' への変換です。データが失われる可能性があります。 1>c:\users\daito\source\repos\project18\project18\source.cpp(31): warning C4244: '=': 'double' から 'int' への変換です。データが失われる可能性があります。 1>c:\users\daito\source\repos\project18\project18\source.cpp(33): warning C4244: '引数': 'int' から 'float' への変換です。データが失われる可能性があります。 1>プロジェクト "Project18.vcxproj" のビルドが終了しました -- 失敗。 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== img_srcはunsigned charと関係があるところまでは調べられたのですが、どうやってもimg_srcが定義できません。私はimg_srcを使っていますが愚かなことに定義の仕方がわかりません。 どうかヒントを頂けないでしょうか? どのように調べれば、自力で解決できるヒントが見つかりでしょうか? いつもご迷惑ばかりおかけしますがどうかよそしくお願いいたします。
asm

2018/06/11 10:03

まず改変について teratail内にて掲載したソースコードは自由に改変して構いませんが その結果発生した事象について責任は持てませんし、サポートも負いかねます。 極端な話、改変した結果あなたのHDDが初期化されようが、PCが爆発しようがあなたの責任です。 > img_src[x][y] == 255 以前議論したと思いますが、画像データというのは概ね X座標: 0~3 Y座標: A~Cとした場合 A0 A1 A2 A3 B0 B1 B2 B3 C0 C1 C2 C3 と並んでいます。(実際にはなぜか形式によってY座標が上下逆になってたり、もうちょっとめんどくさい) C言語の2次元配列というのはimg_src[x][y]とimg_src[x][y+1]は連続していますが img_src[x+1][y]は連続していません。 つまりimg_src[x][y]として画素にアクセスするのは無駄にめんどくさいです。 (転置させるだけではあるが) さらに、C言語の2次元配列というのは動的に確保する事ができません。(VLAを除く) よって、img_src[x][y]での画素へアクセスできる配列img_srcを定義する事はほぼ不可能です。 書籍にあったというimg_src[y*width+x]の方は上下が正しいか確認する必要はありますが uchar *img = img.ptr(); で動くかもしれません。
asm

2018/06/11 10:14

もうひとつ問題があります。 int height = 400; int width = 300; 幅・高さをマジックナンバーとして埋め込んでいるせいで 画像ファイルを読み込んでいる意味がありません。 領域外アクセスの原因になりかねません。 img.rowsおよびimg.colsを使うべきです。 もしくは、表示がめんどくさくなりますが画像も配列リテラルとして埋め込んでしまうのも手ではあります。
carnage0216

2018/06/11 14:15

素直にimg.rowsおよびimg.colsを使います。どうもありがとうございます。 あのasmさんが書いてくださったプログラムに関して質問があるのですが、 Mat img = imread("sample.jpg", IMREAD_GRAYSCALE);より読み込んだ画像の画素が255の時に{ count++; x_g += x; y_g += y; }の処理をする。しかしなぜ画像を読み込んだときはimgとしたのにif文で処理する際にはimg.atと名前が変わっているのでしょうか? 個人の解釈としてimg.atは画素を扱う際に使うと載っていたので、読み込んだ画像のデータの画素を直接を扱えるのがimg.atというものなのでimg( y, x )と掛けないのでimg.at( y, x )と書いたのですよね? 画像を読み込みという処理と画素を操作する処理がごっちゃになっていました。 ですが、画素を操作せずに読み込んだ画像の画素を一つの塊として扱えればimg.atを使わずにMat imgのみで画素の値を255にできるかもしれませんが、やり方が思いつかないので、素直に画素を操作するimg.atを使います。 しかし、img.atを使わずに画素を操作するプログラムが載っているサイトなどはないでしょうか?
carnage0216

2018/06/11 14:27

書き忘れていました。asmさんからのプログラムは(img.at(y, x) == 255)に<unsigned char>を付けることでビルドできました。 こちらがプログラムです。 #include <stdio.h> #include <opencv/cv.h> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgcodecs/imgcodecs.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/core/core.hpp> using namespace cv; int main() { Mat img = imread("photoshop-gradation8.jpg", IMREAD_GRAYSCALE); int count = 0; double x_g = 0.0, y_g = 0.0; for (int y = 0; y < img.rows; y++) { for (int x = 0; x < img.cols; x++) { if (img.at<unsigned char>(y, x) == 255) { //img.atの扱う画素が何バイトかわからないためunsigned charを定義することで、unsigned chaによりimg.atの扱う画素が入るメモリが確保できた。 count++; x_g += x; y_g += y; } } } x_g /= count; y_g /= count; Point2f mc = Point2f(x_g, y_g); circle(img, mc, 4, Scalar(100), 2, 4); printf("x: %f y: %f", mc.x, mc.y); imshow("img", img); waitKey(0); return 0; }
asm

2018/06/12 01:37

> img.atと名前が変わっている Mat型の変数imgのメンバ関数atを呼び出しています。 C++のクラスという機能です。 > img( y, x) と掛けないのか ちょっと工夫することでできますが、内部の動作は変わらずメンバ関数の呼び出しです。
carnage0216

2018/06/12 03:37

ちなみに、heightやwidthを定義した際にビルドは出来たのですが、img.rowsやimg.colsを使った時とは違う結果が出ました。というか、重心がとんでもないところにあったりします。 なぜなのでしょうか? heightやwidth自体がただの変数名としてとしか認識されていないのでしょうか? こちらのサイトより https://ideone.com/3gVcUH include <stdio.h>をインクルードして使えているのに今回のプログラムで定義をちゃんとしたのに使えない理由がわかりません。
carnage0216

2018/06/12 04:09

opencvとは別で画素データを収納するために必要なメモリを確保するプログラムです。 #include "image.h" /* List1-2 画像データ作成 width :画像の横幅 height:画像の縦幅 depth :1画素あたりのビット数(8 or 24) */ ImageData* createImage(int width,int height,int depth) { ImageData *newimg; int byte_per_pixel; if(width<0 || height<0) return NULL; if(depth!=8 && depth!=24) return NULL; // 1画素あたりのビット数(8,24以外はエラー) newimg=malloc(sizeof(ImageData)); if(newimg==NULL) return NULL; // 1画素格納するのに必要なバイト数を求める byte_per_pixel=depth/8; // 画像データを格納するのに必要なメモリを確保 newimg->pixels=malloc(sizeof(BYTE)*byte_per_pixel*width*height); if(newimg->pixels==NULL) { free(newimg); return NULL; } // 各プロパティ値を設定 newimg->width=width; newimg->height=height; newimg->depth=depth; return newimg; } このImageData* createImage関数をプログラムに埋め込めれば 画像を読み込むMat img の部分やimg.at<unsigned char>の部分と置き換えて使えるかもしれません。
asm

2018/06/12 04:29

> heightやwidth自体がただの変数名 それ以外のなにだというのでしょうか? > 今回のプログラムで定義をちゃんとしたのに そう豪語する根拠はなんでしょうか? 改変の結果、動作がおかしいのならば 当然、それは改変が間違っています。 まずは、printf("w,h = %d, %d\n", width, height); 等で正しい幅・高さが挿入されているかを確認すべきです。 width,heightが正しい場合でもアラインメントが必要な場合もあり確認すべき事は多いです。 ソースも提示されずに原因・対策を挙げるとこんなところでしょうか。 > opencvとは別で画素データを収納するために必要なメモリを確保するプログラムです。 はぁ、そうですか 見つけたものを嬉しそうに見せびらかされても、私は貴方の飼い主ではないです。 > 画像を読み込むMat img の部分やimg.at<unsigned char>の部分と置き換えて使えるかもしれません。 必要性も利点も感じません。
carnage0216

2018/06/12 04:47 編集

>>見つけたものを嬉しそうに見せびらかされても、私は貴方の飼い主ではないです。 自分があほっぽく見えてきますね。あほなのですが。 >>必要性も利点も感じません。 どのように動いているのか知りたかっただけです。 くだらないこだわりのせいでご迷惑おかけしました。 どうもありがとうございます。
carnage0216

2018/06/12 05:33

ちなみに、asmさんは必要性は別として、opencvとは別に 画素のデータをいじるようなプログラムを作り、プログラムに打ち込んだりは出来るのでしょうか?(width,heightなどの定義、関数の自作など、めちゃくちゃ面倒なことが多いですが) 僕には到底出来ない事ですが、asmさんほどの技術者ならば出来るのではないかと思い質問しました。
asm

2018/06/12 05:54

難しい事ではなく面倒なだけですね (読み込み形式を無圧縮bmp等に限り、画像の表示を行わなければ)
guest

0

mc はモーメントmuから得られた重心
mu.m10 x方向の座標値の総和
mu.m01 y方向の座標値の総和
mu.m00 点の総数
重心は 座標値の平均なので (mu.m10/mu.m00, mu.m01/mu.m00)

...って書いてあった。

Moments muの各メンバ m00, m01, m10 については http://opencv.jp/opencv-2.1/cpp/structural_analysis_and_shape_descriptors.html?highlight=moment#moments
にきっちり書いてある。

muが何を表しているのかわからず困り果てています。

アナタそのmuを求めてるじゃん。

投稿2018/06/07 12:25

編集2018/06/07 12:48
episteme

総合スコア16614

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

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

carnage0216

2018/06/07 15:06 編集

>>アナタそのmuを求めてるじゃん。 とはmu.m10 x方向の座標値の総和 mu.m01 y方向の座標値の総和 mu.m00 点の総数 より 載せました以下のプログラム int count=0; double x_g=0.0,y_g=0.0,x_d=0.0,y_d=0.0,xy_d=0.0 for(int y=0; y<height; y++){ for(int x=0;x<width; x++){ if(img_src[y*width+x] == 255){ count++; x_g +=x; y_g +=y; } } } x_g /=conut; y_g/=count;のプログラムがあるため求めてるじゃんということでしょうか? まあ、確かに載せたプログラムはxとyの総数を画素の総数分で割っているので求めているようなものかもしれません。
episteme

2018/06/07 17:27

"OpenCV Moments"
episteme

2018/06/07 17:29

> ...のプログラムがあるため求めてるじゃんということでしょうか? じゃなかったらそのコードは何だというんです?
carnage0216

2018/06/08 00:30

xとyの総数を画素の総数分を割り平均値(重心の座標)を求めるコードです。 ごめんなさい。わかってはいたのですが、自信がなくてつい悩んでしまいました。
carnage0216

2018/06/08 00:33

後は、このコードをopencvのプログラムと置き換えて動作させたいと思います。
guest

0

こんなのがお望みか?

C++

1#include "opencv2/opencv.hpp" 2 3int main(){ 4 using namespace cv; 5 6 Mat img = imread("sample.jpg", IMREAD_GRAYSCALE); 7 8 // unsigned char* img.data : 画像データの先頭 9 // int img.rows : 幅(pixel) 10 // int img.cols : 高さ(pixel) 11 // size_t img.step : 一行のbyte数 12 int count = 0; 13 float x_g = 0.0f; 14 float y_g = 0.0f; 15 for ( int y = 0; y < img.rows; y++ ) { 16 for ( int x = 0; x < img.cols; x++ ) { 17 if ( img.data[y*img.step + x] == 255 ) { 18 count++; 19 x_g += x; 20 y_g += y; 21 } 22 } 23 } 24 Point2f mc = Point2f( x_g/count, y_g/count); 25 26 circle( img, mc, 4, Scalar(100), 2, 4); 27 28 imshow("img",img); 29 waitKey(0); 30}

!実行結果

投稿2018/06/12 09:37

episteme

総合スコア16614

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

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

carnage0216

2018/06/12 10:01

!? 私が参考にしたサイトのプログラムと少し違いますが、結果が同じ。
episteme

2018/06/12 10:28

ならば「opencvの関数ではない重心を求めるプログラムを入れたい」って願いは叶ったかな。
carnage0216

2018/06/12 11:33

感謝します。いつもいつもご迷惑おかけします。 身近にepistemeさんのような先生が居たらどんなにいいことかと思ってしまいます。 本当にどうもありがとうございます。早速ビルドしてみます。
carnage0216

2018/06/12 12:49

ちなみにどうたってimg_src[y*whide + x]からimg.data[y*img.step + x]を作ったのですか? というかimg.dataとimg.stepをどうやって見つけてきたのですか?
episteme

2018/06/12 18:49

あらかたマニュアルに書いてある。
guest

0

int conut = 0; double x_g = 0.0, y_g = 0.0; for (int y = 0; y<height; y++) { for (int x = 0; x<width; x++) { if (img_src[y*width + x] == 255) { count++; x_g += x; y_g += y; } } } int a; int b; a= x_g / conut; b= y_g / conut;

自分なりに書いたのはココ↑なんでしょ?
自分で書いたコードなら width, height, img_src が何を意味するのかわかってるハズね?

投稿2018/06/09 16:36

episteme

総合スコア16614

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

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

carnage0216

2018/06/10 00:07

widthは画像の幅を求めるための幅を表す変数です。 heightは画像の高さを求めるための高さを表す変数です。img_srcは画像を読み込むための関数です。
episteme

2018/06/10 02:17 編集

それらがヘッダの中にあると? どう考えればその想いに至るわけ? 計算対象となる画像はアナタがimgに読みこんでるんだから、 そいつの幅と高さを手に入れればいいやん。 てかそのものヅバリをasmさんが書いてくれてる。それをガン無視?
carnage0216

2018/06/10 13:47

本当にすいません。無礼を働きました。
episteme

2018/06/10 14:33

いや、わざわざ改悪したのはなんの意図があって?
carnage0216

2018/06/10 14:36

asmさんのプログラムは実行できたのですが、どうしても、 for (int y = 0; y<height; y++) { for (int x = 0; x<width; x++) { if (img_src[y*width + x] == 255) の方でもビルドしたいと思ったためです。いくつかの方法で実行できないかと思ったためです。 要は欲張りなのです。
episteme

2018/06/10 18:38

> インクルードしたヘッダファイルにheight、width、img_srcの定義は書いてあると思ったのですが これはナゼ?
carnage0216

2018/06/11 11:31

参考にしたサイトでは #include <stdio.h> #include "opencv/cv.h" #include "opencv/highgui.h"ヘッダファイルをインクルードしてエラーが出なかったためです。 しかし、今思うとそのサイトではimg_srcを使っていないので私の勘違いでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問