前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【OpenCV入门之十五】随心所欲绘制想要形状

【OpenCV入门之十五】随心所欲绘制想要形状

作者头像
小白学视觉
发布2019-05-30 19:25:58
1.7K0
发布2019-05-30 19:25:58
举报

绘制点和圆

代码语言:javascript
复制
void cvCircle( CvArr* img, CvPoint center, int radius, CvScalar color,int thickness=1, int line_type=8, int shift=0 );
  • img:图像。
  • center:圆心坐标。
  • radius:圆形的半径。
  • color:线条的颜色。
  • thickness:如果是正数,表示组成圆的线条的粗细程度。否则,表示圆是否被填充。
  • line_type:线条的类型。见 cvLine 的描述
  • shift:圆心坐标点和半径值的小数点位数。

画圆画点都是使用circle()函数来画,点就是圆,我们平常所说的圆只不过是半径大一点而已。

代码语言:javascript
复制
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

//画圆画点都是使用circle()函数来画,点就是圆,我们平常所说的圆只不过是半径大一点而已。
int main()
{
    Mat img = imread("lol16.jpg");  

    //画空心点
    Point p(20, 20);//初始化点坐标为(20,20)
    circle(img, p, 2, Scalar(0, 255, 0)); //第三个参数表示点的半径,第四个参数选择颜色。这样子我们就画出了绿色的空心点

    //这种初始化点的方式也可以
    Point p2;
    p2.x = 100;
    p2.y = 100;
    //画实心点
    circle(img, p2, 3,Scalar(255,0,0),-1); //第五个参数我设为-1,表明这是个实点。

    //画空心圆
    Point p3(300, 300);
    circle(img,p3,100,Scalar(0,0,255),3);//第五个参数我们调高点,让线更粗

    //画实心圆
    Point p4;
    p4.x = 600;
    p4.y = 600;
    circle(img, p4, 100, Scalar(120, 120, 120), - 1);

    imshow("画点画圆", img);

    waitKey();
    return 0;
}

绘制椭圆

代码语言:javascript
复制
void ellipse(Mat& img, Point center,Size axes, double angle, double startAngle, double endAngle, const Scalar& color,int thickness=1, int lineType=8, int shift=0)
  • img:图像。
  • center:椭圆圆心坐标。
  • axes:轴的长度。
  • angle:偏转的角度。
  • start_angle:圆弧起始角的角度。
  • end_angle:圆弧终结角的角度。
  • color:线条的颜色。
  • thickness:线条的粗细程度。
  • line_type:线条的类型,见CVLINE的描述。
  • shift:圆心坐标点和数轴的精度。 #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main() { Mat img = imread("lol16.jpg"); int thickness = 3; int lineType = 8; double angle = 30; //椭圆旋转角度 //第三个参数Size中的两个参数分别是横轴长、纵轴长。 //同理,thickness若是小于0,表示实心 ellipse(img,Point(100, 100),Size(90, 60),angle,0,360,Scalar(255, 255, 0),thickness,lineType); imshow("画椭圆", img); waitKey(); return 0; }

绘制矩形

代码语言:javascript
复制
void rectangle(Mat& img,Rect rec, const Scalar&color, intthickness=1, intlineType=8,intshift=0 )
  • img:图像。
  • rec:表征矩形的位置和长宽。
  • color:线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。
  • thickness:组成矩形的线条的粗细程度。取负值时(如CV_FILLED)函数绘制填充了色彩的矩形。
  • line_type:线条的类型。见cvLine的描述
  • shift:坐标点的小数点位数。 #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace std; using namespace cv; int main() { Mat img = imread("lol16.jpg"); Rect r(250, 250, 120, 200); rectangle(img, r, Scalar(0, 255, 255), 3); imshow("画矩形", img); waitKey(); return 0; }

绘制直线

代码语言:javascript
复制
void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,int thickness = 1, int lineType = LINE_8, int shift = 0);
  • img:图像.
  • pt1:线条起点.
  • pt2:线条终点.
  • color:线条颜色.
  • thickness:线条宽度.
  • lineType:线型
代码语言:javascript
复制
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

int main()
{
    Mat img = imread("lol16.jpg");  
    Point p1(100, 100);
    Point p2(758, 50);
    line(img, p1, p2, Scalar(33, 33, 133), 2);

    //画第二条线
    line(img, Point(300, 300), Point(758, 300), Scalar(89, 90, 90), 3);

    imshow("画矩形", img);

    waitKey();
    return 0;
}

输出文字

代码语言:javascript
复制
void cv::putText(cv::Mat& img, const string& text,cv::Point origin,   int fontFace,double fontScale,  cv::Scalar color,int thickness = 1,int lineType = 8, bool bottomLeftOrigin = false );
  • img:待绘制的图像
  • text:待绘制的文字
  • origin:文本框的左下角
  • fontFace:字体 (如cv::FONT_HERSHEY_PLAIN)
  • fontScale:尺寸因子,值越大文字越大
  • color:线条的颜色(RGB)
  • thickness:线条宽度
  • lineType:线型(4邻域或8邻域,默认8邻域)
  • bottomLeftOrigin:true='origin at lower left'

最后给出一个完整的程序

代码语言:javascript
复制
#include<opencv2/opencv.hpp>
#include<iostream>

using namespace std;
using namespace cv;

Mat src;
void drawLines();
void drawRectangle();
void drawEllipse();
void drawCircle();
void drawPolygon();
void drawRandomLine();
void drawText();

int main(int argc,char** argv){
  //创建空白图用于绘制图形
  src=Mat::zeros(Size(500,500),CV_8UC3);
  //设置蓝色背景
  src.setTo(cv::Scalar(100, 0, 0));

  //调用函数
  drawLines();
  drawRectangle();
  drawEllipse();
  drawCircle();
  drawPolygon();
  drawText();
  drawRandomLine();

  imshow("input Image",src);

  waitKey(0);
  return 0;
}

void drawLines(){//绘制线条
  Point p1 = Point(20,30);//Point表示平面上的点,OpenCV中的这些坐标值都是相对于图像本身像素值的
  Point p2;
  p2.x = 300;
  p2.y = 300;
  Scalar color = Scalar(0,0,255);
  line(src, p1, p2, color, 1, LINE_AA);//绘制线条到Mat,1是线宽、LINE_4或LINE_8是带锯齿的,LINE_AA是抗锯齿的
}


void drawRectangle(){//绘制矩形
  //OpenCV的坐标系,原点在屏幕左上角,x朝右正,y朝下正
  Rect rect = Rect(200, 100, 200, 250);//起始位置x、y,宽,高
  Scalar color = Scalar(255, 0, 0);
  rectangle(src, rect, color, 2, LINE_8);//绘制矩形到Mat,自带圆角
}


void drawEllipse(){//绘制椭圆
  Scalar color = Scalar(0, 255, 0);
  //绘制椭圆,参数:Mat,中心点,椭圆的长短轴半径,椭圆的朝向(0表示水平),起始角度,终点角度
  ellipse(src, Point(src.cols/2,src.rows/2), Size(src.cols/8,src.rows/4), 90, 0, 360, color, 1, LINE_8);
}


void drawCircle(){//绘制圆
  Scalar color = Scalar(0, 255, 255);
  circle(src, Point(src.cols / 2, src.rows / 2), 150, color, 2, LINE_8);
}


void drawPolygon(){//绘制多边形,绘制的多边形是填充的
  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, 0, 255);
    //参数:Mat,顶点数据指针,顶点个数,1表示只绘制一个contour(轮廓)
    fillPoly(src, ppts, npt, 1, color, LINE_8);
}

void drawText(){
  //设置绘制文本的相关参数
  std::string text = "Hello OpenCV!";
  int font_face = cv::FONT_HERSHEY_COMPLEX; 
  double font_scale = 2;
  int thickness = 2;
  int baseline;
  //获取文本框的长宽
  cv::Size text_size = cv::getTextSize(text, font_face, font_scale, thickness, &baseline);
 
  //将文本框居中绘制
  Point origin; 
  origin.x = src.cols / 2 - text_size.width / 2;
  origin.y = src.rows / 2 + text_size.height / 2;
  putText(src, text, origin, font_face, font_scale, cv::Scalar(0, 255, 255), thickness, 8, 0);
 
  //参数:Mat,文字(不识别中文?),文字的位置(锚点?),字体,缩放,颜色,线宽,线类型
    //putText(src, "Hello OpenCV", Point(0, 200), CV_FONT_HERSHEY_COMPLEX, 1.0, Scalar(0), 3, LINE_8);//绘制文字

  //显示绘制解果
  //cv::imshow("image", src);
}


void drawRandomLine()//循环绘制随机位置随机颜色的线段
{
    Mat randomLineMat = Mat::zeros(src.size(), src.type());
    RNG rng(12345);//生成高斯随机数,参数种子
    Point p1, p2;
    for (int i = 0; i < 100000; i++)
    {
        p1.x = rng.uniform(0, randomLineMat.cols);//生成正态分布 0-bgImage.cols 范围内的随机数
        p1.y = rng.uniform(0, randomLineMat.rows);
        p2.x = rng.uniform(0, randomLineMat.cols);
        p2.y = rng.uniform(0, randomLineMat.rows);
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        if (waitKey(50) > 0)//参数delay如果传0表示阻塞等待键盘事件,传大于0表示只阻塞等待delay毫秒,键盘无响应返回-1
        {
            break;
        }
        line(randomLineMat, p1, p2, color, 1, LINE_8);
        imshow("randomLine", randomLineMat);
    }
}

运行结果

主要借鉴”Madcola“和”Micheal超“两位大神的文章。两位大神的博客主页是: https://www.cnblogs.com/skyfsm/(Madcola) https://blog.csdn.net/qq_42887760(Micheal超)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小白学视觉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档