c++ - 访问 3 channel 矩阵的元素

标签 c++ opencv

下面的代码用于访问转换为矩阵的 3 个 RGB 图像的元素,并将它们放在一个更大的矩阵中。但是,我知道 CV_MAT_ELEM(mat, type, row, col) 仅用于访问单 channel 矩阵的元素,而我的图像都是 3 channel 的。那么我是否会着手修复此代码以访问 3 channel 矩阵而不是单 channel 矩阵的元素?

#include "cv.h" 
#include "highgui.h" 
#include "iostream" 

using namespace std; 

void cvDoubleMatPrint (const CvMat* mat)
{
int i, j;
for (i = 0; i < mat->rows; i++)
{
for (j = 0 ; j < mat->cols; j++)
{
    printf ( "%f ", cvGet2D (mat, i , j));
}
printf ( "\n" );
}
}


int main( int argc, char* argv ) 
{ 
CvMat *img0, *img1, *img2,  *img0_mat, *img1_mat, *img2_mat, *col0, *col1, *col2, *superMat = NULL;

img0 = cvLoadImageM("C:\\small\\walk mii.jpg", CV_LOAD_IMAGE_UNCHANGED);    
img1 = cvLoadImageM("C:\\small\\wave mii.jpg", CV_LOAD_IMAGE_UNCHANGED);  
img2 = cvLoadImageM("C:\\small\\fantasy.jpg", CV_LOAD_IMAGE_UNCHANGED); 

CvMat img0_header ,img1_header, img2_header;

col0 = cvReshape(img0, &img0_header, 0, 4800);
col1 = cvReshape(img1, &img1_header, 0, 4800);
col2 = cvReshape(img2, &img2_header, 0, 4800);

superMat = cvCreateMat(4800, 3, CV_8UC1);
cvSetZero(superMat);

for(int i=0; i<col0->height; i++)
{
CV_MAT_ELEM( *superMat, double, i, 0 ) = CV_MAT_ELEM( *col0, double, i, 0 );
}

for(int j=0; j<col1->height; j++)
{
CV_MAT_ELEM( *superMat, double, j, 1 ) = CV_MAT_ELEM( *col1, double, j, 0 );
}

 for(int k=0; k<col2->height; k++)
{
CV_MAT_ELEM( *superMat, double, k, 2 ) = CV_MAT_ELEM( *col2, double, k, 0 );
}


cvDoubleMatPrint(superMat);

cvWaitKey(0);
return 0;

最佳答案

我对 C API 不太熟悉,但这里介绍了如何使用 C++ API 完成您正在做的事情。

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

int main(int /*argc*/, char** /*argv*/)
{
    cv::RNG rng = cv::theRNG();

    // create 3 random 10x10 matrices to simulate your situation.
    vector<Mat> matrices;
    for(int i = 0; i < 3; i++)
    {
        Mat temp(Size(10, 10), CV_64FC3);
        rng.fill(temp, RNG::UNIFORM, 0.0, 1.0);
        matrices.push_back(temp);
    }

    // reshape the matrices to have 1 row and 1 channel (i.e., 10x10x3 -> 300x1).
    vector<Mat> singleRows;
    vector<Mat>::iterator i;
    for(i = matrices.begin(); i != matrices.end(); i++)
    {
        singleRows.push_back(i->reshape(1, 1));
    }

    // finally, concatenate the matrices to make a 300x3 matrix.
    Mat concatenated;
    for(i = singleRows.begin(); i != singleRows.end(); i++)
    {
        concatenated.push_back(i->clone());
    }

    cout << concatenated.size().width << "x" << concatenated.size().height << endl;

    return 0;
}

如果您需要在 C++ API 中访问 RGB 值,请参阅我的 other post关于如何使用 cv::Vec3b 类。一般来说,我建议使用 C++ API 而不是 C API,因为它具有更多功能并且更易于使用。另外,看看 OpenCV 函数 splitmerge .这些功能对于多 channel 管理很有用。希望对您有所帮助!

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

相关文章:

c++ - For循环添加到一个变量

C++ 在结构初始化期间出现奇怪的错误,里面有一个数组

c++ - 未处理的异常 Microsoft C++ 异常:cv::Exception at memory location

c++ - 实例化 Mat 对象时 opencv 3.0.0 链接器错误

c# - 使用中轴变换的图像骨架化

c++ - 将 char * 转换为 vector C++

c++ - 函数参数中的 struct 关键字和常量正确性

c - 使用ffmpeg安装Open-CV出错

java - Java中的OpenCV approxPolyDP函数参数

python - OpenCV使用单色相机将帧扔到输出时得到3张图片而不是1张