Opencv学习----基本结构对象-cv::_InputArray

4.1.1 定义

这是将只读输入数组传递到OpenCV函数的代理类。

它被定义为:

typedef  const  _InputArray& InputArray ;

_InputArray是由Mat、Mat_<T>、Matx<T,m,n>、std::vector<T>、std::vector<std::vector<T> >、std::vector<Mat>、std::vector<Mat_<T> >、UMat、std::vector<UMat>或double构造的类。它也可以由矩阵表达式构造。

该类仅用于传递参数。也就是说,通常不应该声明该类的类成员、局部变量和全局变量。

4.1.2 成员和接口

首先需要说明的是_InputArray在mat.hpp文件中定义,对应接口的实现包括两个文件mat.inl.hpp和matrix_wrap.cpp,mat.inl.hpp是一些内联函数,而其他非内联接口则在matrix_wrap.cpp中实现。

(1)成员

int flags;

对应KindFlag枚举,标识输入对象的类型

void* obj;

输入对象的指针

Size sz;

 

2)接口

_InputArray (int _flags, void *_obj)

_InputArray (const Mat &m)

_InputArray (const std::vector< Mat > &vec)

_InputArray (const UMat &um)

int   channels (int i=-1) const

Mat getMat(int idx=-1) const;

void getMatVector(std::vector<Mat>& mv) const;

cuda::GpuMat getGpuMat() const;

ogl::Buffer getOGlBuffer() const;

int getFlags() const;

void* getObj() const;

Size getSz() 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 depth(int i=-1) const;

bool empty() const;

void copyTo(const _OutputArray& arr) const;

bool isMat() const;

bool isVector() const;

(3)接口实现说明

构造接口:
inline void _InputArray::init(int _flags, const void* _obj)
{ flags = _flags; obj = (void*)_obj; }

inline void _InputArray::init(int _flags, const void* _obj, Size _sz)
{ flags = _flags; obj = (void*)_obj; sz = _sz; }

inline _InputArray::_InputArray() { init(0 + NONE, 0); }

inline _InputArray::_InputArray(const Mat& m) { init(MAT+ACCESS_READ, &m); }

inline _InputArray::_InputArray(const std::vector<Mat>& vec) { init(STD_VECTOR_MAT+ACCESS_READ, &vec); }

template<typename _Tp> inline
_InputArray::_InputArray(const std::vector<_Tp>& vec)
{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec); }

inline bool _InputArray::isMat() const { return kind() == _InputArray::MAT; }

其他接口:
int _InputArray::type(int i) const
{
	。。。
    if( k == STD_VECTOR_MAT )
{
。。。
        return vv[i >= 0 ? i : 0].type();
    }
	。。。
	return obj->type();
}
如果类型为集合类型,则i可以传入指定的序号,type接口返回的就是指定序号对象的类型。

int _InputArray::channels(int i) const
{
    return CV_MAT_CN(type(i));
}
相关宏定义如下:
#define CV_CN_MAX     512
#define CV_CN_SHIFT   3
#define CV_DEPTH_MAX  (1 << CV_CN_SHIFT)

#define CV_MAT_CN_MASK          ((CV_CN_MAX - 1) << CV_CN_SHIFT)
#define CV_MAT_CN(flags)        ((((flags) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
假设对象为Mat,Mat的type接口定义如下:
The method returns a matrix element type. This is an identifier compatible with the CvMat type system, like CV_16SC3 or 16-bit signed 3-channel array, and so on.
int type() const;

Mat的type接口的实现如下:
inline int Mat::type() const
{
    return CV_MAT_TYPE(flags);
}
#define CV_MAT_TYPE_MASK        (CV_DEPTH_MAX*CV_CN_MAX - 1)
#define CV_MAT_TYPE(flags)      ((flags) & CV_MAT_TYPE_MASK)

flags在构造函数赋值:
inline Mat::Mat(): flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),datalimit(0), allocator(0), u(0), size(&rows), step(0)
{}

enum { MAGIC_VAL  = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };

则_InputArray::channels返回结果:
=(((((( MAGIC_VAL) & CV_MAT_TYPE_MASK)) & CV_MAT_CN_MASK) >> CV_CN_SHIFT) + 1)
返回的结果代表什么暂时不清楚。

4.1.3 使用

使用2x3矩阵作为Matx<float, 2, 3>实例对向量进行仿射变换。

std::vector<Point2f> vec;
// points or a circle
for( int i = 0; i < 30; i++ )
    vec.push_back(Point2f((float)(100 + 30*cos(i*CV_PI*2/5)),
                          (float)(100 - 30*sin(i*CV_PI*2/5))));
cv::transform(vec, vec, cv::Matx23f(0.707, -0.707, 10, 0.707, 0.707, 20));

void myAffineTransform(InputArray _src, OutputArray _dst, InputArray _m)
{
    // get Mat headers for input arrays. This is O(1) operation,
    // unless _src and/or _m are matrix expressions.
    Mat src = _src.getMat(), m = _m.getMat();
    CV_Assert( src.type() == CV_32FC2 && m.type() == CV_32F && m.size() == Size(3, 2) );
    // [re]create the output array so that it has the proper size and type.
    // In case of Mat it calls Mat::create, in case of STL vector it calls vector::resize.
    _dst.create(src.size(), src.type());
    Mat dst = _dst.getMat();
    for( int i = 0; i < src.rows; i++ )
        for( int j = 0; j < src.cols; j++ )
        {
            Point2f pt = src.at<Point2f>(i, j);
            dst.at<Point2f>(i, j) = Point2f(m.at<float>(0, 0)*pt.x +
                                            m.at<float>(0, 1)*pt.y +
                                            m.at<float>(0, 2),
                                            m.at<float>(1, 0)*pt.x +
                                            m.at<float>(1, 1)*pt.y +
                                            m.at<float>(1, 2));
        }
}

cv::_OutputArray与cv::_InputArray相似,只是用于输出。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 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
发出的红包

打赏作者

dylan55_you

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值