【问题标题】:CV::Mat causing runtime error - OpenCV Error - Assertion failedCV::Mat 导致运行时错误 - OpenCV 错误 - 断言失败
【发布时间】:2016-02-21 04:03:14
【问题描述】:

我正在处理一个图像处理项目,但我遇到了系统崩溃。这是不断弹出的错误:

OpenCV 错误:断言失败 (dims ::channels) > ((DataType<_tp>::depth) & ((1

我发现是下面这段代码造成了问题

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 是一个 Mat 对象,在该类的头文件中声明。

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

我一无所知。谁能帮我吗?

【问题讨论】:

  • 什么是 src.type()?当样本都具有相同的类型时,为什么将样本访问为“floats”而将 src 访问为“Vec3b”?

标签: c++ opencv


【解决方案1】:

您似乎希望samples 成为一个矩阵:

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

您可以使用src 中位置(r,c) 的索引来访问samples 的行:

int index = r * src.cols + c;

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

您希望samples 成为8x3 单通道浮点矩阵:

代码:

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

【讨论】:

  • 非常感谢您的回答和解释。这对我帮助很大。
【解决方案2】:

在调用samples.at&lt;float&gt;((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() 是什么?当它们都具有相同的类型时,为什么将样本作为“floats”访问,将 src 作为“Vec3b”访问?这样做似乎也很危险。

【讨论】:

  • 非常感谢您指出我的错误。它节省了我很多时间。我将代码更改为samples.at&lt;float&gt;((x + (y*src.cols)), z) = src.at&lt;Vec3b&gt;(y,x)[z]; 现在它工作正常。另外我使用“float”而不是“Vec3b”的原因是,我使用“samples”作为kmeans聚类的输入数据,它不接受“Vec3b”类型。
  • @nickY 我不确定您更改的代码是否有效……我认为您仍然有同样的问题。为什么不改成samples.at&lt;float&gt;(y, x)?另外,如果你使用浮点数,你应该用samples = (src.size(), CV_F32)而不是samples = (src.size(), src.type())初始化样本。
  • 很抱歉我忘了提。我确实将其更改为 Mat samples (src.rows * src.cols, 3, CV_32F); 因此它可以正常工作而没有任何错误。再次感谢您指出。
猜你喜欢
  • 2017-12-24
  • 2023-03-23
  • 2014-11-25
  • 1970-01-01
  • 2016-04-15
  • 2019-05-04
  • 2018-11-29
  • 2017-04-04
  • 2020-08-21
相关资源
最近更新 更多