2013-08-29 78 views
5

Tôi muốn chuyển đổi một vector<vector<double> > thành Mat vì tôi cần áp dụng bộ lọc mịn tùy chỉnh cho các giá trị này.OpenCV - Chuyển đổi vectơ của véc tơ thành Mat

Những hình ảnh dưới đây cho thấy các giá trị ĐÚNG

This image shows the CORRECT values

Tôi cố gắng này.

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

Nhưng giá trị trong các cột đầu tiên được chuyển đổi sai, với giá trị 2.12566e-314.

Hình ảnh thu được

result image

Tôi cũng đã cố gắng đưa các giá trị trực tiếp trong 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; 
    } 
} 
} 

Nhưng các giá trị được lặp lại sau một thời điểm nhất định.

enter image description here

Đây là cách các giá trị được in

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

Trả lời

6

Dưới đây là một cách để cư một cv :: Mat từ một vector của vector.

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

Cảm ơn, tôi đã đặt nó sau khi tính toánCác góc (góc) và nó hoạt động. Nhưng, nếu tôi chuyển đổi bên trong chức năng này và vượt qua một Mat & như tham số vấn đề vẫn còn. –

3

Nếu bạn muốn sao chép tạm thời một đoạn lớn của std: vector dữ liệu std :: vector để cv :: Mat mà không sao chép, hiệu quả nhất là:

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

Hãy ghi nhớ rằng :

  • Không thao tác dữ liệu trong NewSamples, chỉ sử dụng dữ liệu.
  • OrigSamples phải nằm trong phạm vi (không thể bị hủy) hoặc sửa đổi cho đến khi bạn sử dụng Mẫu mới.

... nếu không bạn sẽ bị hỏng/hỏng bộ nhớ.