2017-06-14 75 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 827平均池C++錯誤

reccently我嘗試實施的平均使用池C++,這是錯誤,當我運行的代碼,看來也許PTR指針超出範圍。但我無法弄清楚問題出在哪裏。真的需要一些幫助

+0

您標記爲「這是發生錯誤的位置」的行不會導致描述的錯誤,因爲它只包含整數操作。最有可能發生在下面的某處。例如'mat_new.ptr (2 * i + 1);'。對於我來說,'mat_new'的行數是「res」的兩倍,並不明顯。你也應該正確地命名你的變量,虛擬的名字,如'data','data1','i','j'只是一條直線失敗的道路。 – VTT

回答

1

如果打開的錯誤消息中引用,你會看到ptr()方法的定義如下文件:

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

裏面的一切CV_DbgAssert()必須求true - 否則程序將在運行時崩潰。從這種情況來看,很明顯,你指的是你的程序中在Mat邊界之外的行(上面的變量y)。

就你而言,我可以看到幾行程序將要崩潰的地方。

在這些線中,崩潰發生時i變得等於或大於res.rows/2(如果res.rows爲奇數的第一個將崩潰):

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

此循環也將崩潰,因爲data_res只有res.cols列,並且允許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; 

     } 

而且,我相信,在這裏:

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

您可能有意外的交換參數 - resmat_new.cols/2行,而我認爲您希望它是mat_new.rows/2