C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: cv::Mat::setTo()でエラー


(過去ログ 134 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■78854 / inTopicNo.1)  cv::Mat::setTo()でエラー
  
□投稿者/ こまお (28回)-(2016/02/21(Sun) 15:56:56)

分類:[C/C++] 

こんにちは

ネットで拾った下記のコードを試しているのですが、"ココ"の所で

>OpenCV Error: Assertion failed (mask.empty() || mask.type() == CV_8U) in setTo,
>file D:\Devz\opencv\sources\modules\core\src\copy.cpp, line 347
>terminate called after throwing an instance of 'cv::Exception'
>  what():  D:\Devz\opencv\sources\modules\core\src\copy.cpp:347: error: (-215) m
>ask.empty() || mask.type() == CV_8U in function setTo

と表示して落ちます。cv::Mat::setTo()の意味が判らないのでエラーの意味も
さっぱりなのですが、識者の方よろしくお願いします。


#include "opencv2/opencv.hpp"
#include <vector>

std::vector<cv::Point> bhContoursCenter(const std::vector<std::vector<cv::Point> >& contours,bool centerOfMass,int contourIdx=-1) {
 std::vector<cv::Point> result;
 if (contourIdx > -1) {
  if (centerOfMass) {
   cv::Moments m = cv::moments(contours[contourIdx],true);
   result.push_back( cv::Point(m.m10/m.m00, m.m01/m.m00));
  }
  else {
   cv::Rect rct = cv::boundingRect(contours[contourIdx]);
   result.push_back( cv::Point(rct.x + rct.width / 2 ,rct.y + rct.height / 2));
  }
 }
 else {
  if (centerOfMass) {
   for (int i=0; i < (int)contours.size();i++) {
    cv::Moments m = cv::moments(contours[i],true);
    result.push_back( cv::Point(m.m10/m.m00, m.m01/m.m00));

   }
  }
  else {

   for (int i=0; i < (int)contours.size(); i++) {
    cv::Rect rct = boundingRect(contours[i]);
    result.push_back(cv::Point(rct.x + rct.width / 2 ,rct.y + rct.height / 2));
   }
  }
 }

 return result;
}

std::vector<cv::Point> bhFindLocalMaximum(cv::Mat const& src,int neighbor=2) {
 cv::Mat peak_img = src.clone();
 dilate(peak_img,peak_img,cv::Mat(),cv::Point(-1,-1),neighbor);
 peak_img = peak_img - src;

 cv::Mat flat_img ;
 erode(src,flat_img,cv::Mat(),cv::Point(-1,-1),neighbor);
 flat_img = src - flat_img;

 threshold(peak_img,peak_img,0,255,CV_THRESH_BINARY);
 threshold(flat_img,flat_img,0,255,CV_THRESH_BINARY);
 bitwise_not(flat_img,flat_img);

    cv::imshow("AAA", flat_img);
    cv::imshow("BBB", peak_img);
    cv::waitKey();

 peak_img.setTo(cv::Scalar::all(255),flat_img); //ココ
 bitwise_not(peak_img,peak_img);

 std::vector<std::vector<cv::Point> > contours;
 findContours(peak_img,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);

 return bhContoursCenter(contours,true);
}

int main(void) {
 cv::namedWindow("AAA", 1);
 cv::namedWindow("BBB", 1);

 cv::Mat src = cv::imread("test.bmp", 1);

 cv::imshow("AAA", src);
 cv::waitKey();

 std::cout << bhFindLocalMaximum(src).size() << std::endl;
}

引用返信 編集キー/
■78856 / inTopicNo.2)  Re[1]: cv::Mat::setTo()でエラー
□投稿者/ Azulean (602回)-(2016/02/21(Sun) 16:44:31)
No78854 (こまお さん) に返信
> >OpenCV Error: Assertion failed (mask.empty() || mask.type() == CV_8U) in setTo,
> >file D:\Devz\opencv\sources\modules\core\src\copy.cpp, line 347

setto の第 2 引数に書かれている要素が「空」か、「8bit の 1 チャンネル」のいずれかでなければならないということでしょう。
この変数の出典をたどると、bmp から読み込んでいるようですし、CV_8UC3 となっているでしょうから、不適切な組み合わせ、あるいは利用方法なのでは?


> cv::Mat::setTo()の意味が判らないのでエラーの意味も
> さっぱりなのですが、識者の方よろしくお願いします。

厳しいことを言えば「わからない状態で使おうとしないこと」です。
サンプルで出てきた関数が参考になりそうなら、関数について調べることから始めるべきです。

誰かが書いたコードを適当に組み合わせることで動くかもしれませんが、そういう風に作り上げたプログラムはきちんと動かないか、たまに動かないかなどといった結末を招きますし、そうなったとしても自分の理解度が低いために不具合を直せません。
調べる・理解するを意識して取り組みましょう。
引用返信 編集キー/
■78925 / inTopicNo.3)  Re[2]: cv::Mat::setTo()でエラー
□投稿者/ こまお (29回)-(2016/02/24(Wed) 16:57:41)
No78856 (Azulean さん) に返信
> 厳しいことを言えば「わからない状態で使おうとしないこと」です。
> サンプルで出てきた関数が参考になりそうなら、関数について調べることから始めるべきです。
>
> 誰かが書いたコードを適当に組み合わせることで動くかもしれませんが、そういう風に作り上げたプログラムはきちんと動かないか、たまに動かないかなどといった結末を招きますし、そうなったとしても自分の理解度が低いために不具合を直せません。
> 調べる・理解するを意識して取り組みましょう。

おっしゃるとおりです。
とりあえず使えそうかどうか当たりをつけたい段階でして、
詳しく調べるのはそれからにしたいと。#ごめんなさい
引用返信 編集キー/
■78936 / inTopicNo.4)  Re[3]: cv::Mat::setTo()でエラー
□投稿者/ ビール呑み (1回)-(2016/02/24(Wed) 19:13:19)
No78925 (こまお さん) に返信
> とりあえず使えそうかどうか当たりをつけたい段階でして、
> 詳しく調べるのはそれからにしたいと。#ごめんなさい

うーん、それでいいと思いますけどねぇ。

「わからないから教えてください」→「自分で調べて」
「やってみたけどわかりません」→「わからないのが罪」
では結局何も進まないし、せっかくの掲示板の意義がなくなっちゃうと
思うんですよ。

まあ、Azuleanさんのお眼鏡には適わないにしても、
他にもいっぱい回答者さんがいらっしゃるので、
気長に待っていればいいんじゃないでしょうか。

(私に回答のスキルがないことを深くお詫び申し上げます。m(_ _)m)

引用返信 編集キー/
■78937 / inTopicNo.5)  Re[4]: cv::Mat::setTo()でエラー
□投稿者/ 774RR (378回)-(2016/02/24(Wed) 19:32:45)
まあ、自分ぢゃ何一つ調べる気がありませーん、って公言してる奴を手助けする義理もないけどな。
オイラも気長に暇人が現れるのを待つことにしましょう。
引用返信 編集キー/
■78939 / inTopicNo.6)  Re[4]: cv::Mat::setTo()でエラー
□投稿者/ Azulean (603回)-(2016/02/24(Wed) 22:04:31)
2016/02/24(Wed) 22:27:24 編集(投稿者)

No78925 (こまお さん) に返信
> とりあえず使えそうかどうか当たりをつけたい段階でして、
> 詳しく調べるのはそれからにしたいと。#ごめんなさい

誤解しないでいただきたいのですが、私は謝罪を求める意図は持っていません。
元の私の投稿は「質問に対するある程度の回答」を示し、その上で「自分の経験・知識に基づいた懸念」を示すという形をとらせていただいたつもりです。

「ある程度の回答」となっているのは、OpenCV での画像処理を扱っているので、ある程度以上の知識・理解度を期待したいということからです。
CV_8U や CV_8UC3 が何を示すのかを把握できていないと意味不明な言葉に見えますが、逆に言えばこれを理解できていないと、画像処理は苦しいです。
掲示板といった媒体で1から10まで説明するわけにもいきませんし、質問者の方の理解度も不明瞭であったため、「ある程度に回答」にとどめた次第です。

また、C/C++ 言語では「間違って使うことができるが、間違えた箇所以外の場所でエラーになるなどして、原因特定が困難になりやすい」ものです。
ゆえに、「試しに使ってみる」ためにも「少しは関数の役割・入出力を知る」ことは必要だと思っています。
そういった事情があることもご理解いただければ幸いです。


-----追伸
あと一点書けてなかったのですが、cv::Mat::setTo は「第 2 引数が CV_8U のマスク画像であり、そのマスク画像に従って、第 1 引数の値で上書きする」です。
目的をかなえる関数であるならば、第 2 引数をマスク画像にしなければなりません。マスク画像にできているならピクセルフォーマットを変換すればいいでしょう。

// 膨張させた画像と、縮退させた画像を作って、さらにそれぞれの画像から元画像を引いて膨張した際に増えた画素の画像と、縮退したときに減った画素の画像を作っている?
// さらに縮退したときに減った画素の画像を反転し、その部分を膨張した際に増えた画素の画像でセットしている?
// そして、その結果を反転して何かしてるところまでは把握。
// その路線が合っているなら、ピクセルフォーマット変換だけでよいでしょうね。
引用返信 編集キー/
■79199 / inTopicNo.7)  Re[5]: cv::Mat::setTo()でエラー
□投稿者/ こまお (30回)-(2016/03/15(Tue) 10:29:17)
  解決しました。ヒントをくださった方、ありがとうございました。

int main(void) {

	// ...略

	cv::cvtColor(src, src, CV_RGB2GRAY); //追加
	std::cout << bhFindLocalMaximum(src).size() << std::endl;
}

  自分で調べる気が無いわけではなくて、自分も調べるけれど、既に知ってい
る人、あるいは一緒に調べてくれる人がいたらうれしいな。みたいな感じで書
いてました。気分を害された方はごめんなさい。

  それでは、また来ます。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -