opencv cv::Mat In/Out putArray InputArray

综述

该目的是函数的形参类型基于实际情况而定,不需要传入指针等情况

InputArray

  • 其中 _InputArray 是一个类,可以从 MatMat_<T>Matx<T, m, n>std::vector<T>std::vector<std: :vector<T> >std::vector<Mat>std::vector<Mat_<T> >UMatstd::vector<UMat>double。它也可以从矩阵表达式构造。
  • 可选输入参数:如果某些输入数组可能为空,则传递 cv::noArray() (或者像您之前所做的那样简单地传递 cv::Mat())。
  • 该类仅用于传递参数。也就是说,通常你 不应该 声明这种类型的类成员、局部和全局变量。
  • 如果您想设计自己的函数或类方法,可以操作多种类型的数组,您可以使用 InputArray(或 OutputArray)作为相应的参数。在函数内部,您应该使用 _InputArray::getMat() 方法为数组构造矩阵头(不复制数据)。
class CV_EXPORTS _InputArray
{
public:
    enum KindFlag {
        KIND_SHIFT = 16,
        FIXED_TYPE = 0x8000 << KIND_SHIFT,
        FIXED_SIZE = 0x4000 << KIND_SHIFT,
        KIND_MASK = 31 << KIND_SHIFT,

        NONE              = 0 << KIND_SHIFT,
        MAT               = 1 << KIND_SHIFT,
        MATX              = 2 << KIND_SHIFT,
        STD_VECTOR        = 3 << KIND_SHIFT,
        STD_VECTOR_VECTOR = 4 << KIND_SHIFT,
        STD_VECTOR_MAT    = 5 << KIND_SHIFT,
#if OPENCV_ABI_COMPATIBILITY < 500
        EXPR              = 6 << KIND_SHIFT,  //!< removed: https://github.com/opencv/opencv/pull/17046
#endif
        OPENGL_BUFFER     = 7 << KIND_SHIFT,
        CUDA_HOST_MEM     = 8 << KIND_SHIFT,
        CUDA_GPU_MAT      = 9 << KIND_SHIFT,
        UMAT              =10 << KIND_SHIFT,
        STD_VECTOR_UMAT   =11 << KIND_SHIFT,
        STD_BOOL_VECTOR   =12 << KIND_SHIFT,
        STD_VECTOR_CUDA_GPU_MAT = 13 << KIND_SHIFT,
#if OPENCV_ABI_COMPATIBILITY < 500
        STD_ARRAY         =14 << KIND_SHIFT,  //!< removed: https://github.com/opencv/opencv/issues/18897
#endif
        STD_ARRAY_MAT     =15 << KIND_SHIFT
    };

    _InputArray();
    _InputArray(int _flags, void* _obj);
    _InputArray(const Mat& m);
    _InputArray(const MatExpr& expr);
    _InputArray(const std::vector<Mat>& vec);
    template<typename _Tp> _InputArray(const Mat_<_Tp>& m);
    template<typename _Tp> _InputArray(const std::vector<_Tp>& vec);
    _InputArray(const std::vector<bool>& vec);
    template<typename _Tp> _InputArray(const std::vector<std::vector<_Tp> >& vec);
    _InputArray(const std::vector<std::vector<bool> >&) = delete;  // not supported
    template<typename _Tp> _InputArray(const std::vector<Mat_<_Tp> >& vec);
    template<typename _Tp> _InputArray(const _Tp* vec, int n);
    template<typename _Tp, int m, int n> _InputArray(const Matx<_Tp, m, n>& matx);
    _InputArray(const double& val);
    _InputArray(const cuda::GpuMat& d_mat);
    _InputArray(const std::vector<cuda::GpuMat>& d_mat_array);
    _InputArray(const ogl::Buffer& buf);
    _InputArray(const cuda::HostMem& cuda_mem);
    template<typename _Tp> _InputArray(const cudev::GpuMat_<_Tp>& m);
    _InputArray(const UMat& um);
    _InputArray(const std::vector<UMat>& umv);

    template<typename _Tp, std::size_t _Nm> _InputArray(const std::array<_Tp, _Nm>& arr);
    template<std::size_t _Nm> _InputArray(const std::array<Mat, _Nm>& arr);

    template<typename _Tp> static _InputArray rawIn(const std::vector<_Tp>& vec);
    template<typename _Tp, std::size_t _Nm> static _InputArray rawIn(const std::array<_Tp, _Nm>& arr);

    Mat getMat(int idx=-1) const;
    Mat getMat_(int idx=-1) const;
    UMat getUMat(int idx=-1) const;
    void getMatVector(std::vector<Mat>& mv) const;
    void getUMatVector(std::vector<UMat>& umv) const;
    void getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const;
    cuda::GpuMat getGpuMat() const;
    ogl::Buffer getOGlBuffer() const;

    int getFlags() const;
    void* getObj() const;
    Size getSz() const;

    _InputArray::KindFlag kind() const;
    int dims(int i=-1) const;
    int cols(int i=-1) const;
    int rows(int i=-1) const;
    Size size(int i=-1) const;
    int sizend(int* sz, int i=-1) const;
    bool sameSize(const _InputArray& arr) const;
    size_t total(int i=-1) const;
    int type(int i=-1) const;
    int depth(int i=-1) const;
    int channels(int i=-1) const;
    bool isContinuous(int i=-1) const;
    bool isSubmatrix(int i=-1) const;
    bool empty() const;
    void copyTo(const _OutputArray& arr) const;
    void copyTo(const _OutputArray& arr, const _InputArray & mask) const;
    size_t offset(int i=-1) const;
    size_t step(int i=-1) const;
    bool isMat() const;
    bool isUMat() const;
    bool isMatVector() const;
    bool isUMatVector() const;
    bool isMatx() const;
    bool isVector() const;
    bool isGpuMat() const;
    bool isGpuMatVector() const;
    ~_InputArray();

protected:
    int flags;
    void* obj;
    Size sz;

    void init(int _flags, const void* _obj);
    void init(int _flags, const void* _obj, Size _sz);
};

OutputArray

  • 该类型与 InputArray 非常相似,只是它用于输入/输出和输出函数参数。
  • 该类型基本都是引用 ,毕竟要作为输出使用
class CV_EXPORTS _OutputArray : public _InputArray
{
public:
    enum DepthMask
    {
        DEPTH_MASK_8U = 1 << CV_8U,
        DEPTH_MASK_8S = 1 << CV_8S,
        DEPTH_MASK_16U = 1 << CV_16U,
        DEPTH_MASK_16S = 1 << CV_16S,
        DEPTH_MASK_32S = 1 << CV_32S,
        DEPTH_MASK_32F = 1 << CV_32F,
        DEPTH_MASK_64F = 1 << CV_64F,
        DEPTH_MASK_16F = 1 << CV_16F,
        DEPTH_MASK_ALL = (DEPTH_MASK_64F<<1)-1,
        DEPTH_MASK_ALL_BUT_8S = DEPTH_MASK_ALL & ~DEPTH_MASK_8S,
        DEPTH_MASK_ALL_16F = (DEPTH_MASK_16F<<1)-1,
        DEPTH_MASK_FLT = DEPTH_MASK_32F + DEPTH_MASK_64F
    };

    _OutputArray();
    _OutputArray(int _flags, void* _obj);
    _OutputArray(Mat& m);
    _OutputArray(std::vector<Mat>& vec);
    _OutputArray(cuda::GpuMat& d_mat);
    _OutputArray(std::vector<cuda::GpuMat>& d_mat);
    _OutputArray(ogl::Buffer& buf);
    _OutputArray(cuda::HostMem& cuda_mem);
    template<typename _Tp> _OutputArray(cudev::GpuMat_<_Tp>& m);
    template<typename _Tp> _OutputArray(std::vector<_Tp>& vec);
    _OutputArray(std::vector<bool>& vec) = delete;  // not supported
    template<typename _Tp> _OutputArray(std::vector<std::vector<_Tp> >& vec);
    _OutputArray(std::vector<std::vector<bool> >&) = delete;  // not supported
    template<typename _Tp> _OutputArray(std::vector<Mat_<_Tp> >& vec);
    template<typename _Tp> _OutputArray(Mat_<_Tp>& m);
    template<typename _Tp> _OutputArray(_Tp* vec, int n);
    template<typename _Tp, int m, int n> _OutputArray(Matx<_Tp, m, n>& matx);
    _OutputArray(UMat& m);
    _OutputArray(std::vector<UMat>& vec);

    _OutputArray(const Mat& m);
    _OutputArray(const std::vector<Mat>& vec);
    _OutputArray(const cuda::GpuMat& d_mat);
    _OutputArray(const std::vector<cuda::GpuMat>& d_mat);
    _OutputArray(const ogl::Buffer& buf);
    _OutputArray(const cuda::HostMem& cuda_mem);
    template<typename _Tp> _OutputArray(const cudev::GpuMat_<_Tp>& m);
    template<typename _Tp> _OutputArray(const std::vector<_Tp>& vec);
    template<typename _Tp> _OutputArray(const std::vector<std::vector<_Tp> >& vec);
    template<typename _Tp> _OutputArray(const std::vector<Mat_<_Tp> >& vec);
    template<typename _Tp> _OutputArray(const Mat_<_Tp>& m);
    template<typename _Tp> _OutputArray(const _Tp* vec, int n);
    template<typename _Tp, int m, int n> _OutputArray(const Matx<_Tp, m, n>& matx);
    _OutputArray(const UMat& m);
    _OutputArray(const std::vector<UMat>& vec);

    template<typename _Tp, std::size_t _Nm> _OutputArray(std::array<_Tp, _Nm>& arr);
    template<typename _Tp, std::size_t _Nm> _OutputArray(const std::array<_Tp, _Nm>& arr);
    template<std::size_t _Nm> _OutputArray(std::array<Mat, _Nm>& arr);
    template<std::size_t _Nm> _OutputArray(const std::array<Mat, _Nm>& arr);

    template<typename _Tp> static _OutputArray rawOut(std::vector<_Tp>& vec);
    template<typename _Tp, std::size_t _Nm> static _OutputArray rawOut(std::array<_Tp, _Nm>& arr);

    bool fixedSize() const;
    bool fixedType() const;
    bool needed() const;
    Mat& getMatRef(int i=-1) const;
    UMat& getUMatRef(int i=-1) const;
    cuda::GpuMat& getGpuMatRef() const;
    std::vector<cuda::GpuMat>& getGpuMatVecRef() const;
    ogl::Buffer& getOGlBufferRef() const;
    cuda::HostMem& getHostMemRef() const;
    void create(Size sz, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const;
    void create(int rows, int cols, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const;
    void create(int dims, const int* size, int type, int i=-1, bool allowTransposed=false, _OutputArray::DepthMask fixedDepthMask=static_cast<_OutputArray::DepthMask>(0)) const;
    void createSameSize(const _InputArray& arr, int mtype) const;
    void release() const;
    void clear() const;
    void setTo(const _InputArray& value, const _InputArray & mask = _InputArray()) const;

    void assign(const UMat& u) const;
    void assign(const Mat& m) const;

    void assign(const std::vector<UMat>& v) const;
    void assign(const std::vector<Mat>& v) const;

    void move(UMat& u) const;
    void move(Mat& m) const;
};

案例

  • cv::Mat .at<类型>(行,列) 取对应数据

Code

  void PointCvMat(const cv::Mat& mat,const std::string& head_str = "") {
    std::cout<<head_str<<" data: \n"<<mat<<std::endl;
  }

  void ComputeL_6x4(double * l_6x4) {

      for(int i=0;i<6;i++) {
         double * row = l_6x4 + 4 * i;
         row[0] = i * 10 + 0;
         row[1] = i * 10 + 1;
         row[2] = i * 10 + 2;
         row[3] = i * 10 + 3;
      }
  }


  void TestChangeL(cv::InputArray _src,cv::OutputArray _dst) {

    cv::Mat src = _src.getMat();
    _dst.createSameSize(_src,src.type());
    cv::Mat dst = _dst.getMat();
    int rows = src.rows,cols = src.cols;
    CHECK_EQ(src.rows,dst.rows);
    CHECK_EQ(src.cols,dst.cols);
    LOG(INFO)<<"r:"<<rows<<" c:"<<cols;
    for(int i =0; i< rows;i++) {
      for(int j =0; j< cols;j++) {
        dst.at<double>(rows-1-i,cols-1 -j) = src.at<double>(i,j);
      }
    }
  }

TEST(FunctionTest,cvMatTest1) {


  double l_6x4[6 * 4], b4[4] = {0};
  cv::Mat L_6x41,L_6x4 = cv::Mat(6, 4, CV_64F, l_6x4);
  cv::Mat B4    = cv::Mat(4, 1, CV_64F, b4);

  PointCvMat(L_6x4,"front");
  std::cout<<"------------------"<<std::endl;
  L_6x4.setTo(0);
  PointCvMat(L_6x4,"set_zero");
  std::cout<<"------------------"<<std::endl;
  ComputeL_6x4(l_6x4);
  PointCvMat(L_6x4,"back ");
  std::cout<<"------------------"<<std::endl;
  TestChangeL(L_6x4,L_6x41);
  PointCvMat(L_6x41,"TestChange ");
  std::cout<<"------------------"<<std::endl;

}

输出

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个错误通常是由于传递给 `findContours()` 函数的轮廓参数类型不正确导致的。 在你的代码中,`findContours()` 函数的第一个参数是一个 `cv::Mat` 类型的矩阵,而第二个参数 `intersectionPolygon` 是一个 `std::vector<cv::Point>` 类型的向量。这里的问题是,`findContours()` 函数期望的第二个参数是一个用于存储轮廓的输出向量,而你传递了一个点的向量。因此,你需要将 `intersectionPolygon` 声明为一个 `std::vector<std::vector<cv::Point>>` 类型的向量,以存储轮廓。 更改后的代码如下所示: ``` bool isPolygonInside(const std::vector<cv::Point>& polygon1, const std::vector<cv::Point>& polygon2, double& outsideArea) { // Check if all vertices of polygon1 are inside polygon2 bool allInside = true; for (const auto& vertex : polygon1) { double distance = cv::pointPolygonTest(polygon2, vertex, true); if (distance < 0) { allInside = false; break; } } if (allInside) { return true; } // Polygon1 is partially or completely outside polygon2 std::vector<std::vector<cv::Point>> intersectionPolygon; // 修改此处 if (cv::isContourConvex(polygon1) && cv::isContourConvex(polygon2)) { cv::Mat intersectionMat; cv::intersectConvexConvex(cv::Mat(polygon1), cv::Mat(polygon2), intersectionMat); if (cv::countNonZero(intersectionMat) > 0) { cv::findContours(intersectionMat, intersectionPolygon, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); } } else { std::vector<cv::Point> hull1, hull2; cv::convexHull(polygon1, hull1); cv::convexHull(polygon2, hull2); std::vector<cv::Point> hullIntersection; cv::convexHull(hull1, hullIntersection, false, false); cv::fillConvexPoly(cv::Mat(hullIntersection), hull2, cv::Scalar(0), false); cv::findContours(cv::Mat(hullIntersection), intersectionPolygon, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); } if (intersectionPolygon.empty()) { outsideArea = 0; return false; } double intersectionArea = std::abs(cv::contourArea(intersectionPolygon[0])); // 修改此处 double polygon1Area = std::abs(cv::contourArea(polygon1)); outsideArea = polygon1Area - intersectionArea; return true; // 修改此处 } ``` 你需要将 `intersectionPolygon` 的类型从 `std::vector<cv::Point>` 改为 `std::vector<std::vector<cv::Point>>`,以及在计算交集面积时使用 `intersectionPolygon[0]` 来获取轮廓。 另外,最后一行需要返回 true,因为在计算出多边形1在多边形2外部的面积后,函数应该返回 true。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值