opencv多通道元素访问 我正在努力学习如何使用OpenCV的新C++接口。

opencv多通道元素访问 我正在努力学习如何使用OpenCV的新C++接口。,c++,image,image-processing,opencv,C++,Image,Image Processing,Opencv,如何访问多通道矩阵的元素。例如: 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); } } Mat myMat(尺寸(3,3),CV_32FC2); 对于(int i=0;ic++转换的信息,请查看此链接:谢谢,但不是我想要的。您使用的是CvMat-旧的(

如何访问多通道矩阵的元素。例如:

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);
    }
}
Mat myMat(尺寸(3,3),CV_32FC2);
对于(int i=0;i<3;++i)
{
对于(int j=0;j<3;++j)
{
//(i,j)=(i,j);
}
}
最简单的方法是什么?类似于旧接口的cvSet2D
最有效的方法是什么?类似于在旧接口中使用直接指针

多谢各位

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个维度:行、列、通道。
我们可以通过指定行和列来访问矩阵中的一个元素(或像素)。

CV_32FC2
表示元素为32位浮点值,有2个通道。
因此,上述代码中的元素是
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)
查看源代码以获取更多可以表示元素的类型。
这里我们使用
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;

Vic您必须使用Vec3b而不是Vec3i:

for (int i=0; i<image.rows; i++)
{
    for (int j=0; j<image.cols; j++)
    {
        if (someArray[i][j] == 0)
        {
            image.at<Vec3b>(i,j)[0] = 0;
            image.at<Vec3b>(i,j)[1] = 0;
            image.at<Vec3b>(i,j)[2] = 0;
        }
    }
}

for(int i=0;i您可以直接访问底层数据数组:

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

myMat.ptr<float>(y)[2*x]; // first channel
myMat.ptr<float>(y)[2*x+1]; // second channel
Mat myMat(尺寸(3,3),CV_32FC2);
myMat.ptr(y)[2*x];//第一个通道
myMat.ptr(y)[2*x+1];//第二个通道

它取决于您使用的Mat的数据类型,如果它是类似于CV_32FC1的数字 您可以使用:

myMat.at<float>(i, j)
myMat.at(i,j)
如果是uchar类型,则可以使用

(symb.at<Vec3b>(i, j)).val[k]
(symb.at(i,j)).val[k]

K是通道,灰度图像为0,彩色为

< P> 3。用C++ API访问多通道数组的最佳方法是用PTR方法创建特定行的指针。 比如,

type elem=matrix.ptr(i)[N~c~*j+c]

其中

  • 类型:数据类型(float、int、char等)
  • i:您感兴趣的那一排
  • Nc:通道数
  • j:您感兴趣的专栏
  • c:您感兴趣的专栏(0-3)

有关其他c->c++转换的信息,请查看此链接:

谢谢,但不是我想要的。您使用的是CvMat-旧的(1.1版)c API。我希望新的(2.0a)使用类似的方法C++类API使用了Mat类。有什么类似的类吗?我很抱歉。我忘记了OpenCV2.0已经发布了。我下载了2个源,找到了一些方法来达到你的目标。看看更新的代码。有没有更好的方法来访问CVMAT WiHTOW,使用CVYMatthelEm,比如CVYMattheleM(OLDYMAT,ELEM,行,COL)。.f1??在f1或f2固定的情况下,我们无法通过编程方式迭代矩阵,即i,j indexIt Worth说y是图像行,x是图像列。您需要将x乘以2,因为您有2个通道,并且在OpenCV中,图像以行的主要顺序表示为高度x宽度x通道矩阵。
myMat.at<float>(i, j)
(symb.at<Vec3b>(i, j)).val[k]