opencv学习(5)

图像几何变换

绘图

目录

目标:

图像几何变换

缩放

翻转

平移

旋转

绘图

画线

矩形

椭圆

多边形

添加文字 

例子

小结

练习


目标:

1.实现旋转、平移和缩放图片

2.OpenCV函数:cv2.resize()cv2.flip()cv2.warpAffine()

3.绘制各种几何形状、添加文字

4.OpenCV函数:cv2.line()cv2.circle()cv2.rectangle()cv2.ellipse()cv2.putText()

图像几何变换

旋转、平移、缩放和翻转图片

缩放

缩放就是调整图片的大小,使用cv2.resize()函数实现缩放

可按照比例缩放,也可按照指定大小缩放:

import cv2

img = cv2.imread('drawing.jpg')

# 按照指定的宽度、高度缩放图片
res = cv2.resize(img, (132, 150))
# 按照比例缩放,如x,y轴均放大一倍
res2 = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_LINEAR)

cv2.imshow('shrink', res), cv2.imshow('zoom', res2)
cv2.waitKey(0)

可指定缩放方法interpolation(插值方法),默认是INTER_LINEAR

具体参考InterpolationFlags

翻转

镜像翻转图片,可以用cv2.flip()

dst = cv2.flip(img, 1)

其中,参数2 = 0:垂直翻转(沿x轴),

参数2 > 0: 水平翻转(沿y轴),

参数2 < 0: 水平垂直翻转。

平移

要平移图片,我们需要定义下面这样一个矩阵,tx,ty是向x和y方向平移的距离:

平移是用仿射变换函数cv2.warpAffine()实现的:

# 平移图片
import numpy as np

rows, cols = img.shape[:2]

# 定义平移矩阵,需要是numpy的float32类型
# x轴平移100,y轴平移50
M = np.float32([[1, 0, 100], [0, 1, 50]])
# 用仿射变换实现平移
dst = cv2.warpAffine(img, M, (cols, rows))

cv2.imshow('shift', dst)
cv2.waitKey(0)

 

 

旋转

旋转同平移一样,也是用仿射变换实现的,因此也需要定义一个变换矩阵。

OpenCV直接提供了cv2.getRotationMatrix2D()函数来生成这个矩阵,该函数有三个参数:

参数1:图片的旋转中心

参数2:旋转角度(正:逆时针,负:顺时针)

参数3:缩放比例,0.5表示缩小一半

# 45°旋转图片并缩小一半
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 0.5)
dst = cv2.warpAffine(img, M, (cols, rows))

cv2.imshow('rotation', dst)
cv2.waitKey(0)

 

 

绘图

学习画线、圆和矩形等多种几何形状,给图片添加文字

绘制形状的函数有一些共同参数,提前在此说明一下:

img:要绘制形状的图片

color:绘制的颜色

彩色图,传入BGR的一组值,如蓝色就是(255,0,0)

灰度图,传入一个灰度值就行

thickness:线宽,默认为1;对于矩形/圆之类的封闭形状而言,传入-1表示填充形状

需要导入的模块和显示图片的通用代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt

cv2.imshow('img', img)
cv2.waitKey(0)

 

画线

画直线只需指定点和点的坐标就行:

# 创建一副黑色的图片
img = np.zeros((512, 512, 3), np.uint8)
# 画一条线宽为5的蓝色直线,参数2:起点,参数3:终点
cv2.line(img, (0, 0), (512, 512), (255, 0, 0), 5)

注:所有绘图函数均会直接影响原图片,这点要注意。 

矩形

画矩形需要知道左上角和右下角的坐标:

# 画一个绿色边框的矩形,参数2:左上角坐标,参数3:右下角坐标
cv2.rectangle(img, (384, 0), (510, 128), (0, 255, 0), 3)

 

画圆需要指定圆心半径,注意下面例子中线宽=-1代表填充:

# 画一个填充红色的圆,参数2:圆心坐标,参数3:半径
cv2.circle(img, (447, 63), 63, (0, 0, 255), -1)

 

椭圆

画椭圆需要的参数比较多,请对照后面的代码理解这几个参数:

参数2:椭圆中心(x,y)

参数3:x/y轴的长度

参数4:angle---椭圆的旋转角度

参数5:startAngle---椭圆的起始角度

参数6:endAngle---椭圆的结束角度

注:OpenCV中原点在左上角,所以这里的角度是以顺时针方向计算的。

# 在图中心画一个填充的半圆
cv2.ellipse(img, (256, 256), (100, 50), 0, 0, 180, (255, 0, 0), -1)

多边形

画多边形需要指定一系列多边形的顶点坐标,相当于从第一个点到第二个点画直线,再从第二个点到第三个点画直线....

OpenCV中需要先将多边形的顶点坐标需要变成顶点数×1×2维的矩阵,再来绘制:

# 定义四个顶点坐标
pts = np.array([[10, 5],  [50, 10], [70, 20], [20, 30]], np.int32)
# 顶点个数:4,矩阵变成4*1*2维
pts = pts.reshape((-1, 1, 2))
cv2.polylines(img, [pts], True, (0, 255, 255))

 cv2.polylines()的参数3如果是False的话,多边形就不闭合

注:如果需要绘制多条直线,使用cv2.polylines()要比cv2.line()高效很多,例如:

# 使用cv2.polylines()画多条直线
line1 = np.array([[100, 20],  [300, 20]], np.int32).reshape((-1, 1, 2))
line2 = np.array([[100, 60],  [300, 60]], np.int32).reshape((-1, 1, 2))
line3 = np.array([[100, 100],  [300, 100]], np.int32).reshape((-1, 1, 2))
cv2.polylines(img, [line1, line2, line3], True, (0, 255, 255))

添加文字 

使用cv2.putText()添加文字,它的参数也比较多,同样要对照后面的代码理解这几个参数:

参数2:要添加的文本

参数3:文字的起始坐标(左下角为起点)

参数4:字体

参数5:文字大小(缩放比例)

# 添加文字
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, 'ex2tron', (10, 500), font,
            4, (255, 255, 255), 2, lineType=cv2.LINE_AA)

字体可参考HersheyFonts 

另外,这里有个线型lineType参数,LINE_AA表示抗锯齿线型,具体可见LineTypes

例子

上述成品如图

 

小结

1.cv2.resize() 缩放图片,可按指定大小缩放,也可按比例缩放

2.cv2.flip()翻转图片,可以指定水平/垂直/水平垂直翻转三种方式

3.平移/旋转是靠仿射变换cv2.warpAffine()实现的

4.cv2.line()画直线,cv2.circle()画圆,cv2.rectangle()画矩形,cv2.ellipse()画椭圆,cv2.polylines()画多边形,cv2.putText()添加文字

5.画多条直线时,cv2.polylines()要比cv2.line()高效很多

练习

1.能用已学的绘图功能画出OpenCV的logo吗?(提示:椭圆和圆)

 

import cv2
import numpy as np

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

# 画OpenCV的logo
# 1.先画一个0°到300°的圆
# 2.再在中心画一个跟背景颜色一样的小圆
# 3.重复前两部,并且旋转一定的角度即可

# 画绿色的部分
cv2.ellipse(img, (43, 125), (45, 45), 0, 0, 300,
            (0, 255, 0), -1, lineType=cv2.LINE_AA)
cv2.circle(img, (43, 125), 15, (0, 0, 0), -1, lineType=cv2.LINE_AA)

# 画红色的部分
cv2.ellipse(img, (90, 40), (45, 45), 120, 0, 300,
            (0, 0, 255), -1, lineType=cv2.LINE_AA)
cv2.circle(img, (90, 40), 15, (0, 0, 0), -1, lineType=cv2.LINE_AA)

# 画蓝色的部分
cv2.ellipse(img, (137, 125), (45, 45), -60, 0, 300,
            (255, 0, 0), -1, lineType=cv2.LINE_AA)
cv2.circle(img, (137, 125), 15, (0, 0, 0), -1, lineType=cv2.LINE_AA)

cv2.imshow('img', img)
cv2.waitKey(0)

执行如图 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值