opencv_usage
保存图片
1 |
|
cv::Mat
基础概念
OpenCV:Mat中的step、elemSize、channel和任意内存访问
判断是否连续
isContinuous() 方法可以判断一个 cv::Mat 对象是否在内存中是连续的。
如果是连续的返回 true,如果在每一行的结尾跳过一部分内存地址到达下一行,那么就会返回 false。
所以很显然,1x1 和 1xN 的对象一定是连续的,因为只有一行数据。
使用 cv::Mat::create
创建的对象也是连续的,表示直接开辟了一个连续的内存空间进行对象的创建。
但是,如果从一个 cv::Mat 对象中截取了一部分数据,或者构造数据来自外部存储的数据,那么就不一定是连续的了。
1 |
|
非连续Mat 如何拷贝
非连续是指行之间的地址是间断的,但是同一行的内存是连续,所以可以按行复制
下面是把非连续的 Mat 复制给vector.data(),
把非连续变成了连续,如果不关注连续还是非连续,可以直接
a_mat.copyTo(b_mat) 1
2
3
4
5
6
7
8
9
10
11// apollo
void BEVObstacleDetector::Mat2Vec(const cv::Mat &im, float *data) {
ACHECK(nullptr != data);
int rh = im.rows;
int rw = im.cols;
int rc = im.channels();
for (int i = 0; i < rc; ++i) {
cv::extractChannel(im, cv::Mat(rh, rw, CV_32FC1, data + i * rh * rw), i);
}
}
深拷贝与浅拷贝
1 |
|
cv::cuda::GpuMat
cuda kernel 访问 GpuMat
GpuMat的数据在gpu 上,那么如何在 cuda kernel 中访问 GpuMat 呢?可以直接访问吗,答案是不可以,因为 cuda kernel 不可以传入不带__device__修饰的构造和析构的对象,就是说GpuMat 的构造和析构没有用__device__修饰,所以无法直接传递给kernel
opencv 提供了一个 PtrStepSz 类,其构造和析构函数是用__device__修饰的,所以可以传递给kernel。
另外一个问题是 GpuMat 是如何转化为 PtrStepSz 的,在GpuMat 的成员函数实现了GpuMat 到 PtrStepSz 的类型转换,因此在调用kernel 的时候直接传递GpuMat,而在kernel 的形参中用 PtrStepSz 进行接收
详细说明: https://stackoverflow.com/questions/73171101/how-does-cvcudagpumat-turn-into-cvcudaptrstepsz-when-passed-to-a-kernel
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!