简体   繁体   English

OpenCV - 将矢量矢量转换为Mat

[英]OpenCV - Convert vector of vector to Mat

I want to convert a vector<vector<double> > to Mat because I need to apply a custom smooth filter to this values. 我想将vector<vector<double> >转换为Mat因为我需要对此值应用自定义平滑滤镜。

The image below shows the CORRECT values 下图显示了CORRECT值

此图像显示CORRECT值

I tried this. 我试过这个。

std::vector<std::vector<double> > angles;
calculateAngles(angles);
Mat matAngles(angles.size(), angles.at(0).size(), CV_64FC1, angles.data());

But the values in the first columns are wrong converted, with value 2.12566e-314. 但是第一列中的值被错误转换,值为2.12566e-314。

The resulting image 结果图像

结果图像

I also tried put the values directly in the Mat . 我也尝试将值直接放在Mat

void calculateAngles(cv::Mat& im, cv::Mat& angles, int blockSize, int(*f)(int x, int y), int(*g)(int x, int y)){

static int ySobel[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
static int xSobel[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};

angles.create(cv::Size(im.cols/blockSize+1, im.rows/blockSize+1), CV_64FC1);

int nominator;
int denominator;
int GX, GY;
double angle;
for(int i = 1; i < im.cols; i += blockSize){
    for(int j = 1; j < im.rows; j += blockSize){
        nominator = 0;
        denominator = 0;
        for(int k = i; k < std::min(i + blockSize, im.cols-1); k++){
            for(int l = j; l < std::min(j + blockSize, im.rows-1); l++){
                GX = applyKernelAt(im, xSobel, k, l);
                GY = applyKernelAt(im, ySobel, k, l);

                nominator += f(GX, GY);
                denominator += g(GX, GY);
            }
        }

        angle = (PI + std::atan2(nominator, denominator)) / 2;
        angles.at<double>((i-1)/blockSize, (j-1)/blockSize) = angle;
    }
}
}

But the values are repeated after a certain point. 但是在某一点之后重复这些值。

在此输入图像描述

This is how the values are printed 这是值的打印方式

void drawLines(cv::Mat& src, cv::Mat& dst, cv::Mat& angles, int blockSize){
cv::Size size = src.size();
dst.create(src.size(), src.type());

// for a white background
dst += 255;

cv::cvtColor(dst, dst, CV_GRAY2BGR);

int x1,y1,x2,y2;

for(int i = 1; i < size.width; i += blockSize){
    for(int j = 1; j < size.height; j += blockSize){
        double tang = std::tan(angles.at<double>((i-1)/blockSize,(j-1)/blockSize));

        if( tang >= -1 && tang <= 1 ){
            x1 = i;
            y1 = (-blockSize/2) * tang + j + blockSize/2;
            x2 = i + blockSize;
            y2 = (blockSize/2) * tang + j + blockSize/2;
        }else{
            x1 = i + blockSize/2 + blockSize/(2*tang);
            y1 = j + blockSize/2;
            x2 = i + blockSize/2 - blockSize/(2*tang);
            y2 = j -blockSize/2;
        }

        cv::line(dst, cv::Point(x1,y1), cv::Point(x2,y2), cv::Scalar(0,0,255));
    }
}
}

Here is a way to populate a cv::Mat from a vector of vectors. 这是一种从向量向量填充cv :: Mat的方法。

std::vector<std::vector<double> > angles;
cv::Mat matAngles(angles.size(), angles.at(0).size(), CV_64FC1);
for(int i=0; i<matAngles.rows; ++i)
     for(int j=0; j<matAngles.cols; ++j)
          matAngles.at<double>(i, j) = angles.at(i).at(j);

If you want to temporary copy a big chunk of std:vector of std::vector data to cv::Mat without copying, the most efficient is: 如果你想将一大块std:vector std:vector数据临时复制到cv :: Mat而不复制,最有效的是:

std:vector<std::vector<float> > OrigSamples;
...
... // Here OrigSamples is filled with some rows with the same row size
...

// Create a new, _empty_ cv::Mat with the row size of OrigSamples
cv::Mat NewSamples(0, OrigSamples[0].size(), cv::DataType<float>::type);

for (unsigned int i = 0; i < OrigSamples.size(); ++i)
{
  // Make a temporary cv::Mat row and add to NewSamples _without_ data copy
  cv::Mat Sample(1, OrigSamples[0].size(), cv::DataType<float>::type, OrigSamples[i].data());

  NewSamples.push_back(Sample);
}

Keep in mind that: 请记住:

  • Don't manipulate the data in NewSamples, only use it. 不要操纵NewSamples中的数据,只使用它。
  • OrigSamples must be in scope (can't be destroyed) or modified until you use NewSamples. 在使用NewSamples之前,OrigSamples必须在范围内(不能销毁)或修改。

...otherwise you will get memory corruption/crash. ...否则你会得到内存损坏/崩溃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM