<学习opencv>绘画和注释
/*=========================================================================*/
// 绘画 和 注释
/*=========================================================================*/
我们经常想画一些图片,或者在从其他地方获得的图像上画一些东西。
为了达到这个目的,OpenCV提供了一个可以让我们制作线条、正方形、圆形等的功能。 OpenCv的绘图功能可以处理任何深度的图像,
但大多数只影响前三个通道-对于单通道图像,默认为仅第一个通道。
大多数绘图功能都支持对象的颜色、粗细、线条类型(实际上是指是否反混叠线条)和子像素对齐。 指定颜色时,约定是使用cv::scalar对象,即使大多数情况下只使用前三个值。
(有时使用cv::scalar中的第四个值来表示alpha通道比较方便,但绘图函数目前不支持alpha混合)
此外,按照惯例,opencv使用bgrordering将多通道图像转换为颜色渲染
(这是u由绘制函数imshow()生成,它实际上在屏幕上绘制图像以供查看)。
当然,您不必使用这个约定,而且如果您使用的是其他库中的数据,
并且这些库的顶部有opencv头,那么它可能不理想。
在任何情况下,库的核心功能总是与您可能分配给某个通道的任何“含义”无关。 线条艺术和填充多边形
——————————————————————————————————————————————————————————————————————————————
绘制一种或另一种线条(段、圆、矩形等)的函数通常接受厚度和线型参数。
两者都是整数,但后者唯一可接受的值是4、8或cv::LINE_AA。
厚度是以像素为单位测量的线条的厚度。
对于圆、矩形和所有其他闭合形状,厚度参数也可以设置为cv::filled(它是−1的别名)。 画一条线,种类或其他(片段,圆形,矩形等)的函数通常会接受a thickness 和lineType 参数。
两者都是整数,但对于后者的唯一可接受的值为4 ,8 ,或cv::LINE_AA 。
thickness 是以像素为单位测量的线条粗细。
对于圆形,矩形和所有其他闭合形状,thickness 参数也可以设置为cv::FILLED (这是别名−1 )。
在这种情况下,结果是绘制的图形将填充与边缘相同的颜色。
该lineType 参数表示线路是“4连接”, “8连接”还是抗锯齿。
对于下面两个示例 ,使用了Bresenham算法,而对于抗锯齿线, 使用高斯滤波。宽线总是绘制圆形末端。 列出的绘制算法 ,端点(线),中心点(圆),角(矩形)等通常指定为整数。
但是,这些算法通过shift 参数支持子像素对齐。在shift 可用的地方,
它被解释为整数参数中作为小数位处理的位数。
例如,如果您想要一个以(5,5)为中心的圆,但设置shift 为1,则圆将在(2.5,2.5)处绘制。
这种效果通常非常微妙,取决于所使用的线型。对于抗锯齿线,效果最明显。 【绘图功能】
【【线条艺术和填充多边形】】
——————————————————————————————————————————————————————————————————————————————
功能 | 描述
——————————————————————————————————————————————————————————————————————————————
cv::circle() | 画出一个简单的圆圈
|——用法:
circle(
cv::Mat &img , //要绘制的图像
cv::Point center , //圆心的位置
int radius , //圆的半径
const cv::Scalar& color, //颜色,RGB形式
int thickness = 1 , //线的粗细
int lineType = 8 , // Connectedness,4或8
int shift = 0 //作为分数处理的半径位
)
cv::circle()的第一个参数就是图像img。接下来是圆心、二维点和半径。
其余参数是标准颜色、厚度、线型和SHIFT。移动同时应用于半径和中心位置。 ——————————————————————————————————————————————————————————————————————————————
cv::clipLine() | 确定一条线是否在给定的椭圆之中
|——用法:
bool clipLine(//如果'imgRect'中的任何一行,则为True
cv :: Rect imgRect,//要剪切的矩形
cv :: Point&pt1,//行的第一个端点,被覆盖
cv :: Point&pt2 //行的第二个端点,被覆盖
); bool clipLine(//如果图像大小为行的任何部分,则为True
cv :: Size imgSize,//图像大小,表示矩形为0,0
cv :: Point&pt1,//行的第一个端点,被覆盖
cv :: Point&pt2 //行的第二个端点,被覆盖
);
此函数用于确定两点pt1和pt2指定的线是否位于矩形边界内。
在第一个版本中,提供了一个cv::rect,并将该行与该矩形进行比较。
cv::clipline()仅当行完全在指定矩形区域之外时才会返回false。
第二个版本是相同的,只是它采用了cv::size参数。
调用第二个版本相当于使用一个矩形(x,y)位置为(0,0)调用第一个版本。 ——————————————————————————————————————————————————————————————————————————————
cv::ellipse() | 画一个椭圆,可以是倾斜的或椭圆弧的
|——用法:
bool ellipse(
cv :: Mat&img,//要绘制的图像
cv ::Point center,//椭圆中心的位置
cv ::Size axes,//长轴和短轴的长度
double angle,//长轴倾斜角度
double startAngle,//弧形绘制的起始角度
double endAngle,//弧形绘制的结束角度
const cv ::Scalar& color,//颜色,BGR形式
int thickness = 1,//线的粗细
int lineType = 8,// Connectedness,4或8
int shift = 0 //作为分数处理的半径位
); bool ellipse(
cv :: Mat&img,//要绘制的图像
const cv :: RotatedRect&rect,//旋转矩形边界椭圆
const cv ::Scalar& color,//颜色,BGR形式
int thickness = 1,//线的粗细
int lineType = 8,// Connectedness,4或8
int shift = 0 //作为分数处理的半径位
);
cv::Ellipse()函数与cv::Circle()函数非常相似,
主要区别在于轴参数,其类型为cv::Size。
在这种情况下,height和width参数表示椭圆长轴和短轴的长度。
角度是长轴的角度(以度为单位),从水平(即从x轴)逆时针测量。
同样,start angle和endangle指示(也以度为单位)圆弧的开始和结束角度。
因此,对于完整的椭圆,必须分别将这些值设置为0和360。 指定椭圆图形的另一种方法是使用边界框。
在这种情况下,cv::rotatedrect类型的参数框完全指定椭圆的大小和方向。
——————————————————————————————————————————————————————————————————————————————
cv::ellipse2Poly() | 计算椭圆弧的多边形近似
|——用法:
void ellipse2Poly(
cv ::Point center,//椭圆中心的位置
cv ::Size axes,//长轴和短轴的长度
double angle,//长轴倾斜角度
double startAngle,//弧形绘制的起始角度
double endAngle,//弧形绘制的结束角度
int delta,//连续顶点之间的角度
vector <cv :: Point>&pts //结果,STL-点向量
);
cv::ellipse2poly()函数在cv::ellipse()内部用于计算椭圆弧,但您也可以自己调用它。
给定有关椭圆弧(中心、轴、角度、开始角度和结束角度-均如cv::Ellipse()中定义)
和参数delta(指定要采样的后续点之间的角度)的信息,
cv::Ellipse2Poly()计算形成多边形a的点序列与指定的椭圆弧近似。
计算的点返回到向量<>pts中。 ——————————————————————————————————————————————————————————————————————————————
cv::fillConvexPoly() | 绘制简单多边形的填充版本
|——用法:
void fillConvexPoly(
cv::Mat& img , //要绘制的图像
const cv::Point* pts , /// C风格的点数组
int npts , //'pts'中的点数
const cv::Scalar& color , //颜色,BGR形式
int lineType = 8 , // Connectedness,4或8
int shift = 0 //作为分数处理的半径位
)
此函数绘制一个填充多边形。它比cv::fillpy()快得多,因为它使用的算法要简单得多。
但是,如果传递给它的多边形具有自交集,则cv::FillConverxpoly()使用的算法将无法正常工作。
PTS中的点被视为连续的,并且PTS中的最后一点和第一点之间的一段是隐含的(即假定多边形是闭合的)。
——————————————————————————————————————————————————————————————————————————————
cv::fillPoly() | 绘制任意多边形的填充版本
|——用法:
void fillPoly(
cv :: Mat&img, //要绘制的图像
const cv :: Point * pts, // C样式的点数组数组
int npts, //'pts [i]'中的点数
int ncontours, //'pts'中的数组数
const cv ::Scalar& color, //颜色,BGR形式
int lineType = 8, // Connectedness,4或8
int shift = 0, //作为分数处理的半径位
cv :: Point offset = Point() //应用于所有点的均匀偏移量
);
此函数绘制任意数量的填充多边形。cv::fillConvexPoly() 与之不同,它可以处理具有自交叉的多边形。
所述ncontours 参数指定不同多边形轮廓有多少会,并且npts 参数是一个C数组,
指示多少个点有在每个轮廓(即,npts[i] 表示有多少点有在多边形i )。
pts 是包含这些多边形中所有点的C样式数组的C样式数组
(即,pts[i][j]包含第多个多边形j中的i第th个点)。
cv::fillPoly() 还有一个附加参数,offset 它是一个像素偏移量,在绘制多边形时将应用于所有顶点位置。
假设多边形是闭合的(即,从最后一个元素开始的一个分段)pts[i][] 将假设第一个元素)。
——————————————————————————————————————————————————————————————————————————————
cv::line() | 画一条简单的线
|——用法:
line(
cv :: Mat&img, //要绘制的图像
cv :: Point pt1, //行的第一个端点
cv :: Point pt2 //行的第二个端点
const cv ::Scalar& color, //颜色,BGR形式
int lineType = 8, // Connectedness,4或8
int shift = 0 //作为分数处理的半径位
);
函数cv::line()在图像img中绘制一条从pt1到pt2的直线。线条被图像边界自动裁剪。
——————————————————————————————————————————————————————————————————————————————
cv::rectangle() | 画一个简单的线
|——用法:
void rectangle(
cv :: Mat&img, //要绘制的图像
cv :: Point pt1, //矩形的第一个角
cv :: Point pt2 //矩形的对角
const cv ::Scalar& color, //颜色,BGR形式
int lineType = 8, // Connectedness,4或8
int shift = 0 //作为分数处理的半径位
); void rectangle(
cv :: Mat&img, //要绘制的图像
cv :: Rect r, //要绘制的矩形
const cv ::Scalar& color, //颜色,BGR形式
int lineType = 8, // Connectedness,4或8
int shift = 0 //作为分数处理的半径位
);
函数的作用是:在图像img中绘制一个角为pt1到pt2的矩形。
此函数的另一种形式允许由单个cv::rect参数r指定矩形的位置和大小。 ——————————————————————————————————————————————————————————————————————————————
cv::polyLines() | 绘制多条多边形曲线
|——用法:
void polyLines(
cv :: Mat&img, //要绘制的图像
const cv :: Point * pts, // C样式的点数组数组
int npts, //'pts [i]'中的点数
int ncontours, //'pts'中的数组数
bool isClosed, //如果为true,则连接last和first pts
const cv ::Scalar& color, //颜色,BGR形式
int lineType = 8, // Connectedness,4或8
int shift = 0 //作为分数处理的半径位
);
此函数绘制任意数量的未填充多边形。它可以处理一般多边形,包括具有自交叉的多边形。
所述ncontours 参数指定不同多边形轮廓有多少会,并且npts 参数是一个C数组,
指示多少个点有在每个轮廓(即,npts[i] 表示有多少点有在多边形i )。
pts 是包含这些多边形中所有点的C样式数组的C样式数组
(即,pts[i][j]包含第多个多边形j中的i第th个点)。不假设多边形是封闭的。
如果参数isClosed 是true ,那么pts[i][] 将假定从最后一个元素到第一个元素的一个段。
否则,轮廓被视为一个开放的轮廓,仅包含npts[i]-1 在轮廓之间的区段npts[i]列出的点数。
——————————————————————————————————————————————————————————————————————————————
cv::LineIterator() |
|——用法:
LineIterator()::LineIterator(
cv::Mat& img , //要绘制的图像
cv::Point pt1 , //行的第一个端点
cv::Point pt2 , //行的第二个端点
int lineType = 8 , //Connectedness,4或8
bool leftToRight = false //如果为true,则始终在左侧开始
)
cv::lineIterator对象是一个迭代器,用于按顺序获取光栅线的每个像素。
行迭代器是opencv中函数的第一个示例。我们将在下一章中看到更多这些“做事情的对象”。
行迭代器的构造函数接受行的两个端点,以及一个行类型说明符和一个附加的布尔值,该值指示行应该遍历的方向。 初始化后,行中的像素数存储在成员整数cv::lineIterator::count中。
重载的取消引用运算符cv::lineIterator::operator*()返回类型为uchar*的指针,
该指针指向“当前”像素。当前像素从行的一端开始,
并通过重载的递增运算符cv::lineIterator::operator++()递增。
实际的遍历是根据前面提到的Bresenham算法完成的。 [注意]
重载解除引用运算符的样式cv::LineIterator::operator*()与STL等库可能习惯的样式略有不同。
不同之处在于迭代器的返回值本身就是一个指针,因此迭代器的行为不像指针,而是指向指针的指针。
—————————————————————————————————————————————————————————————————————————————— 【【字体和文字】】
另一种绘图形式是绘制文本。
——————————————————————————————————————————————————————————————————————————————
功能 | 描述
cv::putText() | 在图像中绘制指定的文本
|——用法:
void cv::putText(
cv::Mat& img, //要绘制的图像
const string& text , //要写这个(通常来自cv::format)
int fontFace , //Font(例如,cv::FONT_HERSHEY_PLAIN)
double fontScale , //size(乘数,不是"points"")
cv::Scalar& color , //颜色,RGB
int thickness = 1 , //线的粗细
int lineType = 8 , //Connectedness,4或8
bool bottomLeftOrigin = false //true = "左下角的原点"
)
这个函数是OpenCV的一个主要文本绘图程序; 它只是将一些文本抛到图像上。
指示的文本text 打印时,文本框的左上角位于origin 和指示的颜色color,
除非bottomLeftOrigin 标志是true,在这种情况下,文本框的左下角位于origin 。
使用的字体由fontFace 参数选择,其中可以是任何一个列于下表的字体。
可用的字体(都是Hershey的变体) 识别码 描述
——————————————————————————————————————————————————————————————————————————
cv::FONT_HERSHEY_SIMPLEX 正常尺寸sans-serif
cv::FONT_HERSHEY_PLAIN 小尺寸无衬线
cv::FONT_HERSHEY_DUPLEX 正常尺寸sans-serif; 比...更复杂cv::FONT_HERSHEY_SIMPLEX
cv::FONT_HERSHEY_COMPLEX 正常大小的衬线; 比...更复杂cv::FONT_HERSHEY_DUPLEX
cv::FONT_HERSHEY_TRIPLEX 正常大小的衬线; 比...更复杂cv::FONT_HERSHEY_COMPLEX
cv::FONT_HERSHEY_COMPLEX_SMALL 较小的版本 cv::FONT_HERSHEY_COMPLEX
cv::FONT_HERSHEY_SCRIPT_SIMPLEX 手写风格
cv::FONT_HERSHEY_SCRIPT_COMPLEX 更复杂的变种 cv::FONT_HERSHEY_SCRIPT_SIMPLEX
——————————————————————————————————————————————————————————————————————————
列出的任何字体名称 也可以组合(通过OR运算符)以cv::FONT_HERSHEY_ITALIC 斜体显示指示的字体。
每种字体都有“自然”大小。如果fontScale 不是1.0,则在绘制文本之前,通过此数字缩放字体大小。 ——————————————————————————————————————————————————————————————————————————————
cv::getTextSize() | 确定文本字符串的宽度和高度
|——用法:
cv::Size::getTextSize(
const string& text ,
cv::Point origin ,
int fontFace ,
double fontScale ,
int thickness ,
int* baseLine
) ;
cv::gettextsize()函数回答了这样一个问题:
如果不在图像上绘制文本(使用一些参数集),那么某些文本会有多大。
cv::gettextsize()唯一新颖的参数是baseline,它实际上是一个输出参数。
基线是文本基线相对于文本最低点的Y坐标
——————————————————————————————————————————————————————————————————————————————
参考书籍:<学习opencv>
<学习opencv>绘画和注释的更多相关文章
- [opencv]<学习Opencv>英文原版翻译学习
[注]下文全部内容为 <<Learning OpenCV 3: Computer Vision in C++ with the OpenCV Library>>经由在线翻译整理 ...
- 《学习OpenCV》练习题第四章第八题ab
这道题是利用OpenCV例子程序里自带的人脸检测程序,做点图像的复制操作以及alpha融合. 说明:人脸检测的程序我参照了网上现有的例子程序,没有用我用的OpenCV版本(2.4.5)的facedet ...
- 学习opencv中文版教程——第二章
学习opencv中文版教程——第二章 所有案例,跑起来~~~然而并没有都跑起来...我只把我能跑的都尽量跑了,毕竟看书还是很生硬,能运行能出结果,才比较好. 越着急,心越慌,越是着急,越要慢,越是陌生 ...
- 学习opencv之路(一)
先看一下<学习opencv> 找几个demo 学会相机标定 我做的是单目相机的标定.
- [纯小白学习OpenCV系列]官方例程00:世界观与方法论
2015-11-11 ----------------------------------------------------------------------------------- 其实,写博 ...
- 《学习OpenCV》中求给定点位置公式
假设有10个三维的点,使用数组存放它们有四种常见的形式: ①一个二维数组,数组的类型是CV32FC1,有n行,3列(n×3) ②类似①,也可以用一个3行n列(3×n)的二维数组 ③④用一个n行1列(n ...
- 对人脑处理视觉的描述(摘《学习OpenCV(中文版)》)
人脑将视觉信号划分入很多个通道,将各种不同的信息输入你的大脑.你的大脑有一个关注系统,会根据任务识别出图像的重要部分,并做重点分析,而其他部分则分析得较少 .在人类视觉流中存在大量的反馈,但是目前我们 ...
- 《学习OpenCV》练习题第五章第二题abc
代码: #include <stdio.h> #include <opencv/highgui.h> #include <opencv/cv.h> #include ...
- 《学习OpenCV》练习题第五章第一题ab
这道题是载入一幅带有有趣纹理的图像并用不同的模板(窗口,核)大小做高斯模糊(高斯平滑),然后比较用5*5大小的窗口平滑图像两次和用11*11大小的窗口平滑图像一次是否接近相同. 先说下我的做法,a部分 ...
随机推荐
- applogs流量数据项目学习
一. 项目介绍 项目的功能主要是面向App开发商提供App使用情况的统计服务 主要是基于用户启动app的统计分析,app只要启动就会上报一条日志记录 (启动日志),当然也会有其他的日志比如说页面访问日 ...
- celery开启worker报错django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE o
其实挺简单的问题,但花了自己一个下午来解决,先是浏览各种博客,无果:没办法,然后去看celery官方文档,无果,近乎绝望,最后仔细看代码,找到问题所在(如下),自学狗这效率...... 下面是自己ta ...
- Linux 设置时区
一.查看和修改Linux的时区 1. 查看当前时区命令 : "date -R" 2. 修改设置Linux服务器时区方法 A命令 : "tzselect" 方法 ...
- tomcat结合nginx
相信很多人都听过nginx,这个小巧的东西慢慢地在吞食apache和IIS的份额.那究竟它有什么作用呢?可能很多人未必了解. 说到反向代理,可能很多人都听说,但具体什么是反向代理,很多人估计就不清楚了 ...
- 记一次 .NET 某妇产医院 WPF内存溢出分析
一:背景 1. 讲故事 上个月有位朋友通过博客园的短消息找到我,说他的程序存在内存溢出情况,寻求如何解决. 要解决还得通过 windbg 分析啦. 二:Windbg 分析 1. 为什么会内存溢出 大家 ...
- 1、Linux下安装JDK
1.Linux下安装JDK 1 权限设置(可忽略) 1.1 安装过程与Windows安装过程相差不多,下载解压安装 1.切换root用户( 如果当前登录的用户权限够的话,请忽略这步) 由于创建目录的位 ...
- 资源分配(Project)
<Project2016 企业项目管理实践>张会斌 董方好 编著 资源设置好以后,不能光摆着看,分配到各任务中去才是正道. 分配资源就需要回到与任务相关的视图了,比如[任务工作表]视图或者 ...
- 【紧急】Log4j又发新版2.17.0,只有彻底搞懂漏洞原因,才能以不变应万变,小白也能看懂
1 事件背景 经过一周时间的Log4j2 RCE事件的发酵,事情也变也越来越复杂和有趣,就连 Log4j 官方紧急发布了 2.15.0 版本之后没有过多久,又发声明说 2.15.0 版本也没有完全解决 ...
- SpringCloud微服务实战——搭建企业级开发框架(三十四):SpringCloud + Docker + k8s实现微服务集群打包部署-Maven打包配置
SpringCloud微服务包含多个SpringBoot可运行的应用程序,在单应用程序下,版本发布时的打包部署还相对简单,当有多个应用程序的微服务发布部署时,原先的单应用程序部署方式就会显得复杂且 ...
- 背水一战——CSP2021/NOIP2021 游记
洛谷 version 转载本文章的其他链接: 1(S00021 提供) 2(Ew_Cors 提供) \[\texttt{2021.9.10} \] 终于开坑了. 笑死,初赛根本还没开始复习,反正初赛也 ...