Правильные аргументы для cv :: Mat :: split (args) - PullRequest
0 голосов
/ 02 мая 2020

Мне нужно использовать функцию split (), которая имеет подпись:

void split(const Mat& src, Mat* mvbegin)

Я натолкнулся на эту подпись в официальной документации . Я попробовал следующее:

#include<opencv2/opencv.hpp>
#include<stdint.h>
#include<array>
#include<vector>

using namespace std; 
using namespace cv; 

int main(){

    //Common Parts : 
    //Loading the image : 
    Mat modified1 = imread("sample.jpg",CV_LOAD_IMAGE_COLOR);

    /* ATTEMPT 1 : This works : 
    *********************/
    vector<cv::Mat> rgb ;
    cv::split(modified1 , rgb); 

    /********************/

    /* ATTEMPT 2 : Does not work
    ********************/
    Mat* rgb1{nullptr} ;
    //rgb1 = &modified1;  Doesn't make a difference.
    cv::split(modified1 , rgb1); 
    /********************/

    return 0 ; 
}

Attempt 1 работает, и это то, что я видел, люди делали во время поиска ответов на stackoverflow. Ошибка, которую я получаю для Attempt2: segmentation fault (core dumped)

Мои вопросы:
1.) Почему не работает Attempt2, когда я слежу за сигнатурами функций?

2.) Почему Attempt1 работает?

Ответы [ 2 ]

0 голосов
/ 03 мая 2020

Итак, я выяснил, как это сделать, благодаря @ ypnos .

1.) Следует помнить, что если array in C++ инициализируется как:

int arr1[3] ={31,21,57};
cout<<*arr1<<endl //Prints 31 

Значение массива указывает на первый элемент, сохраненный в массиве. Это не относится к std::array.

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

  Mat rgb1[3]  ;
cv::split(modified1 , rgb1); 

Так что rgb1 ведет себя как указатель типа Mat и защищает сигнатуру

void split(const Mat& src, Mat* mvbegin)

Но тот факт, что mvbegin должен быть массивом размера 3, а не просто указателем, это то, что я не нашел явно записано в документах .

0 голосов
/ 02 мая 2020

Вы должны использовать перегруженную функцию, как показано ниже:

Mat rgb1[3] ;
cv::split(modified1 , rgb1); 

Для получения дополнительной информации о том, почему мы должны использовать такую ​​функцию, вы можете посмотреть документацию по этой ссылке , особенно ниже:

mvbegin: выходной массив; количество массивов должно соответствовать sr c .channels (); сами массивы перераспределяются, если это необходимо.

Так что это говорит о том, что вы должны определить массив размером 3 (или sr c .channels).

...