简体   繁体   中英

How to use OutputArrayOfArrays in C++ OpenCV

I've been trying to create a function, using OpenCV proxy's functions to accept multiple types of elements (inputArray, OutputArray, OutputArrayOfArrays).

So far, I've found info on how to use InputArray and OutputArray, but not on OutputArrayOfArrays.

I've made this code in order to test the result assignment to OutputArrayOfArrays, with no avail:

//Return 3 Mats, each one filled with a different primary color
void rgb_mats(cv::OutputArrayOfArrays results){
    cv::vector<cv::Mat> bgr;
    cv::Mat B(100,100, CV_8UC3, cv::Scalar(255,0,0));
    cv::Mat G(100,100, CV_8UC3, cv::Scalar(0,255,0));
    cv::Mat R(100,100, CV_8UC3, cv::Scalar(0,0,255));
    bgr.push_back(B);
    bgr.push_back(G);
    bgr.push_back(R);
    cv::merge(bgr, results);
}

And this fails with an OpenCV assertion:

OpenCV Error: Assertion failed (dims == 2 && (sizes[0] == 1 || sizes[1] == 1 || sizes[0]*sizes[1] == 0)) in cv::_OutputArray::create, file C:\opencv_code\sources\modules\core\src\matrix.cpp, line 1564

I expected to get 3 cv::Mats, each with one different color, to later use the function like this:

cv::vector<cv::Mat> rgb_results;
rgb_mats(rgb_results);
assert(rgb_results.size() == 3);

I have searched the docs and I didn't find any example on how to return data with an OutputArrayofArrays.

What I can change in my example in order to pass the assert?

Your issue is not in OutputArrayOfArrays but with cv::merge you're trying to merge cv::vector<cv::Mat> to another object of the same type cv::vector<cv::Mat> which is not what cv::merge is suppose to do. Also you're declaring B , G and R as 3-channels each CV_8UC3 , so you're variable bgr or results will be of size = 9 (3*3).

The result code would look like something like that:

#include <opencv2/highgui.hpp>
#include <vector>

template <typename T, typename ... Ts>
void insert_all(std::vector<T> &vec, Ts ... ts)
 {   
     (vec.push_back(ts), ...);
 }


void rgb_mats(cv::Mat& results)
{
    std::vector<cv::Mat> bgr;
    bgr.reserve(3);

    cv::Mat B(100,100, CV_8UC1, cv::Scalar(255,0,0));
    cv::Mat G(100,100, CV_8UC1, cv::Scalar(0,255,0));
    cv::Mat R(100,100, CV_8UC1, cv::Scalar(0,0,255));

    insert_all(bgr, B,G, R);

    cv::merge(bgr, results);
}

int main ()
{
cv::Mat rgb_results;
rgb_mats(rgb_results);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM