您的位置:首页 > 编程语言 > C语言/C++

Opencv3中画图功能详解(C++实现,python说明)

2017-02-17 15:42 4199 查看
之前每次用opencv作图都要去搜下指定功能,遂在这里对照着官网说明整理下,方便之后调用。

一开始看的是python版的,所幸就翻译了下粘过来了,后面是Python版的。

C++版

Opencv提供的C++画图功能还是满强大,写的一个小Demo如下:
包括了箭头,圆,直线的截取,标记,两种椭圆,多边形及填充,文字,以及透明填充。



完整可运行C++程序如下:

#include<opencv2/opencv.hpp>
#define 作者 "朱铭德"
#define 地址 "blog.csdn.net/zmdsjtu"
using namespace cv;
using namespace std;

void DrawTransRec(Mat mat, int x, int y, int width, int height, CvScalar color, double alpha);

int main() {
system("color 9F");//修改编译器的颜色,233

//新建一个白画布
Mat picture(500, 500, CV_8UC3, Scalar(255, 255, 255,0.5));

//-----------画箭头-----------------

//新建一个点的类型
Point point1 = Point(0, 0);
Point point2 = Point(100, 100);//第一位是→方向,第二位是↓方向
arrowedLine(picture, point1, point2, Scalar(0, 255, 0), 2);

//------------画圆------------------
int r = 50;//半径
Point center = Point(150, 50);
circle(picture, center, r, Scalar(123, 21, 32), -1);//-1为填充

//clipLine的作用是剪切图像矩形区域内部的直线,line()用来画线段
//并判断一个直线是否部分在一个rect里
Rect 矩形1 = Rect(200, 0, 100, 100);//Rect类,前两个为坐标,后面是长和宽
//Rect 矩形(0, 0, 5, 5);  这种命名也是一样的
Point &point3 = Point(200, 0);
Point &point4 = Point(400, 100);
cout<<clipLine(矩形1, point3, point4);//返回的是一个bool值
line(picture, point3, point4, Scalar(144, 144, 144));
putText(picture, "clipLine", Point(210, 50), 1, 1, Scalar(0, 111, 255));

//DrawConters()函数主要用来画轮廓线
//详细介绍地址://http://m.blog.csdn.net/article/details?id=47982167
putText(picture, "DrawConters", Point(300, 50), 1, 1, Scalar(255, 0, 255));

//drawMarker()做标记
drawMarker(picture, Point(450, 50), Scalar(0, 0, 255));

//ellipse()画椭圆的两种方法
Size 轴(20,50);//轴线长度,横着20,竖着50
ellipse(picture,Point(50, 150),轴,20.0,0.0,300.0,  Scalar(55, 123, 222),-1);
//参数说明,axes表示轴,20.0表示整个椭圆旋转20度,从0开始画到300度
//重载函数利用了RotatedRect,表示在一个旋转矩形里画最大椭圆
RotatedRect box1(Point(150,150),Size(40,100),-20);//负的为逆时针
ellipse(picture, box1, Scalar(122, 122, 122));

//函数ellipse2Poly计算近似指定椭圆弧的折线的顶点。

//getTextSize()返回一个指定字体以及大小的String所占的空间
//rectangle()画一个矩形
String text = "Happy 88 Days";
int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
/*
FONT_HERSHEY_SIMPLEX        = 0, //!< normal size sans-serif font
FONT_HERSHEY_PLAIN          = 1, //!< small size sans-serif font
FONT_HERSHEY_DUPLEX         = 2, //!< normal size sans-serif font (more complex than FONT_HERSHEY_SIMPLEX)
FONT_HERSHEY_COMPLEX        = 3, //!< normal size serif font
FONT_HERSHEY_TRIPLEX        = 4, //!< normal size serif font (more complex than FONT_HERSHEY_COMPLEX)
FONT_HERSHEY_COMPLEX_SMALL  = 5, //!< smaller version of FONT_HERSHEY_COMPLEX
FONT_HERSHEY_SCRIPT_SIMPLEX = 6, //!< hand-writing style font
FONT_HERSHEY_SCRIPT_COMPLEX = 7, //!< more complex variant of FONT_HERSHEY_SCRIPT_SIMPLEX
FONT_ITALIC                 = 16 //!< flag for italic font
*/
double fontScale = 1.5;
int thickness = 2;
int baseline = 0;
Size textSize = getTextSize(text, fontFace,
fontScale, thickness, &baseline);
baseline += thickness;
// center the text
Point textOrg((picture.cols - textSize.width) / 2,
(picture.rows + textSize.height) / 2);
// draw the box
rectangle(picture, textOrg + Point(0, baseline),
textOrg + Point(textSize.width, -textSize.height),
Scalar(0, 0, 255,1));
// ... and the baseline first
line(picture, textOrg + Point(0, thickness),
textOrg + Point(textSize.width, thickness),
Scalar(0, 0, 255));
// then put the text itself
putText(picture, text, textOrg, fontFace, fontScale,
Scalar::all(120), thickness, 8);

//画多边形并填充
Point points[1][20];
points[0][0] = Point(100, 100) + Point(200, 0);
points[0][1] = Point(200, 100) + Point(200, 0);
points[0][2] = Point(250, 200) + Point(200, 0);
points[0][3] = Point(50, 200) + Point(200, 0);
const Point* pt[1] = { points[0] };
int npt[1] = { 4 };
polylines(picture, pt, npt, 1, 1, Scalar(0, 0,255),3);
fillPoly(picture, pt, npt, 1, Scalar(250, 255, 0),8 );
putText(picture, "  polylines()", Point(300, 120), 1.5, 1, Scalar::all(0));
putText(picture, "  fillPoly()", Point(300, 160), 1.5, 1, Scalar::all(0));

putText(picture, "transparent", Point(150, 380),2, 1, Scalar::all(0));

DrawTransRec(picture, 50, 320, 400, 100, Scalar(255, 122, 122), 0.2);

//显示部分
imshow("Drawing Function", picture);
waitKey(-1);//显示图片专用
}

void DrawTransRec(Mat mat, int x, int y, int width, int height, CvScalar color, double alpha)
{
IplImage * img = &(IplImage)mat;
IplImage * rec = cvCreateImage(cvSize(width, height), img->depth, img->nChannels);
//if(x>0&&y>0&&x<mat.cols&&y<mat.){
cv::Rect roi = cv::Rect(x, y, width, height) & cv::Rect(0, 0, mat.cols, mat.rows);
if (roi.area() != width*height)return;
cvRectangle(rec, cvPoint(0, 0), cvPoint(width, height), color, -1);
cvSetImageROI(img, cvRect(roi.x, roi.y, roi.width, roi.height));
cvAddWeighted(img, alpha, rec, 1 - alpha, 0.0, img);
cvResetImageROI(img);
cvReleaseImage(&rec);
}

//
//                       _oo0oo_
//                      o8888888o
//                      88" . "88
//                      (| -_- |)
//                      0\  =  /0
//                    ___/`---'\___
//                  .' \\|     |// '.
//                 / \\|||  :  |||// \
//                / _||||| -:- |||||- \
//               |   | \\\  -  /// |   |
//               | \_|  ''\---/''  |_/ |
//               \  .-\__  '-'  ___/-. /
//             ___'. .'  /--.--\  `. .'___
//          ."" '<  `.___\_<|>_/___.' >' "".
//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//         \  \ `_.   \_ __\ /__ _/   .-` /  /
//     =====`-.____`.___ \_____/___.-`___.-'=====
//                       `=---='
//
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//               佛祖保佑         永无BUG
//
//
//


CPP常用函数:

画直线

void cv::line	(	InputOutputArray 	img,
Point 	pt1,
Point 	pt2,
const Scalar & 	color,
int 	thickness = 1,
int 	lineType = LINE_8,
int 	shift = 0
)

画箭头

void cv::arrowedLine	(	InputOutputArray 	img,
Point 	pt1,
Point 	pt2,
const Scalar & 	color,
int 	thickness = 1,
int 	line_type = 8,
int 	shift = 0,
double 	tipLength = 0.1
)


画圆

void cv::circle	(	InputOutputArray 	img,
Point 	center,
int 	radius,
const Scalar & 	color,
int 	thickness = 1,
int 	lineType = LINE_8,
int 	shift = 0
)

画矩形

void cv::rectangle	(	InputOutputArray 	img,
Point 	pt1,
Point 	pt2,
const Scalar & 	color,
int 	thickness = 1,
int 	lineType = LINE_8,
int 	shift = 0
)

画多边形

void cv::polylines	(	Mat & 	img,
const Point *const * 	pts,
const int * 	npts,
int 	ncontours,
bool 	isClosed,
const Scalar & 	color,
int 	thickness = 1,
int 	lineType = LINE_8,
int 	shift = 0
)

画椭圆

void cv::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 cv::ellipse	(	InputOutputArray 	img,
const RotatedRect & 	box,
const Scalar & 	color,
int 	thickness = 1,
int 	lineType = LINE_8
)

画标记

void cv::drawMarker	(	Mat & 	img,
Point 	position,
const Scalar & 	color,
int 	markerType = MARKER_CROSS,
int 	markerSize = 20,
int 	thickness = 1,
int 	line_type = 8
)

叠加文字

void cv::putText	(	InputOutputArray 	img,
const String & 	text,
Point 	org,
int 	fontFace,
double 	fontScale,
Scalar 	color,
int 	thickness = 1,
int 	lineType = LINE_8,
bool 	bottomLeftOrigin = false
)


更为详细的解释:官网地址


Python+Opencv:

官网地址:地址

Drawing Functions in OpenCV

Goal
学习用OpenCV绘制不同的几何形状
您将了解这些功能:cv2.line() cv2.circle() cv2.rectangle() cv2.ellipse() cv2.putText()
Code

在所有上述函数中,您将看到一些常见的参数,如下所示:
img:要绘制形状的图像
color:形状的颜色。对于BGR,将其作为元组传递,例如:(255,0,0)用于蓝色。对于灰度,只传递标量值。
thickness:线或圆的厚度等。如果对于像圆圈的封闭图形通过** - 1 **,它将填充形状。默认厚度= 1
lineType:线路类型,是8连接,抗锯齿线(8-connected, anti-aliased )等。默认情况下,它是8连接。线路_AA给出了抗锯齿线,看起来很好的曲线


绘直线

要绘制线,您需要传递线的开始和结束坐标。我们将创建一个黑色图像,并从左上角到右下角绘制一条蓝线。

import numpy
as np

import cv2

#创建黑色图像

img = np.zeros((512,512,3),np.uint8)

#绘制一条厚度为5像素的对角蓝线

cv2.line(img,(0,0),(511,511),(255,0,0),5)


绘制矩形

要绘制矩形,您需要矩形的左上角和右下角。这次我们将在图像的右上角绘制一个绿色矩形。

cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)


绘图圈

要绘制圆,您需要它的中心坐标和半径。我们将在上面绘制的矩形内画一个圆。

cv2.circle(img,(447,63),63,(0,0,255), - 1)


绘制椭圆

要绘制椭圆,我们需要传递几个参数。一个参数是中心位置(x,y)。下一个参数是轴长度(长轴长度,短轴长度)。angle是椭圆在逆时针方向上的旋转角度。startAngle开始和endAngle表示椭圆弧从长轴按顺时针方向测得的起始和结束。即给出值0和360给出完整的椭圆。有关更多详细信息,请查看cv2.ellipse()文档。下面的示例在图像的中心绘制一个半椭圆。

cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1)


绘图多边形

要绘制多边形,首先需要顶点的坐标。将这些点变成形状ROWSx1x2的数组,其中ROWS是顶点的数量,它应该是int32类型。这里我们绘制一个小的多边形与四个顶点黄色。

pts = np.array([[10,5],[20,30],[70,20],[50,10]],np.int32)

pts = pts.reshape(( - 1,1,2))

cv2.polylines(img,[pts],True,(0,255,255))

注意如果第三个参数为False,您将得到连接所有点的折线,而不是闭合形状。cv2.polylines()可以用来绘制多行。只需创建一个列表,您想要绘制的所有行,并将其传递给函数。所有行将单独绘制。这是一个更好和更快的方式来绘制一组线,而不是调用cv2.line()为每一行。


向图像添加文本:

要在图像中放置文本,您需要指定以下内容。
要写入的文本数据
要放置的位置坐标(即数据开始的左下角)。
字体类型(检查cv2.putText() docs支持的字体)
字体缩放(指定字体的大小)
常规的东西,如颜色,厚度,线型等。为了更好看,lineType = cv2.LINE_AA推荐。

我们将在我们的图像上以白色写入OpenCV

font = cv2.FONT_HERSHEY_SIMPLEX

cv2.putText(img,'OpenCV',(10,500),font,4,(255,255,255),2,cv2.LINE_AA)

结果

所以现在是时候看到我们的绘图的最终结果。正如你在以前的文章中学习,显示图像看到它。



祝Opencv使用愉快~~

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐