OpenCV 常用操作 | C & C++

本文列举了一些 OpenCV 中常用的函数。

遍历像素点

1
2
3
4
5
6
7
for (int i = 0; i < mat.rows; ++i) {
for (int j = 0; j < mat.cols; ++j) {
std::cout << (float)mat.at<cv::Vec3b>(i,j)[0] << std::endl;
std::cout << (float)mat.at<cv::Vec3b>(i,j)[1] << std::endl;
std::cout << (float)mat.at<cv::Vec3b>(i,j)[2] << std::endl;
}
}
1
2
unsigned char *data = mat.ptr<unsigned char>();
float *data = mat.ptr<float>();

BGR -> YUV

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void YUVI420ToNV12(unsigned char* i420bytes, unsigned char* nv12bytes, int width, int height) {
int nLenY = width * height;
int nLenU = nLenY / 4;

memcpy(nv12bytes, i420bytes, width * height);

for (int i = 0; i < nLenU; i++) {
nv12bytes[nLenY + 2 * i] = i420bytes[nLenY + i]; // U
nv12bytes[nLenY + 2 * i + 1] = i420bytes[nLenY + nLenU + i]; // V
}
}

void BGRToYUVNV12(cv::Mat src, cv::Mat &dst) {
int w_img = src.cols;
int h_img = src.rows;
dst = cv::Mat(h_img*1.5, w_img, CV_8UC1, cv::Scalar(0));
cv::Mat src_YUV_I420(h_img*1.5, w_img, CV_8UC1, cv::Scalar(0)); //YUV_I420
cv::cvtColor(src, src_YUV_I420, CV_BGR2YUV_I420);
swapYUV_I420toNV12(src_YUV_I420.data, dst.data, w_img, h_img);
}

HWC -> CHW

1
2
3
4
5
6
7
8
9
void HWCToCHW(const cv::Mat& src, float *dst) {
std::vector<Mat> vec;
cv::split(src, vec);
int hw = src.rows * src.cols;
memcpy(dst + hw * 0, vec[0].data, hw * sizeof(float));
memcpy(dst + hw * 1, vec[1].data, hw * sizeof(float));
memcpy(dst + hw * 2, vec[2].data, hw * sizeof(float));
}

初始化

无数据拷贝的 cv::Mat 的定义和初始化

  • 默认形式
1
cv::Mat m;
  • 指定类型和大小(行列)的二维数组
1
cv::Mat m(int rows, int cols, int type);

关于 type:

基本类型 C1(或留空) C2 C3 备注
CV_8U 0 8 16 unsigned int
CV_8S 1 9 17 signed int
CV_16U 2 10 18 unsigned int
CV_16S 3 11 19 signed int
CV_32S 4 12 20 signed int
CV_32F 5 13 21 float
CV_64F 6 14 22 float
  • 有初始化值的指定类型和大小(行列)的二维数组
1
cv::Mat m(int rows, int cols, int type, const Scalar& value);
  • 指定大小(size)和类型的二维数组
1
2
cv::Mat m(int rows, int cols, int type, void* data, size_t step = AUTO_STEP);
cv::Mat m(cv::Size sz, int type, const Scalar& value);

其中 step 参数表示两个相邻行同列数据之间的距离,设为 AUTO_STEP 时两个相邻行在内存中是连续的,所以 step 为 width

  • 使用预先存在的数据定义的指定大小(size)和类型的二维数组
1
cv::Mat m(cv::Size sz, int type, void* data, size_t step = AUTO_STEP);
  • 指定类型的多维数组
1
cv::Mat m(int ndims, const int* sizes, int type);
  • 有初始化值的指定类型多维数组
1
cv::Mat m(int ndims, const int* sizes, int type, const Scalar& value);
  • 使用预先存在的数据定义的指定类型的多维数组
1
cv::Mat m(int ndims, const int* sizes, int type, void* data, size_t step = AUTO_STEP);

从其他 cv::Mat 进行数据拷贝的定义和初始化

  • 拷贝构造形式
1
cv::Mat m(const cv::Mat& mat);
  • 指定行列范围的拷贝构造
1
cv::Mat m(const cv::Mat& mat, const cv::Range& rows, const cv::Range& cols);
  • 指定 ROI 的拷贝构造
1
cv::Mat m(const cv::Mat& mat, const cv::Rect& roi);
  • 使用多维数组中指定范围内的数据的拷贝构造
1
cv::Mat(const cv::Mat& mat, const cv::Range* ranges);

使用 OpenCV 中的模板进行定义和初始化

  • 相同类型、大小为 n 的一维数组
1
cv::Mat m(const cv::Vec<T, n>& vec, bool = copyData = true);
  • 使用cv::Matx定义相同类型、大小为mxn的二维数组
1
cv::Mat(const cv::Matx<T, m, n>& vec, bool copyData = true);
  • 使用 std::vector 定义相同类型的一维数组
1
cv::Mat(const std::vector<T>& vec, bool copyData = true);

直接使用静态函数创建 cv::Mat

  • 值全为 0
1
cv::Mat m = cv::Mat::zeros(int rows, int cols, int type);
  • 值全为 1
1
cv::Mat m = cv::Mat::ones(int rows, int cols, int type);
  • 单位矩阵
1
cv::Mat m = cv::Mat::eye(int rows, int cols, int type);
作者

zhongtian

发布于

2020-10-18

更新于

2023-12-16

许可协议

评论