【基于C++和Python的Opencv3学习笔记之基本图形的绘制】

Opencv作为计算机视觉库,主要工作是处理和操作图像,因此如何存储和处理图像非常重要,opencv3主要运用Mat这个类来存储对象。

Mat类介绍

Mat类由两部分组成,矩阵头(主要是矩阵尺寸,存储方法、存储地址等)和一个指向存储像素值的矩阵的指针。为了解决传递图像可能产生的运算量大等问题,opencv使用了引用计数机制,即每个Mat对象都有自己信息头,但是共享同一个像素矩阵。赋值和拷贝构造函数只是复制信息头和矩阵指针,不复制矩阵。这种情况下,通过任何一个Mat对象对矩阵的改变都会影响其他对象,但是有时想复制矩阵本身,可以使用clone()函数或者copyTo()函数。

像素值的存储要指定颜色空间和数据类型,最简单的颜色空间是灰度空间,只有黑色和白色,通过不同组合达到不同程度的灰色,对于彩色的颜色空间,通常采用RGB颜色空间,有时候会加入透明度Alpha。数据类型决定了像素值的精度,最小的数据类型是char,占一个字节或者8位,可以是有符号(0到255)和(-128到127),还可以是float(4字节,32位)和double(8字节,64位)。

Opencv常见类和函数

Point类

Point类描述图像上的点,及由图像坐标x和y指定的二维点,用法如下:

Point point;

Point point = Point(10,8);

point.x = 5;

point.y = 10;

另外在Opnecv中有如下定义:

typedef Point<int> Point2i;

typedef Point2i Point;

typedef Point_<float> Point2f

所以Point<int>、Point2i、Point等价,Point_<float>、Point2f等价


2、Scalar类

Scalar()表示有4个元素的数组,在Opencv常用于传递像素值,如RGB颜色值。其实如果只写三个参数,Opencv或默认为RGB三个参数


3、Rect类

Rect类的成员变量有x、y、width、height,分辨是左上角点的坐标和矩形的宽和高。常见的成员函数有,Size()返回值为Size,area()返回矩形的面积,contain(Point)判断点是否在矩形内,inside(Rect)判断矩形是否在矩形内,tl()返回左上角点的坐标,br()返回右下角点的坐标。


4、cvtColor()函数

cvtColor()函数是Opencv的颜色空间转换函数,函数原型如下:

void cvtColor(InputArray src, OutputArray dst, int coded, int dstCn=0);

函数参数分别代表输入图像,输出图像,颜色空间转换标识符,目标图像的通道数(默认取源图像的通道数)


基本图形绘制(基于C++)

#include "stdafx.h"
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>

using namespace std;
using namespace cv;

# define WINDOW_WIDTH 600

// 绘制不同角度椭圆
void DrawEllipse(Mat img, double angle)
{
	int thickness = 2;
	int lineType = 8;

	// 调用ellipse函数
	ellipse(img, Point( WINDOW_WIDTH / 2, WINDOW_WIDTH / 2), Size( WINDOW_WIDTH / 4, WINDOW_WIDTH / 16), angle,
		0, 360, Scalar(255, 129, 0), thickness, lineType);
}

// 绘制实心圆
void DrawFilledCircle(Mat img, Point center)
{
	int thickness = -1;
	int lineType = 8;

	circle(img, center, WINDOW_WIDTH / 32, Scalar(0, 0, 255), thickness, lineType);
}

// 绘制多边形
void DrawPolygon(Mat img)
{
	int lineType = 8;

	Point rookPoints[1][20];
	rookPoints[0][0] = Point(WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8);
	rookPoints[0][1] = Point(3 * WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8);
	rookPoints[0][2] = Point(3 * WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16);
	rookPoints[0][3] = Point(11 * WINDOW_WIDTH / 16, 13 * WINDOW_WIDTH / 16);
	rookPoints[0][4] = Point(19 * WINDOW_WIDTH / 32, 3 * WINDOW_WIDTH / 8);
	rookPoints[0][5] = Point(3 * WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8);
	rookPoints[0][6] = Point(3 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 8);
	rookPoints[0][7] = Point(26 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 8);
	rookPoints[0][8] = Point(26 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 4);
	rookPoints[0][9] = Point(22 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 4);
	rookPoints[0][10] = Point(22 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 8);
	rookPoints[0][11] = Point(18 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 8);
	rookPoints[0][12] = Point(18 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 4);
	rookPoints[0][13] = Point(14 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 4);
	rookPoints[0][14] = Point(14 * WINDOW_WIDTH / 40, WINDOW_WIDTH / 8);
	rookPoints[0][15] = Point(WINDOW_WIDTH / 4, WINDOW_WIDTH / 8);
	rookPoints[0][16] = Point(WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8);
	rookPoints[0][17] = Point(13 * WINDOW_WIDTH / 32, 3 * WINDOW_WIDTH / 8);
	rookPoints[0][18] = Point(5 * WINDOW_WIDTH / 16, 13 * WINDOW_WIDTH / 16);
	rookPoints[0][19] = Point(WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16);

	const Point *ppt[1] = { rookPoints[0] };
	int npt[] = { 20 };

	fillPoly(img, ppt, npt, 1, Scalar(255, 255, 255), lineType);

}

// 绘制线
void DrawLine(Mat img, Point start, Point end)
{
	int thickness = 2;
	int lineType = 8;
	line(img, start, end, Scalar(0, 0, 0), thickness, lineType);
}

int _tmain(int argc, _TCHAR* argv[])
{
	namedWindow("基本图形绘制1");
	namedWindow("基本图形绘制2");
	Mat img1 = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3);
	Mat img2 = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3);

	// 绘制椭圆
	DrawEllipse(img1, 0);
	DrawEllipse(img1, 45);
	DrawEllipse(img1, 90);
	DrawEllipse(img1, 135);

	// 绘制实心圆
	DrawFilledCircle(img1, Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2));

	// 显示图形1
	imshow("基本图形绘制1", img1);

	// 绘制多边形
	DrawPolygon(img2);

	// 绘制线段
	DrawLine(img2, Point(100, 200), Point(500, 200));
	
	
	// 显示图形2
	imshow("基本图形绘制2", img2);
	waitKey(0);
	return 0;
}




基本图形绘制(基于Python)

# coding=UTF-8
import numpy as np
import cv2

WINDOW_WIDTH = 600
title_1 = '基本图形绘制1'
title_2 = '基本图形绘制2'


def DrawEllipse(img, angle):
    '''

    :param img:
    :param angle:
    :return:
    '''

    thickness = 2
    lineType = 8
    cv2.ellipse(img, ( WINDOW_WIDTH / 2, WINDOW_WIDTH / 2), ( WINDOW_WIDTH / 4, WINDOW_WIDTH / 16), angle, 0, 360,
                (255, 129, 0), thickness, lineType)


def DrawFilledCircle(img, center):
    '''

    :param img:
    :param center:
    :return:
    '''

    thickeness = -1
    lineType = 8;

    cv2.circle(img, center, WINDOW_WIDTH / 32, (0, 0, 255), thickeness, lineType)


def DrawPolygon(img ):
    '''

    :param img:
    :return:
    '''
    lineType = 8

    a3 = np.array([[[100, 100], [500, 100], [500, 500], [100, 500]]])
    cv2.fillPoly(img, a3, (255, 0, 0))


def DrawLine(img, start, end):
    '''

    :param img:
    :param start:
    :param end:
    :return:
    '''
    thickness = 2
    lineType = 8

    cv2.line(img, start, end, (0, 0, 255), thickness, lineType)


if __name__=='__main__':
    # 初始化
    img1 = np.zeros((WINDOW_WIDTH, WINDOW_WIDTH, 3), np.uint8)
    img2 = np.zeros((WINDOW_WIDTH, WINDOW_WIDTH, 3), np.uint8)

    # 绘制椭圆
    DrawEllipse(img1, 0)
    DrawEllipse(img1, 45)
    DrawEllipse(img1, 90)
    DrawEllipse(img1, 135)

    # 绘制实心圆
    DrawFilledCircle(img1, ( WINDOW_WIDTH / 2, WINDOW_WIDTH / 2))

    # 显示基本图形1
    cv2.imshow(title_1, img1)

    # 绘制多边形
    DrawPolygon(img2)

    # 绘制线段
    DrawLine(img2, (200, 300), (400, 300))

    # 显示基本图形1
    cv2.imshow(title_2, img2)

    cv2.waitKey(0)






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程目的:OpenCV是应用非常广泛的开源视觉处理库,在图像处理、计算机视觉和自动驾驶中有着非常重要的作用。课程设计特色:(课程当前为第一期)1、C++Python双语教学Python语言是在计算机视觉中应用最多的一种语言,在工作中,深度学习模型的训练基本上都是使用Python语言编写的训练代码。OpenCV在这个过程中用于图像的预处理(例如图像读取、数据增强)和后处理,还可以用于显示处理的结果,功能强大,使用方便。但是在功能的部署的时候,不管是部署在服务端还是PC端,开发语言基本上用的是C++,所以如何有效的使用OpenCV进行模型或者功能的部署尤为重要。C++语言应用的好坏,在面试中可以看出一个面试者的工程实践能力的强弱,两种语言的开发掌握好了可以使工作如虎添翼。2、全模块讲解我出版了一本图书《学习OpenCV4:基于Python的算法实战》,虽然这本书是写的基于Python的算法实战,但是实际上这本书有详细的介绍算法的C++接口,还有一些C++方向的案例,是以Python为主。图书出版的时候就想双语写作,只是限于篇幅没有成行。本课程不仅采用双语教学,更是对C++的每个模块都做讲解,我们知道,很多的书其实只讲imgproc,如果你翻开一本书图像的形态学运算和图像滤波都是作为独立章节讲解的,那么这本书基本上就可以确定是只是讲解了imgproc模块,但是其他的模块在工作中也有很重要的作用。例如:core模块定义了C++基本数据结构和基本运算(如四则运算);highgui模块是可视化与交互的模块;feature2d是特征点与特征匹配相关算法所在的模块;ml是机器学习相关的模块;dnn是深度学习相关的模块,可以使用OpenCV进行深度学习模型的部署。这些是很多的书和课程都不会讲的。3、讲解细致本课程会从环境搭建开始讲解,环境搭建尤为重要。从我多年的授课经验总结来看,如果只是给了代码,很多的入门用户环境问题处理不好的话,后面的学习很难进行下去,甚至会丧失学习的信心。4、会讲解C++Python的开发语法问题是入门用户的一大难关,特别是C++语言。大学只是教授了C语言相关的内容,C++很多同学只懂一点皮毛,所以写代码步履维艰,我们在讲解代码的过程中会顺带讲解C++Python的内容。我们还会讲解编译相关知识,还有库的装载与链接,这些是学校里不会教的,目前也几乎没有课程讲解。5、讲师经验丰富我讲解过C++OpenCV的多个课程,广受学员好评。我出版过两本图书《深度学习计算机视觉实战》和《学习OpenCV4》,两本书都是细致入微的讲解,主要针对的就是初学者,所以能够很好的处理课程的难易程度。6、讲义准备充分讲义准备的充分细致,标识清楚明确,重点和疑难点突出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值