OpenCV 常用操作 | C & C++
本文最后更新于:2022年6月30日
遍历像素点
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;
}
}
unsigned char *data = mat.ptr<unsigned char>();
float *data = mat.ptr<float>();
BGR -> YUV
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
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 的定义和初始化
- 默认形式
cv::Mat m;
- 指定类型和大小(行列)的二维数组
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 |
- 有初始化值的指定类型和大小(行列)的二维数组
cv::Mat m(int rows, int cols, int type, const Scalar& value);
- 指定大小(size)和类型的二维数组
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)和类型的二维数组
cv::Mat m(cv::Size sz, int type, void* data, size_t step = AUTO_STEP);
- 指定类型的多维数组
cv::Mat m(int ndims, const int* sizes, int type);
- 有初始化值的指定类型多维数组
cv::Mat m(int ndims, const int* sizes, int type, const Scalar& value);
- 使用预先存在的数据定义的指定类型的多维数组
cv::Mat m(int ndims, const int* sizes, int type, void* data, size_t step = AUTO_STEP);
从其他 cv::Mat 进行数据拷贝的定义和初始化
- 拷贝构造形式
cv::Mat m(const cv::Mat& mat);
- 指定行列范围的拷贝构造
cv::Mat m(const cv::Mat& mat, const cv::Range& rows, const cv::Range& cols);
- 指定 ROI 的拷贝构造
cv::Mat m(const cv::Mat& mat, const cv::Rect& roi);
- 使用多维数组中指定范围内的数据的拷贝构造
cv::Mat(const cv::Mat& mat, const cv::Range* ranges);
使用 OpenCV 中的模板进行定义和初始化
- 相同类型、大小为 n 的一维数组
cv::Mat m(const cv::Vec<T, n>& vec, bool = copyData = true);
- 使用cv::Matx定义相同类型、大小为mxn的二维数组
cv::Mat(const cv::Matx<T, m, n>& vec, bool copyData = true);
- 使用 std::vector 定义相同类型的一维数组
cv::Mat(const std::vector<T>& vec, bool copyData = true);
直接使用静态函数创建 cv::Mat
- 值全为 0
cv::Mat m = cv::Mat::zeros(int rows, int cols, int type);
- 值全为 1
cv::Mat m = cv::Mat::ones(int rows, int cols, int type);
- 单位矩阵
cv::Mat m = cv::Mat::eye(int rows, int cols, int type);
评论系统采用 utterances ,加载有延迟,请稍等片刻。