小白记录:《Opencv3 编程入门》P102-P103的问题总结

在该书中的4.3基本图形的绘制的例程中,关于P102中的DrawPolygon()函数的写法代码中,遇到了几个问题,这里进行自我总结:
首先贴出书上的源码:

//-------------------【DrawPolygon( )函数】--------------------------
//描述:自定义的绘制函数,实现了凹多边形的绘制
//-----------------------------------------------------------------
void DrawPolygon( Mat img )
{
 int lineType = 8;
 //创建一些点
 Point rookPoints[1][20];
 rookPoints[0][0]  = Point(    WINDOW_WIDTH/4,   7*WINDOW_WIDTH/8 );
 rookPoints[0][1]  = Point(  3*WINDOW_WIDTH/4,   7*WINDOW_WIDTH/8 );
 rookPoints[0][2]  = Point(  3*WINDOW_WIDTH/4,  13*WINDOW_WIDTH/16 );
 rookPoints[0][3]  = Point( 11*WINDOW_WIDTH/16, 13*WINDOW_WIDTH/16 );
 rookPoints[0][4]  = Point( 19*WINDOW_WIDTH/32,  3*WINDOW_WIDTH/8 );
 rookPoints[0][5]  = Point(  3*WINDOW_WIDTH/4,   3*WINDOW_WIDTH/8 );
 rookPoints[0][6]  = Point(  3*WINDOW_WIDTH/4,     WINDOW_WIDTH/8 );
 rookPoints[0][7]  = Point( 26*WINDOW_WIDTH/40,    WINDOW_WIDTH/8 );
 rookPoints[0][8]  = Point( 26*WINDOW_WIDTH/40,    WINDOW_WIDTH/4 );
 rookPoints[0][9]  = Point( 22*WINDOW_WIDTH/40,    WINDOW_WIDTH/4 );
 rookPoints[0][10] = Point( 22*WINDOW_WIDTH/40,    WINDOW_WIDTH/8 );
 rookPoints[0][11] = Point( 18*WINDOW_WIDTH/40,    WINDOW_WIDTH/8 );
 rookPoints[0][12] = Point( 18*WINDOW_WIDTH/40,    WINDOW_WIDTH/4 );
 rookPoints[0][13] = Point( 14*WINDOW_WIDTH/40,    WINDOW_WIDTH/4 );
 rookPoints[0][14] = Point( 14*WINDOW_WIDTH/40,    WINDOW_WIDTH/8 );
 rookPoints[0][15] = Point(    WINDOW_WIDTH/4,     WINDOW_WIDTH/8 );
 rookPoints[0][16] = Point(    WINDOW_WIDTH/4,   3*WINDOW_WIDTH/8 );
 rookPoints[0][17] = Point( 13*WINDOW_WIDTH/32,  3*WINDOW_WIDTH/8 );
 rookPoints[0][18] = Point(  5*WINDOW_WIDTH/16, 13*WINDOW_WIDTH/16 );
 rookPoints[0][19] = Point(    WINDOW_WIDTH/4,  13*WINDOW_WIDTH/16 );
 
 const Point* ppt[1] = { rookPoints[0] };
 int npt[] = { 20 };
 fillPoly( img,
  ppt,
  npt,
  1,
  Scalar( 255, 255, 255 ),
  lineType );
}

遇到的问题:
①为什么创建一些点的时候,要定义二维数组Point rookPoints[1][20];这和直接定义一维数组Point rookPoint[20];不是一样的吗?
②在定义了点的二维数组Point rookPoints[1][20];之后,为何又要定义一个中间变量const Point* ppt[1] = { rookPoints[0] };呢?
③在书中关于fillPoly()函数中,说明了npt是绘制的多边形顶点数目,为什么要定义成int npt[] = { 20 };而不是直接定义成 int npt=20;呢?

首先去找了下关于fillPoly()函数的说明:
void fillPoly(cvArr* img, cvPoint** pts,int* npts, int contours, cvScalar color, int line_type=8, int shift=0;);
参数说明:
img:图像
pts:指向多边形的数组指针
npts:多边形的顶点个数的数组
contours:要绘制多边形的数量
color:多边形的颜色
line_type:组成多边形的线条的类型
shift:顶点坐标的小数点位数

这就可以解释问题①中为什么要定义二维数组了,因为fillPoly函数中第二个参数就是这么要求的cvPoint**类型
问题③也能解决了,因为要求的是多边形的顶点个数的数组。

关于问题②,在网上也问了一些人,查了些资料,大概意思是
因为fillPoly函数中要求的是cvPoint**类型,直接传rookPoints的话 有些编译器会报warning 甚至还会报error 的错误。若想避免这个才会加个中间变量。

看到这里时,我还是一脸懵逼,fillPoly函数中要求的是二级常指针,而作为中间变量的const Point* ppt[1]他还是一个一级常指针啊,为什么编译就通过了呢?

网上还给出了一个测试程序:

#include <iostream>
using namespace std;
typedef int Point;
void fillPoly(const Point** pts)
{
}
int main()
{
    Point rookPoints[1][20];
    const Point* ppt[1] = { rookPoints[0] };
    Point* ppt1[1] = { rookPoints[0] };
    fillPoly(ppt);
    fillPoly(ppt1);
    fillPoly(rookPoints);
    fillPoly((const Point **)rookPoints);
     
    return 0;
}

大概意思就是定义了一个fillPoly函数、一个rookPoints数组和两个中间变量ppt和ppt1。我去VS编译器试了下,进行编译的时候,fillPoly(ppt1);和fillPoly(rookPoints);报错了,而fillPoly(ppt);和fillPoly((const Point **)rookPoints);没有报错。

这里的fillPoly(ppt);就和书上的做法一样,但明明ppt是一级常指针,却没有报错,还是不明白。

关于一级和二级常指针,自己也补充了点知识:如果函数给它传递的是int*参数,编译是可以通过的,不需要强制转换;但如果是传递的int**参数,编译不能通过,需要进行强制转换,就如上面的fillPoly((const Point **)rookPoints);。

仍然没有解决问题②,若有大佬看到,麻烦能解惑,不胜感激!

发布了25 篇原创文章 · 获赞 0 · 访问量 475

猜你喜欢

转载自blog.csdn.net/qq_45445740/article/details/102681428