使用“外部”数据来初始化openCV对象(Eigen对象与openCV对象的相互转化)

本文介绍如何在Eigen的Matrix对象与OpenCV的Mat对象之间进行转换,包括使用Eigen::Map进行转换的方法,并通过示例代码展示从Mat到Matrix及反向转换的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文由这个问题引出:
我们知道Eigen与openCV都是c++进行矩阵运算的工具,有时就会碰到这样的问题,如何在Eigen的Matrix对象和openCV的Mat对象间进行转换?比如最开始获取到一个Mat对象,要把他转换为matrix对象进行复杂的矩阵运算(需要用Eigen进行),最后再转换成Mat对象显示出来。
此问题在stackoverflow下的解答如下:

Mat A(20, 20, CV_32FC1);
cv::randn(A, 0.0f, 1.0f); // random data

// Map the OpenCV matrix with Eigen:
Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> A_Eigen(A.ptr<float>(), A.rows, A.cols);

// Do something with it in Eigen, create e.g. a new Eigen matrix:
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> B = A_Eigen.inverse();

// create an OpenCV Mat header for the Eigen data:
Mat B_OpenCV(B.rows(), B.cols(), CV_32FC1, B.data());

可以看出来从Mat转为Matrix是用Eigen::Map来完成的。我们现在单拎从Matrix转到Mat,即这一行:

Mat B_OpenCV(B.rows(), B.cols(), CV_32FC1, B.data());

就是把Matrix对象的指针放了进去。其实可以从更一般的角度来看这个问题,即openCV是可以用“外部“的数据来初始化对象的。我从openCV reference manual(2.4.9)看到一些说明。首先我们都知道openCV对象时由一个头和一个数据部分组成的,比如浅拷贝(使用重载的=运算符)就是只创建一个头,而共享数据部分,深拷贝(copyTo方法和clone方法)就是既会创建头又会创建数据。我们可以为这种”外来“的数据创建一个头,就可以构成openCV的对象了。比如:

void process_video_frame(const unsigned char* pixels,
int width, int height, int step)
{
Mat img(height, width, CV_8UC3, pixels, step);
GaussianBlur(img, img, Size(7,7), 1.5, 1.5);
}

这里直接把const unsigned char*的对象传递进了构造函数里,只要指定高度和宽度,步长,就可以初始化openCV对象img了。还有一个例子是用数组也可以直接初始化openCV对象:

double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};
Mat M = Mat(3, 3, CV_64F, m);

m是一个3x3数组的指针,可以直接用来初始化M。还有openCV1.0和openCV2.0间的转换:

IplImage* img = cvLoadImage("greatwave.jpg", 1);
Mat mtx(img); // convert IplImage* -> Mat

这样可以更深入的理解openCV Mat对象的构成本质。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值