2013-08-29 46 views
5

vector<vector<double> >Matに変換したいのですが、この値にカスタムの滑らかなフィルタを適用する必要があります。OpenCV - ベクトルのベクトルをMatに変換

下の画像は、私はこれを試み、正しい値を

This image shows the CORRECT values

を示しています。

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

しかし、最初の列の値は間違って変換され、2.12566e-314という値になります。

私も試みた結果の画像

result image

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

しかし値はある点の後に繰り返されます。

enter image description here

これは、値がここで

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

答えて

6

を印刷する方法であるベクトルのベクトルからのcv ::マットを移入する方法です。あなたは一時的なコピーにSTDの大きな塊たい場合

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

おかげで、これをcalculateAngles(アングル)の後に置き、それが機能しました。しかし、この関数の内部を変換してMat&asパラメータを渡すと、問題は残ります。 –

3

:コピーせずにCV ::マットへのstd ::ベクトルデータのベクトルを、最も効率的である:

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

ことに留意してください:

  • NewSamplesでデータを操作しないでください。
  • OrigSamplesは、NewSamplesを使用するまでは、スコープ内にある必要があります(破棄することはできません)。

...そうしないと、メモリの破損やクラッシュが発生します。

関連する問題