opencv学习笔记(十)画直线、矩形、圆形、椭圆以及多边形程序

第一个是画直线程序,最终效果是在打开的图片上出现一条直线。

#include 
int main(int argc, char **argv[])
{
    IplImage* img =cvLoadImage( "a.jpg",-1);  
    CvScalar color = CV_RGB(255,0,0); 
    cvLine(img,cvPoint(0,0),cvPoint(100,100),color,10,8);
    cvNamedWindow("测试",CV_WINDOW_AUTOSIZE);
    cvShowImage("测试",img);
    cvWaitKey();
    cvReleaseImage(&img);
    cvDestroyWindow("测试");
}

1.1 cvLine
函数原型:
void cvLine(
CvArr* array,
CvPoint pt1,
CvPoint pt2,
CvScalar color,
int thickness = 1,
int connectivity= 8
);
百度得,百度百科里面还有一个参数int shift=0
shift :坐标点的小数点位数。
注意是:我试过了,在程序里加入这个参数并不报错,可见这个参数应该是存在的。

cvLine ( )函数中的第一个属性是CvArr*。在这里,它一般为一个图像类型的指针IplImage*。随后两个CvPoint是一种简单的数据结构,它只包括整型变量x和y。我们可以用CvPoint(int x,int y)函数快速地构造一个CvPoint类型的变量,这样可以方便地把两个整型变量值赋给CvPoint数据结构。
下一个属性是CvScalar类型的颜色变量。CvScalar也是一种数据结构,定义如下所示:
typedef struct{
double val[4];
}CvScalar;
可以看出,这种结构只是四个双精度浮点型变量的集合。在这里,前三个分别代表红,绿,蓝通道;没有用到第四个(它只在适当的时候用于alpha通道)。一个常用的便捷宏指令是CV_RGB(r, g, b),该指令采用三个数字作为参数并将其封装到CvScalar。
接下来的两个属性是可选的。thickness是线的粗细(像素),connectivity被设为反走样模式,默认值为“8连通”,这种是较为平滑不会走样的线型。也可以设置为“4连通”,这样的话,斜线会产生重叠以致看上去过于粗重,不过画起来速度要快得多。

pt1 线段的第一个端点。
pt2 线段的第二个端点。
color 线段的颜色。
thickness 线段的粗细程度(填数字就行)。
int connectivity 线段的类型。
8 (or 0) - 8-connected line(8邻接)连接线。
4 - 4-connected line(4邻接)连接线。
CV_AA - antialiased 线条(百度下是“抗锯齿线条”)。
1.2 CV_RGB
CV_RGB是OPENCV中的一个宏,用于创建一个色彩值:
#define CV_RGB(r,g,b) cvScalar((b),(g),(r))。
R(红),G(绿),B(蓝)
1.3 cvPoint
OpenCV的基本数据类型之一,表示一个坐标为整数的二维点,是一个包含integer类型成员x和y的简单结构体。
所以程序中是cvPoint(0,0)之类。

下面的是画一个矩形程序:

#include 
int main(int argc, char **argv[])
{
    IplImage* img =cvLoadImage( "a.jpg",-1);  
    CvScalar color = CV_RGB(0,0,255); 
    cvRectangle(img,cvPoint(0,0),cvPoint(100,100),color,5,4,0);
    cvNamedWindow("测试",CV_WINDOW_AUTOSIZE);
    cvShowImage("测试",img);
    cvWaitKey();
    cvReleaseImage(&img);
    cvDestroyWindow("测试");
}

这个程序和上面的画线程序几乎一模一样。
2.1 cvRectangle
cvRectangle()和cvLine( )几乎同样便捷。cvRectangle()用于画矩形。除了没有connectivity参数,它和cvLine()的其他参数都是一样的。因为由此产生的矩形总是平行与X和Y轴。利用cvRectangle( ),我们只需给出两个对顶点,OpenCV便于画出一个矩形。
定义:
void cvRectangle(
CvArr* array,
CvPoint pt1,
CvPoint pt2,
CvScalar color,
int thickness=1,
);
其中:
thickness
组成矩形的线条的粗细程度。取负值时(如 CV_FILLED——可以直接写成-1,-2之类)函数绘制填充了色彩的矩形。
但是,我发现如果再加一个参数也是可以的,就是int connectivity=8这个参数——百度到的有。int shift=0 也有。

接下来是画圆:

#include 
int main(int argc, char **argv[])
{
    IplImage* img =cvLoadImage( "a.jpg",-1);  
    CvScalar color = CV_RGB(0,0,255); 
    cvCircle( img,cvPoint(200,300),59,color,CV_FILLED);
    cvNamedWindow("测试",CV_WINDOW_AUTOSIZE);
    cvShowImage("测试",img);
    cvWaitKey();
    cvReleaseImage(&img);
    cvDestroyWindow("测试");
}

3.1 cvCircle圆
void cvCircle(
CvArr* array,
CvPoint center, //圆心
CvPoint radius, // 半径
CvScalar color,
int thickness=1,
int connectivity=8
);
对圆形和矩阵等很多封闭图形来说,thickness参数也可以设置为CV_FILL,其值是一1;其结果是使用与边一样的颜色填充圆内部。

画椭圆的程序和圆类似,只不过换了一个函数:
3.2 cvEllipse椭圆
void cvEllipse(
CvArr* img,
CvPoint center,//圆心
Cvsize axes,//长短轴
double angle,//径向夹角(水平面到长轴的夹角
//从X轴算起,逆时针方向为正。)
double start_angle,//起始角度(长轴到起始边沿的夹角)
double end_angle,//结束角度(长轴到结束点的夹角)
CvScalar color,
int thickness=1,
int line_type=8
);

这里,主要的新成员是axes属性,其类型为Cvsize。Cvsize函数与CvPoint和CvSCalar非常相似;这是一个仅包含宽度和高度的简单结构。同CvPoint和CvSCalar一样,Cvsize也有一个简单的构造函数cvsize(int height,int width),在需要的时候返回一个Cvsize数据。在这种情况下,height和width参数分别代表椭圆的长短半轴长。
angle是指偏离主轴的角度,从X轴算起,逆时针方向为正。同样,start_angle和end_angle表示弧线开始和结束位置的角度。因此,一个完整的椭圆必须分别将这两个值分别设为0°和360°。
如果设置成0,180就是半个椭圆——按顺时针方向来。

接下来是一个画多边形的程序:

#include 
#include 
#include 

int main(int argc, char** argv)
{
  IplImage *src1;
  src1 = cvLoadImage("1.jpg");
  int arr[3]= {4,4,4};   
  CvPoint ** pt =new CvPoint*[3];
  pt[0] = new CvPoint[4];  
  pt[0][0] = cvPoint(10,10);  
  pt[0][1] = cvPoint(210,10);  
  pt[0][2] = cvPoint(210,210);  
  pt[0][3] = cvPoint(10,210);  
  pt[1] = new CvPoint[4]; 
  pt[1][0] = cvPoint(10,310);  
  pt[1][1] = cvPoint(210,310);  
  pt[1][2] = cvPoint(210,510);  
  pt[1][3] = cvPoint(10,510);  
  pt[2] = new CvPoint[4]; 
  pt[2][0] = cvPoint(310,10);  
  pt[2][1] = cvPoint(410,10);  
  pt[2][2] = cvPoint(410,210);  
  pt[2][3] = cvPoint(310,210);  
  cvFillPoly(src1, pt,arr,3,CV_RGB(250,0,0));  
  cvShowImage( "结果图", src1);
  cvWaitKey();
  return 0;
}

4.1 cvFillPoly—画多个实心多边形
其结构
void cvFillPoly( //画多个实心多边形
CvArr* img,//画布图像
CvPoint** pts,//点序列
int* npts,//计数点数组
int contours,//显示几个多边形
CvScalar color,//颜色
int line_type = 8
);
在cvFillPoly ( )中,点是由CvPoint数组提供的。它允许cvFillPoly ( )在一次调用中绘制多个多边形。同样地,npt是由记数点构成的数组,与多边形对应。
cvFillPoly ( )很稳定,可以处理自相交多边形,有孔的多边形等复杂问题。然而不幸的是,函数运行起来相对缓慢。
我们先来看这句话 CvPoint * pt =new CvPoint[3];
创建一个指向指针的指针,那么它指向的肯定是指针——
new CvPoint*[3];就是一个指针数组,里面每个元素都是一个指针。
[3]代表有3个元素——就是下面有3个多边形的端点。
在函数定义里:
CvPoint** pts,//点序列
所以,我们这里创建的pt是我们将要创建的多边形的端点坐标。
pt[0] = new CvPoint[4];
pt[0]是指第一个多边形的端点
pt[1]是第二个(下标从0开始)
然后我们在看看new CvPoint[4]; 它是指针数组new CvPoint*[3]里面的一个元素。
pt[0][0] = cvPoint(10,10);
pt[0][1] = cvPoint(210,10);
pt[0][2] = cvPoint(210,210);
pt[0][3] = cvPoint(10,210);
上述的4个cvPoint就是这个new CvPoint[4]指向的数组。
然后需要注意的一点是,假如创建的多边形有5个点,那么写成
pt[0] = new CvPoint[5];
然后分别是5个点的坐标——N个点也一样(试过了)。
再看 int arr[3]= {4,4,4};
这是干嘛用的呢?
定义里说: int* npts,//计数点数组
里面的每个元素与我们队的多边形的端点数目一一对应——顺序不能乱。
假如定义的第一个多边形是5边形,那么它的第一个元素就是5,以此类推。
再看最后一个参数:
int contours,//显示几个多边形
这是干嘛用的呢?
假如我们定义了4个多边形,这个参数为3,那么就是只显示前3个定义的多边形。

opencv还有其他的画几何图形的函数,大家可以自己去找一下,这儿列举的只是常见的函数。

你可能感兴趣的:(opencv)