2013-08-29 25 views
5

में कनवर्ट करें मैं vector<vector<double> > से 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

मुद्रित कर रहे हैं यहाँ वैक्टर का एक वेक्टर से एक सीवी :: चटाई पॉप्युलेट करने के लिए एक तरीका है।

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

धन्यवाद, मैंने इसे गणना (कोण) की गणना के बाद रखा और यह काम किया। लेकिन, अगर मैं इस फ़ंक्शन के अंदर कनवर्ट करता हूं और मैट पास करता हूं और पैरामीटर के रूप में समस्या रहता है। –

3

आप अस्थायी प्रतिलिपि करने के लिए एसटीडी का एक बड़ा हिस्सा चाहते हैं: नकल के बिना सीवी :: चटाई के लिए 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 में डेटा को परिवर्तित न करें, केवल इसका इस्तेमाल।
  • उत्पत्ति नमूने दायरे में होनी चाहिए (नष्ट नहीं किया जा सकता है) या जब तक आप न्यू सैंपल का उपयोग नहीं करते हैं तब तक संशोधित होना चाहिए।

... अन्यथा आपको स्मृति भ्रष्टाचार/दुर्घटना मिल जाएगी।