4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

もう(x,y)?(y,x)?で迷わない!OpenCVの引数順序ルールのおさらい

4
Last updated at Posted at 2025-12-17

■ TL;DR

  • (x,y) デカルト座標系、 cv::Point, cv::Rect, cv::Size 全部共通
  • [y,x] メモリアクセス、cv::at
  • Mat(cols, rows)が分かりにくいなら、Mat(Size(width, height)) でエンバグ回避!

■ はじめに

とても悲しいバグがあったのです...

Animation GIFで、元の背景画像を書き戻すときに何も起きない、というバグでした。こちらはパッチを出していただいたのですが・・・

- restore = Mat(width, height, CV_8UC4, background);
+ restore = Mat(height, width, CV_8UC4, background);

原因は、幅・高さ指定を間違えたために、その後の処理でOpenCVさんが「コピー元とコピー先でサイズが違うん?よっしゃー、じゃ、新しいメモリ用意したるわー」って張り切って、それで悲しい事が起きたのです。

こういう悲劇が二度と繰り返されないように、copyAt()関数が追加されました。

さて、それでは今一度、OpenCV Libraryにおける「XとY」の指定方法をまとめておきます。

■ デカルト座標系を使うとき = OpenCVのクラスで使うなら (x,y)

imgprocmoduleのdrawing functionなどでデカルト座標系を使う時は、代数幾何学と同様に(x,y)の順番になります。

例1)cv::Point

例2)cv::Rect

例3)cv::Size

■ 直接メモリアクセスするときは (y,x)

直接メモリアクセスしたい場合(=デカルト座標系が関わらない場合)は、(y,x)の順番になります

例)cv::Mat::Mat()

例2) cv::Mat::at()

■ cols? rows? 分からなくなっちゃう → Size()でwrapping

とはいえ、colsとかrowsとか言われても、どっちがどっちか分からなくなりますよね!その気持ち痛いほどよく分かります!!でもご安心ください! cv::Size()があります!

例えばの、サンプルコードは以下になります。 cv::Sizecv::Pointを使う事で、x,y座標表現になるので、ずいぶん人間にとっては読みやすくなりますね!

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

int main(void)
{
  // cols/rows表現は馴れないが・・・
  cv::Mat srcA(5, 3, CV_8UC1, cv::Scalar(0,0,0));
  srcA.at<uchar>(2, 1) = 1;
  std::cout << "srcA(5, 3)      " << srcA.size() << std::endl;
  std::cout << srcA << std::endl;

  // Size/Point使って(x,y)表現は分かりやすい!
  cv::Mat srcB(cv::Size(3, 5), CV_8UC1, cv::Scalar(0,0,0));
  srcB.at<uchar>(cv::Point(1, 2)) = 1;
  std::cout << "srcB(Size(3, 5))" << srcB.size() << std::endl;
  std::cout << srcB << std::endl;
  return 0;
}
kmtr@kmtr-VMware-Virtual-Platform:~/work/temp/a$ ./a.out
srcA(5, 3)      [3 x 5]
[  0,   0,   0;
   0,   0,   0;
   0,   1,   0;
   0,   0,   0;
   0,   0,   0]
srcB(Size(3, 5))[3 x 5]
[  0,   0,   0;
   0,   0,   0;
   0,   1,   0;
   0,   0,   0;
   0,   0,   0]

つまり、cv::Point cv::Rect cv::Sizeを使うときは、(x,y)の並びになる、という法則だけ覚えておけば万事解決オールオッケーです!!

この書き方の何がうれしいかというと、Mat::Matするときの引数の順番が、cv::Point(x,y)なんかと表現方法を全く同じにできる点ですね!これなら間違えない!!:relaxed:

■ まとめ

  • (x,y) デカルト座標系、 cv::Point, cv::Rect, cv::Size 全部共通
  • [y,x] メモリアクセス、cv::at
  • Mat(cols, rows)が分かりにくいなら、Mat(Size(width, height)) でエンバグ回避!

以上です、ありがとうございました!

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?