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 827mise en commun moyenne C++ erreur

reccently je tente de mettre en œuvre la mise en commun moyenne en C++, c'est l'erreur quand je lance le code, il semble que peut-être le pointeur ptr est hors de portée. mais je ne peux pas comprendre où est le problème. Vraiment besoin d'aide

+0

La ligne que vous avez marquée comme "où l'erreur s'est produite" ne peut pas provoquer d'erreur décrite car elle contient uniquement des opérations entières. Très probablement, il arrive quelque part ci-dessous. Par exemple à 'mat_new.ptr (2 * i + 1);'. Pour moi, il n'est pas évident que 'mat_new' ait deux fois plus de lignes avec un peu plus de' res'. Aussi, vous devriez nommer vos variables correctement, les noms fictifs tels que 'data',' data1', 'i',' j' sont juste une route droite pour échouer. – VTT

Répondre

1

Si vous ouvrez le fichier que le message d'erreur des références à, vous verriez que la méthode ptr() est définie comme suit:

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

Tout à l'intérieur CV_DbgAssert() doit évaluer à true - sinon le programme va planter à l'exécution. À partir de cette condition, il est clair que vous faites référence à la ligne de votre programme qui est en dehors des limites de Mat (la variable y ci-dessus).

Dans votre cas, je peux voir plusieurs lignes où le programme va planter.

Dans ces lignes, l'accident se produit lorsque i obtient égale ou supérieure à res.rows/2 (le premier se bloque si res.rows est un nombre impair):

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

Cette boucle va planter aussi, parce que data_res n'a que res.cols colonnes, et vous permettent d'atteindre j res.cols*res.channels()-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; 

     } 

, je crois aussi que ici:

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

vous avez peut-être accidentellement permuté des arguments - res a mat_new.cols/2 lignes, alors que je pense que vous vouliez que ce soit mat_new.rows/2.