/*=========================================================================*/
// 绘画 和 注释
/*=========================================================================*/
我们经常想画一些图片,或者在从其他地方获得的图像上画一些东西。
为了达到这个目的,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::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>
手机扫一扫
移动阅读更方便
你可能感兴趣的文章