c++ - opencv多 channel 元素访问

标签 c++ image image-processing opencv

我正在尝试学习如何使用 OpenCV 的新 C++ 接口(interface)。

如何访问多 channel 矩阵的元素?例如:

Mat myMat(size(3, 3), CV_32FC2);

for (int i = 0; i < 3; ++i)
{
    for (int j = 0; j < 3; ++j)
    {
        //myMat_at_(i,j) = (i,j);
    }
}

最简单的方法是什么?类似于旧界面的 cvSet2D。
最有效的方法是什么?类似于在旧接口(interface)中使用直接指针。

最佳答案

typedef struct elem_ {
        float f1;
        float f2;
} elem;
elem data[9] = { 0.0f };
CvMat mat = cvMat(3, 3, CV_32FC2, data );

float f1 = CV_MAT_ELEM(mat, elem, row, col).f1;
float f2 = CV_MAT_ELEM(mat, elem, row, col).f2;

CV_MAT_ELEM(mat, elem, row, col).f1 = 1212.0f;
CV_MAT_ELEM(mat, elem, row, col).f2 = 326.0f;

更新:适用于 OpenCV2.0

1。选择一种类型来表示元素

Mat(或 CvMat)有 3 个维度:行、列、 channel 。
我们可以通过指定行和列来访问矩阵中的一个元素(或像素)。

CV_32FC2表示元素是 32 位浮点值,有 2 个 channel 。
所以上面代码中的 elem 是 CV_32FC2 的一种可接受的表示形式。 .

您可以使用您喜欢的其他表示。例如:

typedef struct elem_ { float val[2];    } elem;
typedef struct elem_ { float x;float y; } elem;

OpenCV2.0 增加了一些新的类型来表示矩阵中的元素,比如:

template<typename _Tp, int cn> class CV_EXPORTS Vec // cxcore.hpp (208)

所以我们可以使用 Vec<float,2>代表CV_32FC2 ,或使用:

typedef Vec<float, 2> Vec2f; // cxcore.hpp (254)

查看源代码以获取更多可以代表您的元素的类型。
这里我们使用Vec2f

2。访问元素

访问 Mat 类中元素的最简单有效的方法是 Mat::at。
它有 4 个重载:

template<typename _Tp> _Tp& at(int y, int x);                // cxcore.hpp (868)
template<typename _Tp> const _Tp& at(int y, int x) const;    // cxcore.hpp (870)
template<typename _Tp> _Tp& at(Point pt);                    // cxcore.hpp (869)
template<typename _Tp> const _Tp& at(Point pt) const;        // cxcore.hpp (871)
// defineded in cxmat.hpp (454-468)

// we can access the element like this :
Mat m( Size(3,3) , CV_32FC2 );
Vec2f& elem = m.at<Vec2f>( row , col ); // or m.at<Vec2f>( Point(col,row) );
elem[0] = 1212.0f;
elem[1] = 326.0f;
float c1 = m.at<Vec2f>( row , col )[0]; // or m.at<Vec2f>( Point(col,row) );
float c2 = m.at<Vec2f>( row , col )[1];
m.at<Vec2f>( row, col )[0] = 1986.0f;
m.at<Vec2f>( row, col )[1] = 326.0f;

3。与旧界面交互

Mat提供2个转换函数:

// converts header to CvMat; no data is copied     // cxcore.hpp (829)
operator CvMat() const;                            // defined in cxmat.hpp
// converts header to IplImage; no data is copied
operator IplImage() const;

// we can interact a Mat object with old interface :
Mat new_matrix( ... );
CvMat old_matrix = new_matrix;  // be careful about its lifetime
CV_MAT_ELEM(old_mat, elem, row, col).f1 = 1212.0f;

关于c++ - opencv多 channel 元素访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1824787/

相关文章:

c++ - 在 placement new 中输入信息

c++ - 从 Python 调用 C/C++?

c++ - 将 uint8_t* 更改为 char*?

c++ - 我可以通过使用 Wt 作为我的 Web 框架来完全隐藏 Web 应用程序中的 "behind"C 代码吗?

javascript - jQuery 跳转到元素

image - 如何将RGB图像转换为单 channel 灰度图像,并使用python保存它?

java - 如何保存程序中的更改?

java - 解密位图的像素

image-processing - 仅使用预训练的 torchvision 网络的某些层

c++ - OpenCV 调整质量