2.4 OpenCV随手简记(五)

一、图像翻转
第一个图像翻转,这个可是制作表情包的利器。
图像翻转在 OpenCV 中调用函数 flip() 实现,原函数如下:

复制代码
flip(src, flipCode, dst=None)
  • src:原始图像。

  • flipCode:翻转方向,

  • 如果 flipCode 为 0 ,则以 X 轴为对称轴翻转,

  • 如果 fliipCode > 0 则以 Y 轴为对称轴翻转,

  • 如果 flipCode < 0 则在 X 轴、 Y 轴方向同时翻转。

示例如下:

python 复制代码
import cv2 as cv
import matplotlib.pyplot as plt
# 读取图片 由 GBR 转 RGB
img = cv.imread('maliao.jpg')
src = cv.cvtColor(img, cv.COLOR_BGR2RGB)
# 图像翻转
# flipCode 为 0 ,则以 X 轴为对称轴翻转,如果 fliipCode > 0 则以 Y 轴为对称轴翻转,如果
flipCode < 0 则在 X 轴、 Y 轴方向同时翻转。
img1 = cv.flip(src, 0)
img2 = cv.flip(src, 1)
img3 = cv.flip(src, -1)
# plt 显示图形
titles = ['Source', 'Ima1', 'Ima2', 'Ima3']
images = [src, img1, img2, img3]
for i in range(4):
plt.subplot(2, 2, i + 1)
plt.imshow(images[i])
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()


二、放射变换
1.图像平移
图像平移是通过仿射函数 warpAffine() 来实现的,原函数如下:

python 复制代码
warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None,
borderValue=None)

在图像平移中我们会用到前三个参数:

  1. 需要变换的原始图像
  2. 移动矩阵 M
  3. 变换的图像大小(如果这个大小不和原始图像大小相同,那么函数会自动通过插值来调整像素间的关系)。
    图像的平移是沿着 x 方向移动 tx 距离, y 方向移动 ty 距离,那么需要构造移动矩阵 :
python 复制代码
M = [ [1,0,tx], [0,1,ty]]

M 2x3 矩阵, M 矩阵必须是 float 类型的。
创建 M 矩阵有如下两种方法:
(1) 、 M = np.zeros(2,3,np.float32)
M[0] = [1,0,tx]
M[1] = [0,1,ty]
(2) 、 M = np.float32([1,0,tx], [0,1,ty])
我们通过 Numpy 来产生 M 矩阵(必须是 float 类型的),并将其赋值给仿射函数 warpAffine() ,下
面来看个示例:

python 复制代码
import cv2 as cv
import numpy as np
#读取图片
src = cv.imread('maliao.jpg')
rows, cols = src.shape[:2]
# 定义移动距离
tx = 50
ty = 100
# 生成 M 矩阵
M = np.float32([[1, 0, tx], [0, 1, ty]])
# 平移
dst = cv.warpAffine(src, M, (cols, rows))
# 显示图像
cv.imshow('src', src)
cv.imshow("dst", dst)
# 等待显示
cv.waitKey(0)
cv.destroyAllWindows()


注意: warpAffine 函数的第三个参数是输出图像的大小, 这里设置的大小是原图片的大小,所
以结果会有部分遮挡。
2.平移的动态演示

python 复制代码
import cv2 as cv
import numpy as np
import time
#读取图片
src = cv.imread('beauty5.jpeg')
rows, cols = src.shape[:2]
# 定义移动距离
tx = 50
ty = 100
i = 0
while cv.waitKey(1) == -1: #等待1毫秒后,用户按下任意键
# 生成 M 矩阵
M = np.float32([[1, 0, tx+i], [0, 1, ty]])
# 平移
dst = cv.warpAffine(src, M, (cols, rows))
# 显示图像
cv.imshow("dst", dst)
time.sleep(1/190)
i = i+1
cv.destroyWindow("dst")

# 斜下方移动,移出后又返回
import cv2 as cv
import numpy as np
import time
#读取图片
src = cv.imread('beauty5.jpeg')
rows, cols = src.shape[:2]
# 定义移动距离
tx = 0
ty = 0
i = 0
while cv.waitKey(1) == -1: #等待1毫秒后,用户按下任意键
# 生成 M 矩阵
if tx+i>src.shape[1]: # 移出后又返回
i = 0
Tx = tx+i
Ty = ty+i
M = np.float32([[1, 0, Tx], [0, 1, Ty]])
# 平移
dst = cv.warpAffine(src, M, (cols, rows))
# 显示图像
cv.imshow("dst", dst)
time.sleep(1/190)
i = i+1
cv.destroyWindow("dst")

3.图像旋转
图像旋转主要调用 getRotationMatrix2D() 函数和 warpAffine() 函数实现,绕图像的某一个中心
点旋转,具体如下:
M = cv2.getRotationMatrix2D((cols/2, rows/2), 30, 1)
参数分别为:旋转中心、旋转度数、 scale
rotated = cv2.warpAffine(src, M, (cols, rows))
参数分别为:原始图像、旋转参数、原始图像宽高
图像旋转:设( x0 , y0 )是旋转后的坐标,( x , y )是旋转前的坐标, ( m , n ) 是旋转中心, a 是旋转 的角度( 顺时针 ) , ( left , top ) 是旋转后图像的左上角坐标,则公式如下 :

python 复制代码
import cv2 as cv
#读取图片

src = cv.imread('maliao.jpg')
# 原图的高、宽
rows, cols = src.shape[:2]
# 绕图像的中心旋转
# 参数:旋转中心 旋转度数 scale
M = cv.getRotationMatrix2D((cols/2, rows/2), 90, 1)
#
dst = cv.warpAffine(src, M, (cols, rows))
# 显示图像
cv.imshow("src", src)
cv.imshow("dst", dst)
# 等待显示
cv.waitKey()
cv.destroyAllWindows()


4.图片动态旋转效果

python 复制代码
# 固定大小旋转
import cv2 as cv
import time
#读取图片
src = cv.imread('beauty5.jpeg')
# 原图的高、宽
5.4 图像倾斜
rows, cols = src.shape[:2]
i = 1
while cv.waitKey(1) == -1: #等待1毫秒后,用户按下任意键
# 生成 M 矩阵
M = cv.getRotationMatrix2D((cols/2, rows/2), 0+i*30, 0.5) # 0-i*30 反转
# 绕图像的中心旋转
# 参数:旋转中心 旋转度数 scale
dst = cv.warpAffine(src, M, (cols, rows))
i = i+1
# 显示图像
cv.imshow("dst", dst)
time.sleep(1/10) # 时间越短,现象越有趣
cv.destroyWindow("dst")
python 复制代码
# 由小到大旋转
import cv2 as cv
import time
#读取图片
src = cv.imread('beauty5.jpeg')
# 原图的高、宽
rows, cols = src.shape[:2]
i = 1
while cv.waitKey(1) == -1: #等待1毫秒后,用户按下任意键
# 生成 M 矩阵
M = cv.getRotationMatrix2D((cols/2, rows/2), 0+i*20, 0.01*i)
# 绕图像的中心旋转
# 参数:旋转中心 旋转度数 scale
dst = cv.warpAffine(src, M, (cols, rows))
i = i+1
if i == 100:
i = 1
time.sleep(3)
# 显示图像
cv.imshow("dst", dst)
time.sleep(1/30)
cv.destroyWindow("dst")

5.图像倾斜

python 复制代码
import cv2
import numpy as np
img = cv2.imread("demo.png") # 读取图像
rows = len(img) # 图像像素行数
cols = len(img[0]) # 图像像素列数
p1 = np.zeros((3, 2), np.float32) # 32位浮点型空列表,原图三个点
p1[0] = [0, 0] # 左上角点坐标
p1[1] = [cols - 1, 0] # 右上角点坐标
p1[2] = [0, rows - 1] # 左下角点坐标
p2 = np.zeros((3, 2), np.float32) # 32位浮点型空列表,倾斜图三个点
p2[0] = [50, 0] # 左上角点坐标,向右挪50像素
p2[1] = [cols - 1, 0] # 右上角点坐标,位置不变
p2[2] = [0, rows - 1] # 左下角点坐标,位置不变
M = cv2.getAffineTransform(p1, p2) # 根据三个点的变化轨迹计算出M矩阵
dst = cv2.warpAffine(img, M, (cols, rows)) # 按照M进行仿射
cv2.imshow('img', img) # 显示原图
cv2.imshow('dst', dst) # 显示仿射变换效果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体

6.透视变换

摄像机斜视拍摄一物体后,形成的图像会发生变形,如果将图像映射到拍摄物体平面上,相当于将相机垂直于拍摄平面,这样就会得到图像的真实形状,由于这种映射相当于将原图重新 透视 到另一个平面,这种称之为" 重投影 " 。

上述仿射变换可以将矩形映射成任意平行四边形, 各边仍保持平行 ;而透视变换可以将矩形映射为 任意四边形 , 直线仍保持直线 。 由于不再是平行四边形,需提供四个顶点。
透视变换通过函数 cv2.warpPerspective() 实现,语法为 :

python 复制代码
warpPerspective(src, M, dsize, dst=None, flags=None, borderMode=None,
borderValue=None)
'''
dst:透视后的输出图像,dsize决定输出图像大小
src:输入图像
M:3*3变换矩阵
flags:插值方法,默认为INTER_LINEAR
borderMode:边类型,默认为BORDER_CONSTANT
borderValue:边界值,默认为0
'''

透视变换通过函数 cv2.getPerspectiveTransform() 来生成转换矩阵,需输入输入图像和输出图像的
四个顶点的坐标。

python 复制代码
cv2.getPerspectiveTransform(p1,p2)
# p1,p2分别为原图像4点坐标和新图像4点坐标

手动获取图像顶点的直接透视变换
1 、获取图像四个顶点(通过 photoshop 等软件手动获取,或用 python-opencv 程序手动获取)
2 、形成变换矩阵
3 、透视变换

python 复制代码
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('C:/Users/df/Desktop/pp.png')
H_rows, W_cols= img.shape[:2]
print(H_rows, W_cols)
# 原图中书本的四个角点(左上、右上、左下、右下),获取方法见《鼠标点击图片显示点击点及坐标》
pts1 = np.float32([[124,62], [457,100], [53,576], [559,539]])
#变换后矩阵位置
pts2 = np.float32([[0, 0],[W_cols,0],[0, H_rows],[H_rows,W_cols],])
# 生成透视变换矩阵;进行透视变换
M = cv2.getPerspectiveTransform(pts1, pts2)
dst = cv2.warpPerspective(img, M, (668, 634))
cv2.imshow("original_img",img)
cv2.imshow("result",dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
python 复制代码
import cv2
import numpy as np
img = cv2.imread("pp.png")
print("the shape of the imag is: ",img.shape)
def on_EVENT_LBUTTONDOWN(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
xy = "%d,%d" % (x, y)
print (xy)
cv2.circle(img, (x, y), 1, (255, 0, 0), thickness = -1)
cv2.putText(img, xy, (x, y), cv2.FONT_HERSHEY_PLAIN,
1.0, (0,0,0), thickness = 1)
cv2.imshow("image", img)
cv2.namedWindow("image")
cv2.setMouseCallback("image", on_EVENT_LBUTTONDOWN)
cv2.imshow("image", img)
while(True):
try:
cv2.waitKey(100)
if cv2.getWindowProperty('img',cv2.WND_PROP_VISIBLE) <= 0:
break # 防止直接关闭窗口后的"阻塞"
except Exception:
cv2.destroyWindow("image")
break
cv2.waitKey(0)
#cv2.destroyAllWindow()

通过创建一个鼠标回调函数,当鼠标事件发生时执行该函数。鼠标事件可以是任何与鼠标相关的事 件,如左键向下、左键向上、左键双击等。 它为我们提供了每个鼠标事件的坐标( x y )。

相关推荐
GIOTTO情7 分钟前
媒介宣发的技术革命:Infoseek如何用AI重构企业传播全链路
大数据·人工智能·重构
阿里云大数据AI技术16 分钟前
云栖实录 | 从多模态数据到 Physical AI,PAI 助力客户快速启动 Physical AI 实践
人工智能
小关会打代码23 分钟前
计算机视觉进阶教学之颜色识别
人工智能·计算机视觉
IT小哥哥呀29 分钟前
基于深度学习的数字图像分类实验与分析
人工智能·深度学习·分类
机器之心1 小时前
VAE时代终结?谢赛宁团队「RAE」登场,表征自编码器或成DiT训练新基石
人工智能·openai
机器之心1 小时前
Sutton判定「LLM是死胡同」后,新访谈揭示AI困境
人工智能·openai
大模型真好玩1 小时前
低代码Agent开发框架使用指南(四)—Coze大模型和插件参数配置最佳实践
人工智能·agent·coze
jerryinwuhan1 小时前
基于大语言模型(LLM)的城市时间、空间与情感交织分析:面向智能城市的情感动态预测与空间优化
人工智能·语言模型·自然语言处理
落雪财神意1 小时前
股指10月想法
大数据·人工智能·金融·区块链·期股
中杯可乐多加冰1 小时前
无代码开发实践|基于业务流能力快速开发市场监管系统,实现投诉处理快速响应
人工智能·低代码