【问题标题】:Correct args for cv::Mat::split(args)cv::Mat::split(args) 的正确参数
【发布时间】:2020-05-02 10:24:36
【问题描述】:

我需要使用具有签名的函数 split() :

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

我通过official documentation 发现了这个签名。 我尝试了以下方法:

#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 有效?

【问题讨论】:

  • 您应该提供一个准备好的空 Mat 对象数组。 split() 不会为你分配数组。
  • 谢谢,文档中没有明确写出来。

标签: c++ opencv c++14 opencv3.0


【解决方案1】:

你必须使用如下的重载函数:

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

关于为什么我们应该使用这样的功能的更多信息,您可以通过link查看文档,特别是以下文档:

mvbegin:输出数组;数组的数量必须匹配 src.channels();如果需要,数组本身会被重新分配。

所以它说你应该定义一个大小为 3(或 src.channels)的数组。

【讨论】:

    【解决方案2】:

    感谢@ypnos

    1.) 必须记住,如果 C++ 中的 array 被初始化为:

    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 的数组而不仅仅是指针对象这一事实是我在docs 中没有发现明确写的。

    【讨论】:

      猜你喜欢
      • 2014-06-21
      • 1970-01-01
      • 1970-01-01
      • 2015-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-25
      相关资源
      最近更新 更多