2017-06-14 3 views
0
#include "opencv2/core/core.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 
#include "opencv2/highgui/highgui.hpp" 
#include <math.h> 
#include <fstream> 
#include <iostream> 
using namespace cv; 
using namespace std; 
#define ATD at<double> 

Mat average_pooling2x2(Mat mat, int padding_mathed) 
{ 
int width_remain = mat.cols % 2; 
int high_remain = mat.rows % 2; 

Mat mat_new; 
if (width_remain == 0 && high_remain == 0) 
    mat.copyTo(mat_new); 
else 
{ 
    if (padding_mathed == 1)//valid 
    { 
     Rect roi = Rect(0, 0, mat.cols - width_remain, mat.rows - high_remain); 
     mat(roi).copyTo(mat_new); 
    } 
    else //same 
    { 
     mat.copyTo(mat_new); 
     if (high_remain != 0) 
     { 
      Mat row_add = cv::Mat::zeros(high_remain, mat_new.cols,mat_new.type()); 
      mat_new.push_back(row_add); 
     } 
     if (width_remain != 0) 
     { 
      Mat col_add = cv::Mat::zeros(width_remain, mat_new.rows, mat_new.type()); 
      mat_new = mat_new.t(); 
      mat_new.push_back(col_add); 
      mat_new = mat_new.t(); 
     } 
    } 
} 

Mat res(mat_new.cols/2, mat_new.rows/2, mat_new.type(), Scalar::all(0)); 


if (mat_new.channels() ==3) 
{ 


    for (int i = 0; i < res.rows; i++)//this is where error happened 
    { 
     uchar *data_res = res.ptr<uchar>(i); 
     uchar * data = mat_new.ptr<uchar>(2*i); 
     uchar * data1 = mat_new.ptr<uchar>(2*i+1); 
     for (int j = 0; j < res.cols*res.channels(); j = j + 3) 
     { 
      data_res[j] = (data[j*2] + data[j*2+3] + data1[j*2] + data1[j*2+3])/4; 
      data_res[j + 1] = (data[j*2+1] + data[j*2+4] + data1[j*2+1] + data1[j*2+4])/4; 
      data_res[j + 2] = (data[j*2+2] + data[j*2+5] + data1[j*2+2] + data1[j*2+5])/4; 

     } 
    } 

} 

else 
{ 
    for (int i = 0; i<res.rows; i++) 
    { 
     for (int j = 0; j<res.cols; j++) 
     { 
      Mat temp; 
      Rect roi = Rect(j * 2, i * 2, 2, 2); 
      mat_new(roi).copyTo(temp); 
      double val; 
      val = sum(temp)[0]/(2 * 2); 
      res.ATD(i, j) = val; 
     } 
    } 

} 

return res; 


} 


int main(int argc, char** argv) 
{ 
    Mat image = imread("C://Users//Administrator//Desktop//11.jpg"); 
    imshow("???", image); 
    Mat pooling_image; 
    average_pooling2x2(image, 2).copyTo(pooling_image); 
    imshow("???", pooling_image); 
    waitKey(); 
    return 0; 
} 

OpenCV Error: Assertion failed (y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0])) in cv::Mat::ptr, file d:\opencv\build\include\opencv2\core\mat.inl.hpp, line 827durchschnittlicher Pooling C++ Fehler

reccently Ich versuche, die durchschnittliche Pooling unter Verwendung von C++ zu implementieren, das ist der Fehler, wenn ich den Code ausführen, scheint es, dass vielleicht der ptr Zeiger außerhalb des Bereichs liegt. aber ich kann einfach nicht herausfinden, wo das Problem ist. Wirklich brauchen Hilfe

+0

Die Zeile, die Sie als "das ist, wo Fehler aufgetreten ist" markiert, kann nicht zu dem beschriebenen Fehler führen, da es nur Integer-Operationen enthält. Höchstwahrscheinlich passiert es irgendwo unten. Zum Beispiel unter 'mat_new.ptr (2 * i + 1);'. Für mich ist es nicht offensichtlich, ob 'mat_new' doppelt so viele Zeilen mit etwas mehr hat als' res'. Auch sollten Sie Ihre Variablen richtig benennen, Dummy-Namen wie 'data',' data1', 'i',' j' sind nur ein geradliniger Weg zum Scheitern. – VTT

Antwort

1

Wenn Sie die Datei, die die Fehlermeldung Verweise auf geöffnet, würden Sie sehen, dass die ptr() Methode ist wie folgt definiert:

template<typename _Tp> inline _Tp* Mat::ptr(int y) 
{ 
    CV_DbgAssert(y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0])); 
    return (_Tp*)(data + step.p[0]*y); 
} 

Alles in CV_DbgAssert() zu true bewerten müssen - ansonsten das Programm wird zur Laufzeit abstürzen. Aus dieser Bedingung wird deutlich, dass Sie sich auf die Zeile in Ihrem Programm beziehen, die sich außerhalb der Mat-Grenzen befindet (die Variable y oben).

In Ihrem Fall kann ich mehrere Zeilen sehen, wo das Programm abstürzen wird.

In diesen Zeilen, geschieht Absturz bei i gleich oder größer als erhält res.rows/2 (das erste wird abstürzen, wenn res.rows eine ungerade Zahl ist):

uchar * data = mat_new.ptr<uchar>(2*i); 
uchar * data1 = mat_new.ptr<uchar>(2*i+1); 

Diese Schleife wird auch abstürzen, weil data_res hat nur res.cols Spalten, und Sie erlauben j res.cols*res.channels()-1 zu erreichen:

for (int j = 0; j < res.cols*res.channels(); j = j + 3) 
     { 
      data_res[j] = (data[j*2] + data[j*2+3] + data1[j*2] + data1[j*2+3])/4; 
      data_res[j + 1] = (data[j*2+1] + data[j*2+4] + data1[j*2+1] + data1[j*2+4])/4; 
      data_res[j + 2] = (data[j*2+2] + data[j*2+5] + data1[j*2+2] + data1[j*2+5])/4; 

     } 

auch glaube ich, dass hier:

Sie haben möglicherweise versehentlich Argumente ausgetauscht - res hat mat_new.cols/2 Zeilen, während ich denke, Sie wollten es mat_new.rows/2 sein.