openCV创建不同大小的3D矩阵

时间:2015-04-21 10:43:04

标签: c++ opencv matrix

归因于此 http://answers.opencv.org/question/15917/how-to-access-data-from-a-cvmat/  我试图创建一个3D矩阵

void AutomaticMacbethDetection::DrawMacbethROI(ColorCheckerBatchRGB ColorCheckerBatchRGB, int *** raw_frame,int _width, int _height,int colorOrder)
{  
    cv::Mat src;
    if (colorOrder == -1)
    {
        const int sizes[3]={_height,_width,3};
        src = cv::Mat::zeros(3, sizes, CV_32F);

    }else
    {
        const int sizes[3]={_height,_width,1};
        src = cv::Mat::zeros(3, sizes, CV_32F);
    }

    std::vector<float> channel;
    if (colorOrder == -1)
    {
        for (int w = 0; w < _width; w++)
        {               
            for (int h = 0; h < _height; h++)
            {
                float temp =raw_frame[h][w][0]; 
                channel.push_back(temp);
                src.at<float>(h,w,0) = temp;
                src.at<float>(h,w,1) = raw_frame[h][w][1];
                src.at<float>(h,w,2) = raw_frame[h][w][2];
            }               
        }   
    }
    else
    {
        for (int w = 0; w < _width; w++)
        {               
            for (int h = 0; h < _height; h++)
            {
                float temp =raw_frame[h][w][0]; 
                channel.push_back(temp);
                src.at<float>(h,w,0) = temp;
            }               
        }   
        float divider = Utilities::tprctile(channel,99.2);
        src = src/divider;
    }

    cv::imshow("test", src);
    cv::waitKey(0);

}

我的功能支持RGB和原始图像,因此我需要根据图像类型创建100x100x1矩阵或100x100x3矩阵。

然而我在imshow()中得到一个例外

OpenCV Error: Assertion failed (p[-1] <= 2) in cv::Mat::MSize::operator (), file
 C:\buildslave64\win64_amdocl\2_4_PackSlave-win64-vc11-shared\opencv\modules\cor
e\include\opencv2/core/mat.hpp, line 712
你可以解释一下这是什么问题吗?

2 个答案:

答案 0 :(得分:1)

在我看来,你试图在两种情况下都设置一个3层零垫:

const int sizes[3]={_height,_width,1};
src = cv::Mat::zeros(3, sizes, CV_32F);

C ++:static MatExpr Mat :: zeros(int ndims,const int * sz,int type)声明第一个参数是维度。如果你想要一层垫子,这里应该是1。

答案 1 :(得分:0)

我找到的解决方案是使用CV_32FC3,这意味着矩阵(x,y)的每个单元格中都有3个值。 这就是你初始化3D矩阵的方法。

src = cv::Mat::zeros(_height,_width, CV_32FC3);    

现在您需要访问3个单元格,如下所示:

src.at<cv::Vec3f>(h,w)[0]
src.at<cv::Vec3f>(h,w)[1]
src.at<cv::Vec3f>(h,w)[2]

请注意我正在使用Vec3f而不是float,就像我在CV_32F

中使用的那样
void AutomaticMacbethDetection::DrawMacbethROI(ColorCheckerBatchRGB ColorCheckerBatchRGB, int *** raw_frame,int _width, int _height,int colorOrder)
{

    cv::Mat src;
    std::vector<float> channel;
    if (colorOrder != -1 )
    {
        src = cv::Mat::zeros(_height,_width, CV_32F);
        for (int w = 0; w < _width; w++)
        {               
            for (int h = 0; h < _height; h++)
            {
                float temp =raw_frame[h][w][0]; 
                channel.push_back(temp);
                src.at<float>(h,w) = temp;
            }               
        }   
        float divider = Utilities::tprctile(channel,99.2);
        src = src/divider;

    }
    else
    {
        src = cv::Mat::zeros(_height,_width, CV_32FC3); 
        for (int w = 0; w < _width; w++)
        {               
            for (int h = 0; h < _height; h++)
            {
                float temp =raw_frame[h][w][0]; 
                channel.push_back(temp);
                src.at<cv::Vec3f>(h,w)[0] = raw_frame[h][w][0];
                src.at<cv::Vec3f>(h,w)[1] = raw_frame[h][w][1];
                src.at<cv::Vec3f>(h,w)[2] = raw_frame[h][w][2];
            }                       
        }
        float divider = Utilities::tprctile(channel,99.2);
        src = src/divider;
    }

    cv::resize(src,src,cv::Size(),0.3,0.3,cv::INTER_LINEAR);
    cv::imshow("detected", src);    
    cv::waitKey(0);