OpenCV:七、绘制图形与文字

前言

在上一章中描述了图像亮度与对比度的调整,详细描述可点击查看(https://www.jianshu.com/writer#/notebooks/47386368/notes/76843898)

目标

本章中,将学习如何:

  • cv::Point与cv::Scalar的使用
  • 绘制线、矩形、圆、椭圆等基本几何形状
  • 随机生成与绘制文本

重要绘图元素介绍

  1. cv::Point
    Point表示平面上一个点(x,y);其中x,y都是整数,OpenCV关于Point的定义如下:
typedef Point_<int> Point2i;
typedef Point_<int64> Point2l;
typedef Point_<float> Point2f;
typedef Point_<double> Point2d;
typedef Point2i Point;

其中Point_是一个模板类(如果需要多个函数具有相同的解决问题的逻辑,只是它们所使用的形参的类型不同,则可以使用函数模板。同样,如果需要得多个类仅在其某些数据成员的类型方面有所不同,或者仅在其成员函数的形参类型方面有所不同,则都可以使用类模板)。常用的类型还有Point2f、Point3f;2f-二位坐标,坐标的类型为float。3f同理。

  1. cv::Scalar
    Scalar表示一个四元向量,在OpenCV中通常使用其前三个向量表示颜色。Scalar在OpenCV中定义如下:
Scalar(a,b,c);  // a = blue,b = green, c = red表示RGB三个通道
typedef Scalar_<double> Scalar;

图像绘制

  • 画线cv::line(LINE_4\LINE_8\LINE_AA)
    函数原型: void line(InputOutArray img, Point pt1, Pint pt2, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0);
Mat src, dst;
void myLines();

int main()
{
        src = imread("../lena512color.tiff");
    if (!src.data) {
        printf("could not load image...\n");
        return -1;
    }
    char input_win[] = "input image";
    //cvtColor(src, src, COLOR_BGR2GRAY);
    namedWindow(input_win, WINDOW_AUTOSIZE);
    imshow(input_win, src);
    dst = src.clone();
    myLines();
    char output_title[] = "demo";
    namedWindow(output_title, WINDOW_AUTOSIZE);
    imshow(output_title, dst);
        waitKey(0);
    return 0;
}

void myLines()
{
    Point p1 = Point(20, 30);
    Point p2;
    p2.x = 300;
    p2.y = 300;
    Scalar color = Scalar(0, 0, 255);
    line(dst, p1, p2, color, 1, LINE_8);
}
绘制直线.png

函数说明:
1.在图像上绘制一条pt1到pt2的直线,img一般是Mat类型。
2.thickness-表示绘制的线的宽度。
3.lineType-表示线形。OpenCV中有三种可以选择LINE_4、LINE_8、lINE_AA。其中LINE_4表示采用4邻接的方式绘制,LINE_8表示采用8邻接的方式绘制,LINE_AA表示高斯滤波抗锯齿。
4.-表示坐标中的小数点位数。

  • 画矩形cv::rectangle
    函数原型: void rectangle(InputOutputArray img, Rect rec,const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0);
void myRectangle()
{
    Rect rect = Rect(20, 30, 200, 200);
    Scalar color = Scalar(255,0,0);
    rectangle(dst, rect, color, 8, LINE_8);
}
绘制矩形.png
  • 画椭圆cv::elipseh
    函数原型:void ellipse(InputOutputArray img, Point center, Size axes,double angle, double startAngle, double endAngle,const Scalar& color, int thickness = 1,int lineType = LINE_8, int shift = 0);
void myEllipse()
{
    Scalar color = Scalar(0, 255, 0);
    ellipse(dst, Point(dst.cols / 2, dst.rows / 2), Size(dst.cols / 4, dst.rows / 8), 90, 0, 180, color, 8, LINE_8);
}
绘制椭圆.png

函数说明:
1.axes-表示椭圆长轴和短轴长度的一半。
2.angle、startAngle、endAngle-分别表示椭圆旋转的角度,圆弧开始的角度和圆弧结束的角度
3.thickness-表示线宽,如果取-1表示绘制填充图形

  • 画圆cv::circle
    函数原型:void circle(InputOutputArray img, Point center, int radius,const Scalar& color, int thickness = 1,int lineType = LINE_8,int shift = 0);
void myCircle()
{
    Scalar color = Scalar(0, 255, 255);
    circle(dst, Point(dst.cols / 2, dst.rows / 2), 100, color, 8);
}
绘制圆.png

函数说明:center-表示圆心。radius-表示半径。

  • 画填充cv::fillPoly
    函数原型: void fillPoly(InputOutputArray img, const Point** pts,const int* npts, int ncontours, const Scalar& color, int lineType =LINE_8, int shift = 0,Point offset = Point() );
void muPolygon()
{
    Point pts[1][5];
    pts[0][0] = Point(100, 100);
    pts[0][1] = Point(100, 200);
    pts[0][2] = Point(200, 200);
    pts[0][3] = Point(200, 100);
    pts[0][4] = Point(100, 100);
    const Point* ppts[] = { pts[0] };
    int npt[] = { 5 };
    Scalar color = Scalar(255, 12, 255);
    fillPoly(dst, ppts, npt, 1, color, LINE_8);
}
绘制Polygon.png

函数说明:
1.pts-绘制多边形的各个点。
2.npts-绘制多边形点的数目。
3.ncontour-绘制的多边形的数量。
4.offset-轮廓所有点的可选偏移量。

  • 文字绘制cv::putText
    函数原型:void putText( InputOutputArray img, const String& text, Point org, int fontFace, double fontScale, Scalar color, int thickness = 1, int lineType = LINE_8,bool bottomLeftOrigin = false );
putText(dst, "Hello OpenCV", Point(dst.cols / 2, dst.rows / 2), FONT_HERSHEY_COMPLEX, 1, Scalar(18, 26, 189), 5);
绘制文字.png

函数说明:
1.org-字体所在矩形的起始点,左下角。
2.fontFace-字体类型。
3.fontScale-字体比例因子。比例因子*字体类型基本大小=字体大小
4.bottomLeftOrigin-如果为true,则图像数据原点位于左下角。 否则,它位于左上角。

  • 随机线绘制
//绘制随机直线
void myrng() {
    RNG rng(12345);//生成高斯随机函数
    Point p1;
    Point p2;
    Mat RNGimage(500, 500, CV_8UC3, Scalar(0, 0, 0));
    for (int i = 0; i<10; i++) {
        p1.x = rng.uniform(0, RNGimage.cols);//生成任意x坐标
        p2.x = rng.uniform(0, RNGimage.cols);
        p1.y = rng.uniform(0, RNGimage.rows);//生成任意y坐标
        p2.y = rng.uniform(0, RNGimage.rows);
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));//随机生成颜色
        line(RNGimage, p1, p2, color, 1, LINE_8);//画直线
    }
    namedWindow("绘制随机直线");
    imshow("绘制随机直线", RNGimage);
    waitKey(0);
}
随机线绘制.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342