シヨツ鬼のブログ

初心者向けに分かりやすくIT関連の情報を発信しています。

【OpenCV C++】「識別子CV_BGR2GRAYが定義されていません」となって困っているそこのあなたへ

f:id:shiyotsuki:20200418125446p:plain

どうも、プログラミングの鬼シヨツ鬼です。

この記事では「OpenCV使ってたら『識別子CV_BGR2GRAYが定義されていません』って出てきて困っているぜ」って人に向けて、その解決方法をずばり解決しています。

 

解決方法

結論から言うと、「CV_BGR2GRAY」を「cv::COLOR_BGR2GRAY」に書き換えて使ってください。

 

とりあえず、これで解決します。

ただ、今後もOpenCVを使っていく中で、このような事象にはよく出会うことになると思いますので、↓の原因についても読んでおくことをお勧めします。

というか、頑張って書いたので、絶対読んでください。

 

『識別子CV_BGR2GRAYが定義されていません』とエラーが出る原因は?

 これは、エラーに書いてある通り、「CV_BGR2GRAYが定義されていないよ」という意味です。

ただ、この説明だけだと、あまりにもそのまんま過ぎる説明なので、もう少し詳しく説明します。

 

例えば、C++で変数を使うときは「int i;」みたいな感じで宣言を行いますよね?

いきなり「i=29;」みたいな感じで使うとエラーになると思います。

 

これと同じで、「CV_BGR2GRAY」はどこにも宣言されていないので、エラーが出るわけです。

 

すると、「いやいや、僕は公式クックブックからコピペして使っているんだぞ!公式クックブックが間違っているはずがないじゃないか!」と思う人もいると思います。

 

例えば、↓に示す公式クックブックの「色空間を変換する」のサンプルプログラムだと、「CV_BGR2HSV」なんか、どこにも宣言されずに使われているように見えます。

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

int
main(int argc, char *argv[])
{
  cv::Mat bgr_img = cv::imread("../../image/lenna.png", 1);
  if(bgr_img.empty()) return -1; 
  
  cv::Mat dst_img;

  // BGR -> HSV
  cv::cvtColor(bgr_img, dst_img, CV_BGR2HSV);
  // ... 何らかの処理
  
  // BGR -> Lab
  cv::cvtColor(bgr_img, dst_img, CV_BGR2Lab);
  // ... 何らかの処理

  // BGR -> YCrCb
  cv::cvtColor(bgr_img, dst_img, CV_BGR2YCrCb);
  // ... 何らかの処理  
}

opencv.jp

 

上記のサンプルコードでは、最初の3行で「include」が書かれています。

実はここがミソです。 

つまり、ここで別のプログラムが参照されているわけです。

 

この参照先のどこかで「CV_BGR2HSV」や「CV_BGR2GRAY」が定義されているため、宣言せずに使うことができるというわけなのです。

 

 じゃあ、なぜこのクックブックを同じようにコピペしたあなたは定義されていないと怒られるのか?

 

それはこのクックブックが古い(OpenCV ver2.4.0が対象)からです

 

実は、OpenCVはバージョン4より、古いAPIがいろいろと削除されたらしいです。

その削除されたものの一つが「CV_BGR2GRAYの定義」だったわけです。

 

ちなみに、新しく使う「COLOR_BGR2GRAY」の定義は「C:\opencv\build\include\opencv2\imgproc.hpp」ファイルの中でされています。

f:id:shiyotsuki:20200418124938p:plain

ここで定義されている

まとめ

includeはおまじないなんかじゃない。

最後まで読んでくれてありがとう。
参考になったら「☆」を押してね。