您的位置:首页 > 运维架构

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

2016-12-28 14:22 531 查看
第一个是画直线程序,最终效果是在打开的图片上出现一条直线。

#include <opencv2/opencv.hpp>
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)之类。

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

#include <opencv2/opencv.hpp>
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 <opencv2/opencv.hpp>
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 <cv.h>
#include <highgui.h>
#include <stdio.h>

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还有其他的画几何图形的函数,大家可以自己去找一下,这儿列举的只是常见的函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐