2015-11-19 155 views
0

我正在处理图像处理项目,并且遇到系统崩溃。这是一个不断出现的错误:CV :: Mat导致运行时错误 - OpenCV错误 - 断言失败

OpenCV Error: Assertion failed (dims <= 2 && data && (unsigned)i0 < (unsigned)si ze.p[0] && (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channel s()) && ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3 ) - 1))*4) & 15) == elemSize1()) in cv::Mat::at, file d:\libs\opencv-249\build\i nclude\opencv2\core\mat.hpp, line 537

我能够找到下面的代码位使问题

samples = (src.size(), src.type()); 
imshow ("source" , src); 
for(int y = 0; y < src.rows; y++) 
for(int x = 0; x < src.cols; x++) 
    for(int z = 0; z < 3; z++){ 

     samples.at<float>((y + (x*src.rows)), z) = src.at<Vec3b>(y,x)[z];} 

samples是在头文件中声明的垫目标这个班。

我也提到了这个link但即使错误是相同的导致崩溃的代码是不一样的我的。但尴尬的是,这段确切的代码在另一个函数中工作正常,但是当我尝试在属于某个类的方法中包含相同的代码时,它会发生此错误。

我无言以对。谁能帮我吗?

+0

请告诉我src.type()?为什么当它们都具有相同类型时,将样本作为“浮动”和src作为“Vec3b”访问? –

回答

0

看来你想samples是一个矩阵:

# rows  : src.rows * src.cols 
# cols  : src.channels() // it's probably 3, 
type  : CV_32F (float) 
# channels : 1 (single channel matrix) 

使用位置(r,c)的指数你比访问行samplessrc

int index = r * src.cols + c; 

例如,如果src2x4 3通道图像(具有随机值):

enter image description here

你想samples成为8x3单通道浮点矩阵:

enter image description here

代码:

#include <opencv2/opencv.hpp> 
#include <iostream> 
using namespace std; 
using namespace cv; 

int main() 
{ 
    // Init src image 
    Mat src(2, 4, CV_8UC3); 
    randu(src, Scalar(0, 0, 0), Scalar(255, 255, 255)); 

    // Init samples image 
    // # rows = src.rows * src.cols 
    // # cols = src.channels() 
    // type = CV_32FC1 (single channel float, while src type is 3 channel CV_8U) 
    Mat samples(src.rows * src.cols, src.channels(), CV_32FC1); 

    for (int r = 0; r < src.rows; ++r) 
    { 
     for (int c = 0; c < src.cols; ++c) 
     { 
      int index = r * src.cols + c; 
      for (int channel = 0; channel < src.channels(); ++channel) 
      { 
       samples.at<float>(index, channel) = src.at<Vec3b>(r, c)[channel]; 
      } 
     } 
    } 

    cout << "SRC: " << endl << src << endl << endl; 
    cout << "SAMPLES: " << endl << samples << endl << endl; 


    return 0; 
} 
+0

非常感谢你的回答和解释。它帮了我很多忙。 – nickY

0

在电话samples.at<float>((y + (x*src.rows)), z)中,您可以在x = zy = (y + (x*src.rows)处访问图像。

y的最高值是(y + (x*src.rows)) = (src.rows-1 + ((src.cols-1)*src.rows)) = src.rows*src.cols-1。这比src.cols-1允许的最大值大得多,所以OpenCV会抛出一个断言,告诉你这是超出了图像的范围。

我不知道它为什么在代码的一部分工作,而不在另一部分,但这显然是一个问题。

另外,什么src.type()?为什么当它们都具有相同类型时,将样本作为“浮动”和src作为“Vec3b”访问?这似乎也很危险。

+0

非常感谢您指出我的错误。它节省了我很多时间。我将代码改为'samples.at ((x +(y * src.cols)),z)= src.at (y,x)[z];'现在它工作正常。此外,我使用“float”而不是“Vec3b”的原因是,我使用“samples”作为kmeans聚类的输入数据,它不接受“Vec3b”类型。 – nickY

+0

@nickY我不确定您更改的代码是否正常工作...我想,你仍然有同样的问题。为什么不把它改成'samples.at (y,x)'?另外,如果你使用float,你应该用'samples =(src.size(),CV_F32)'而不是'samples =(src.size(),src.type())'来初始化样本。 –

+0

对不起,我忘了提到这一点。我确实将它改为了'Mat samples(src.rows * src.cols,3,CV_32F);'因此它没有任何错误。再次感谢您指出。 – nickY

相关问题