【OpenCV 4开发详解】图像上绘制几何图形
本文首发于“小白学视觉”微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究!
经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《OpenCV 4开发详解》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通,提前在公众号上连载部分内容,请持续关注小白。 |
有时我们需要根据自身的需求在图像中绘制一些图案以起到突出某些内容的作用,例如在某些特别的区域用圆圈起来,或者在图中输入文字进行说明。因此本节将介绍OpenCV 4中用于绘制基础图形的函数。
绘制圆形
圆形是我们在平时中最常使用的图形之一,OpenCV 4中提供了circle()函数用于绘制圆型,其函数的函数原型在代码清单3-40中给出。
代码清单3-40 circle()函数原型
1. void cv::circle(InputOutputArray img,
2. Point center,
3. int radius,
4. const Scalar & color,
5. int thickness = 1,
6. int lineType = LINE_8,
7. int shift = 0
8. )
- img:需要绘制圆形的图像
- center:圆形的圆心位置坐标。
- radius:圆形的半径长度,单位为像素。
- color:圆形的颜色。
- thickness:轮廓的宽度,如果数值为负,则绘制一个实心圆。
- lineType:边界的类型,可取值为FILLED ,LINE_4 ,LINE_8 和LINE_AA
- shift:中心坐标和半径数值中的小数位数。
该函数用于在一张图像中绘制圆形的图案,输入的参数分别是圆形的圆形位置、半径长度以及边界线的宽度和线型。对于该函数的使用我们将在本节最后的代码清单3-47中一起给出。
绘制直线
接下来介绍如何在图像中绘制直线。OpenCV 4中提供了line()函数用于绘制直线,其函数原型在代码清单3-41中给出。
代码清单3-41 line()函数原型
1. void cv::line(InputOutputArray img,
2. Point pt1,
3. Point pt2,
4. const Scalar & color,
5. int thickness = 1,
6. int lineType = LINE_8,
7. int shift = 0
8. )
- pt1:直线起始点在图像中的坐标。
- pt2:直线终点在图像中的坐标。
- color:圆形的颜色,用三通道表示。
该函数利用两点确定一条直线的方式在图像中画出一条直线,函数中的很多参数的含义都与circle()函数一致,这里就不在赘述。对于该函数的使用我们将在本节最后的代码清单3-47中一起给出。
绘制椭圆
在OpenCV 4中提供了ellipse()函数用于绘制椭圆,其函数原型在代码清单3-42中所示。
代码清单3-42 ellipse()函数原型
1. void cv::ellipse(InputOutputArray img,
2. Point center,
3. Size axes,
4. double angle,
5. double startAngle,
6. double endAngle,
7. const Scalar & color,
8. int thickness = 1,
9. int lineType = LINE_8,
10. int shift = 0
11. )
- center:椭圆的中心坐标。
- axes:椭圆主轴大小的一半。
- angle:椭圆旋转的角度,单位为度。
- startAngle:椭圆弧起始的角度,单位为度。
- endAngle:椭圆弧终止的角度,单位为度
该函数中的很多参数的含义都与circle()函数一致,这里就不在赘述。函数通过选定椭圆中心位置和主轴的大小唯一确定一个椭圆,并且可以控制旋转角度改变椭圆在坐标系中的位置。通过椭圆弧起始和终止角度,可以绘制完整的椭圆或者一部分椭圆弧。与circle()函数一致,当边界线的厚度值为负数的时候,将绘制一个实心的椭圆。
在OpenCV 4中还提供了另外一个函数ellipse2Poly()用于输出椭圆的边界的像素坐标,但是不会在图像中绘制椭圆,其函数原型在代码清单3-43中给出。
代码清单3-43 ellipse2Poly()函数原型
1. void cv::ellipse2Poly(Point center,
2. Size axes,
3. int angle,
4. int arcStart,
5. int arcEnd,
6. int delta,
7. std::vector< Point > & pts
8. )
- delta:后续折线顶点之间的角度,它定义了近似精度。
- pts:椭圆边缘像素坐标向量集合。
该函数与绘制椭圆需要输入的参数一致,只是不将椭圆输出到图像中,而是通过vector向量将椭圆边缘的坐标点存储起来,便于后续的再处理。对于绘制椭圆相关函数的使用我们将在本节最后的代码清单3-47中一起给出。
绘制多边形
在几何中多边形也是一个重要的成员,而多边形中矩形又是一个比较特殊的类型,因此OpenCV 4中除了提供绘制多边形的函数fillPoly()外,也提供了绘制矩形的函数rectangle()。我们先介绍矩形的绘制,之后再介绍多边形的绘制。在代码清单3-44中给出了rectangle()函数的函数原型。
代码清单3-44 rectangle()函数原型
1. void cv::rectangle(InputOutputArray img,
2. Point pt1,
3. Point pt2,
4. const Scalar & color,
5. int thickness = 1,
6. int lineType = LINE_8,
7. int shift = 0
8. )
9.
10. void cv::rectangle(InputOutputArray img,
11. Rect rec,
12. const Scalar & color,
13. int thickness = 1,
14. int lineType = LINE_8,
15. int shift = 0
16. )
- pt1:矩形的一个顶点
- pt2:矩形中与pt1相对的顶点,即两个点在对角线上。
- rec:矩形左上角定点和长宽。
函数中与前文参数含义一致的参数不再重复介绍。在OpenCV 4中定义了两种函数原型,分别利用矩形对角线上的两个顶点的坐标或者利用左上角顶点坐标和矩形的长和宽唯一确定一个矩形。在绘制矩形时,同样可以控制边缘线的宽度绘制一个实心的矩形。
这里我们详细介绍Rect变量,该变量在OpenCV 4中表示矩形的含义,与Point、Vec3b等类型相同,都是在图像处理中常用的类型。Rect表示的是一个矩形的左上角和矩形的长和宽,该类型定义的格式为Rect(像素的x坐标,像素的y坐标,矩形的宽,矩形的高),其中可以存放的数据类型也分别为int型(Rect2i或者Rect)、double类型(Rect2d)和float类型(Rect2f)。
接下来介绍多边形绘制函数fillPoly()的使用方法,其函数原型在代码清单3-45中给出。
代码清单3-45 fillPoly()函数原型
1. void cv::fillPoly(InputOutputArray img,
2. const Point ** pts,
3. const int * npts,
4. int ncontours,
5. const Scalar & color,
6. int lineType = LINE_8,
7. int shift = 0,
8. Point offset = Point()
9. )
- pts:多边形顶点数组,可以存放多个多边形的顶点坐标的数组。
- npts:每个多边形顶点数组中顶点个数。
- ncontours:绘制多边形的个数。
- offset:所有顶点的可选偏移。
该函数中与前文含义相同的参数不再重复介绍。函数通过依次连接多边形的顶点来实现多边形的绘制,多边形的顶点需要按照顺时针或者逆时针的顺序依次给出,通过控制边界线宽度可以实现是否绘制实心的多边形。需要说明的是pts参数是一个数组,数组中存放的是每个多边形顶点坐标数组,npts参数也是一个数组,用于存放pts数组中每个元素中顶点的个数。关于多边形绘制的相关函数使用方法将在代码清单3-47中给出,读者一定要格外认真的体会使用方法。
文字生成
本节的最后介绍如何通过OpenCV 4实现在图像中生成文字的putText()函数,该函数的函数原型在代码清单3-46中给出。
代码清单3-46 putText()函数原型
1. void cv::putText(InputOutputArray img,
2. const String & text,
3. Point org,
4. int fontFace,
5. double fontScale,
6. Scalar color,
7. int thickness = 1,
8. int lineType = LINE_8,
9. bool bottomLeftOrigin = false
10. )
- text:输出到图像中的文字,目前OpenCV 4只支持英文。
- org:图像中文字字符串的左下角像素坐标。
- fontFace:字体类型的选择标志,参数取值范围及含义在表3-8中给出。
- fontScale:字体的大小。
- bottomLeftOrigin:图像数据原点的位置,默认为左上角,如果参数改为true,则原点为左下角。
表3-8 getPerspectiveTransform()函数计算方法标志
标志参数 | 简记 | 作用 |
---|---|---|
FONT_HERSHEY_SIMPLEX | 0 | 正常大小的无衬线字体 |
FONT_HERSHEY_PLAIN | 1 | 小尺寸的无衬线字体 |
FONT_HERSHEY_DUPLEX | 2 | 正常大小的较复杂的无衬线字体 |
FONT_HERSHEY_COMPLEX | 3 | 正常大小的衬线字体 |
FONT_HERSHEY_TRIPLEX | 4 | 正常大小的较复杂的衬线字体 |
FONT_HERSHEY_COMPLEX_SMALL | 5 | 小尺寸的衬线字体 |
FONT_HERSHEY_SCRIPT_SIMPLEX | 6 | 手写风格的字体 |
FONT_HERSHEY_SCRIPT_COMPLEX | 7 | 复杂的手写风格字体 |
FONT_ITALIC | 16 | 标志为斜体字体 |
该函数中与前文含义相同的参数不再重复介绍。目前该函数只支持英文的输出,如果想要在图像中输出中文,需要添加额外的依赖项,这里不进行扩展,有需求的读者可以寻找相关资料进行进一步的学习。
为了体会绘制几何图像的函数的用法以及回值图案的样子,在代码清单3-47中给出了本节中前文介绍的所有函数的使用方式,读者可以认真体会其使用方式和最终结果,尤其要注意绘制多边形函数的使用方式。程序运行的结果在图3-28给出。
代码清单3-47 myPlot.cpp绘制基本几何图形
1. #include <opencv2\opencv.hpp>
2. #include <iostream>
3.
4. using namespace cv;
5. using namespace std;
6.
7. int main()
8. {9. Mat img = Mat::zeros(Size(512, 512), CV_8UC3); //生成一个黑色图像用于绘制几何图形
10. //绘制圆形
11. circle(img, Point(50, 50), 25, Scalar(255, 255, 255), -1); //绘制一个实心圆
12. circle(img, Point(100, 50), 20, Scalar(255, 255, 255), 4); //绘制一个空心圆
13. //绘制直线
14. line(img, Point(100, 100), Point(200, 100), Scalar(255, 255, 255), 2, LINE_4,0);
15. //绘制椭圆
16. ellipse(img, Point(300,255), Size(100, 70), 0, 0, 100, Scalar(255,255,255), -1);
17. ellipse(img, RotatedRect(Point2f(150,100), Size2f(30,20), 0), Scalar(0,0,255),2);
18. vector<Point> points;
19. //用一些点来近似一个椭圆
20. ellipse2Poly(Point(200, 400), Size(100, 70),0,0,360,2,points);
21. for (int i = 0; i < points.size()-1; i++) //用直线把这个椭圆画出来
22. {23. if (i==points.size()-1)
24. {25. //椭圆中后于一个点与第一个点连线
26. line(img, points[0], points[i], Scalar(255, 255, 255), 2);
27. break;
28. }
29. //当前点与后一个点连线
30. line(img, points[i], points[i+1], Scalar(255, 255, 255), 2); }
31. //绘制矩形
32. rectangle(img, Point(50, 400), Point(100, 450), Scalar(125, 125, 125), -1);
33. rectangle(img, Rect(400,450,60,50), Scalar(0, 125, 125), 2);
34. //绘制多边形
35. Point pp[2][6];
36. pp[0][0] = Point(72, 200);
37. pp[0][1] = Point(142, 204);
38. pp[0][2] = Point(226, 263);
39. pp[0][3] = Point(172, 310);
40. pp[0][4] = Point(117, 319);
41. pp[0][5] = Point(15, 260);
42. pp[1][0] = Point(359, 339);
43. pp[1][1] = Point(447, 351);
44. pp[1][2] = Point(504, 349);
45. pp[1][3] = Point(484, 433);
46. pp[1][4] = Point(418, 449);
47. pp[1][5] = Point(354, 402);
48. Point pp2[5];
49. pp2[0] = Point(350, 83);
50. pp2[1] = Point(463, 90);
51. pp2[2] = Point(500, 171);
52. pp2[3] = Point(421, 194);
53. pp2[4] = Point(338, 141);
54. const Point* pts[3] = { pp[0],pp[1],pp2 }; //pts变量的生成
55. int npts[] = { 6,6,5 }; //顶点个数数组的生成
56. fillPoly(img, pts, npts, 3, Scalar(125, 125, 125),8); //绘制3个多边形
57. //生成文字
58. putText(img, "Learn OpenCV 4",Point(100, 400), 2, 1, Scalar(255, 255, 255));
59. imshow("", img);
60. waitKey(0);
61. return 0;
62. }
图3-28 myPlot.cpp程序运行结果
OpenCV 4开发详解 |
往期推荐 |
---|
【OpenCV 4开发详解】Windows系统中安装OpenCV 4 |
【OpenCV 4开发详解】Ubuntu系统中安装OpenCV 4 |
【OpenCV 4开发详解】opencv_contrib扩展模块的安装 |
【OpenCV 4开发详解】Image Watch插件的使用 |
【OpenCV 4开发详解】安装过程中问题解决方案 |
【OpenCV 4开发详解】了解OpenCV的模块架构 |
【OpenCV 4开发详解】Mat类介绍 |
【OpenCV 4开发详解】Mat类构造与赋值 |
【OpenCV 4开发详解】4种读取Mat类元素的的方法 |
【OpenCV 4开发详解】图像的读取与显示 |
【OpenCV 4开发详解】视频加载与摄像头调用 |
【OpenCV 4开发详解】图像与视频的保存 |
【OpenCV 4开发详解】保存和读取XML和YMAL文件 |
【OpenCV 4开发详解】颜色模型与转换 |
【OpenCV 4开发详解】多通道分离与合并 |
【OpenCV 4开发详解】图像像素统计 |
【OpenCV 4开发详解】两图像间的像素操作 |
【OpenCV 4开发详解】图像二值化 |
【OpenCV 4开发详解】图像LUT查找表 |
【OpenCV 4开发详解】图像连接 |
【OpenCV 4开发详解】图像仿射变换 |
【OpenCV 4开发详解】图像透视变换 |
【OpenCV 4开发详解】图像极坐标变换 |
经过几个月的努力,市面上第一本OpenCV 4入门书籍《OpenCV 4开发详解》将春节后由人民邮电出版社发行。如果小伙伴觉得内容有帮助,希望到时候多多支持! |
关注小白的小伙伴可以提前看到书中的内容,我们创建了学习交流群,欢迎各位小伙伴添加小白微信加入交流群,添加小白时请备注“学习OpenCV 4”。 |
【OpenCV 4开发详解】图像上绘制几何图形相关推荐
- 【OpenCV 4开发详解】图像直方图绘制
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
- 【OpenCV 4开发详解】分割图像——分水岭法
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
- 【OpenCV 4开发详解】图像修复
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
- 【OpenCV 4开发详解】分割图像——Mean-Shift分割算法
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
- 【OpenCV 4开发详解】分割图像——Grabcut图像分割
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
- 【OpenCV 4开发详解】轮廓发现与绘制
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
- 【OpenCV 4开发详解】图像二值化
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
- 【OpenCV 4开发详解】图像膨胀
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
- 【OpenCV 4开发详解】图像腐蚀
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
最新文章
- 003_Maven插件
- C#调用C++ DLL的方式
- python怎么编辑文件_如何使用python中的方法对文件进行修改文件名
- LCD1602的四线驱动
- Vscode 新建HTML文件
- 分享雷柏无线鼠标接收器损坏后的更换方法
- 云计算时代,NGINX将是你的“必杀技”
- vue给div绑定keyup的enter事件实现接电话(结合阿里云软电话SDK)
- 加装ssd固态硬盘基本要求
- 你有没有感觉现在4G的速度越来越慢了?为什么?
- 计算机中全半角转换是干什么的,全角半角切换快捷键(电脑全角和半角怎么切换)...
- 买笔记本电脑的13个重要的验机步骤
- Blazor 从入门到放弃
- android学习十八(Service服务的基本用法)
- vue项目接入unity3D模块并进行数据通信
- 启动kafka无反应_kafka consumer无法正常启动原因调查
- 51单片机LED点阵屏学习笔记
- python猜字小游戏
- 易筋经、降龙十八掌在英语中如何翻译
- 计算机考证有什么职称
热门文章
- CVPR 2019 | 惊艳的SiamMask:开源快速同时进行目标跟踪与分割算法
- 都有Python了,还要什么编译器!
- 用AI为美国政府“助纣为虐”,微软员工怒了
- 为什么不推荐使用 stop、suspend 方法中断线程?
- Redis分布式锁使用不当,酿成一个重大事故,超卖了100瓶飞天茅台!!!
- IDEA真牛逼,900行又臭又长的类重构,几分钟搞定
- 最近面试Java后端开发的感受
- 如何判断一个元素在亿级数据中是否存在?
- 条件注解 @ConditionalOnBean 的正确使用姿势
- 【精简教程版】100行代码入手天池CV赛事