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

openCV creating a 3D matrix with different sizes

本文关键字:3D 矩阵 创建 openCV      更新时间:2023-10-16

>同意这个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 和 Raw 图像,因此我需要创建一个 100x100x1 矩阵或 100x100x3 矩阵,具体取决于图像类型。

但是我在 imshow() 中得到一个例外

OpenCV Error: Assertion failed (p[-1] <= 2) in cv::Mat::MSize::operator (), file
 C:buildslave64win64_amdocl2_4_PackSlave-win64-vc11-sharedopencvmodulescor
eincludeopencv2/core/mat.hpp, line 712

你能解释一下问题出在哪里吗?

在我看来

,您在这两种情况下都试图设置一个 3 层零垫:

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

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

我为此找到的解决方案是使用 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,而不是像CV_32F中使用的float

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);