Подтвердить что ты не робот

Как заполнить матрицу нулями в OpenCV?

Приведенный ниже код вызывает исключение. Почему?

#include <opencv2/core/core.hpp>
#include <iostream>

using namespace cv;
using namespace std;

void main() {

    try {
        Mat m1 = Mat(1,1, CV_64F, 0);
        m1.at<double>(0,0) = 0;
    }
    catch(cv::Exception &e) {
        cerr << e.what() << endl;
    }

}

Ошибка:

OpenCV Error: Assertion failed (dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] && (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) && ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3
) - 1))*4) & 15) == elemSize1()) in unknown function, file %OPENCV_DIR%\build\include\opencv2\core\mat.hpp, line 537

UPDATE

Если отслеживать этот код, я вижу, что строка конструктора вызывает конструктор

inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)

Почему? Этот прототип имеет 5 параметров, в то время как я предоставляю 4 аргумента.

4b9b3361

Ответ 1

Поскольку последний параметр является необязательным, а также указатель данных должен указывать в любом месте:

//inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
double mydata[1];
Mat m1 = Mat(1,1, CV_64F, mydata); 
m1.at<double>(0,0) = 0;

Но лучше сделайте это непосредственно с помощью этого конструктора на основе шаблонов:

//inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
Mat m1 = Mat(1,1, CV_64F, cvScalar(0.));

//or even
Mat m1 = Mat(1,1, CV_64F, double(0));

Ответ 2

Как заполнить матрицу нулями в OpenCV?

Чтобы заполнить существующий объект Mat нулями, вы можете использовать Mat::zeros()

Mat m1 = ...;
m1 = Mat::zeros(1, 1, CV_64F);

Чтобы инициализировать Mat так, чтобы он содержал только нули, вы можете передать скаляр со значением 0 в конструктор:

Mat m1 = Mat(1,1, CV_64F, 0.0);
//                        ^^^^double literal

Причина, по которой ваша версия не удалась, заключается в том, что передача 0 в качестве четвертого аргумента соответствует перегрузке с void* лучше, чем та, которая принимает скаляр.

Ответ 3

использовать cv:: mat:: setto

img.setTo(резюме:: Скалярное (redVal, greenVal, blueVal))

Ответ 4

Если вы больше занимаетесь программированием с помощью шаблонов, вы также можете сделать это таким образом...

template<typename _Tp>
... some algo ...
cv::Mat mat = cv::Mat_<_Tp>::zeros(rows, cols);
mat.at<_Tp>(i, j) = val;

Ответ 5

Вы можете использовать это, чтобы заполнить нули в объекте Mat, уже содержащем данные:

image1 = Scalar::all(0);

Например, если вы используете его следующим образом:

Mat image,image1;
image = imread("IMG_20160107_185956.jpg", CV_LOAD_IMAGE_COLOR);   // Read the file

if(! image.data )                              // Check for invalid input
{
    cout <<  "Could not open or find the image" << std::endl ;
    return -1;
}
cvtColor(image,image1,CV_BGR2GRAY);
image1 = Scalar::all(0);

Все будет хорошо. Но вы не можете использовать это для неинициализированного Mat. Для этого вы можете использовать другие варианты, упомянутые в приведенных выше ответах, например

Mat drawing = Mat::zeros( image.size(), CV_8UC3 );

Ответ 6

Мать img;

img = Mat:: zeros (размер изображения, CV_8UC3);

если вы хотите, чтобы это было изображение img1

IMG = Mat:: нули (img1.size, CV_8UC3);

Ответ 7

Вы можете выбрать заполнение нулевых данных или создать нулевой Матем.

  • Заполнение нулевых данных setTo():

    img.setTo(Scalar::all(0));
    
  • Создайте нулевые данные с помощью zeros():

    img = zeros(img.size(), img.type());
    

IMG изменяет адрес памяти.

Ответ 8

Предполагаю, вы говорите о заполнении нулей какого-то существующего коврика? Как насчет этого?:)

mat * = 0;