6- OpenCV+TensorFlow 入门人工智能图像处理-图片移位

图片移位

  1. opencvAPI实现
  2. 算法原理
  3. 源代码实现
import cv2
import numpy as np

# 读图
img = cv2.imread('image0.jpg',1)
# 展示图
cv2.imshow('src',img)

# 获取图片信息
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]

# 设置一个偏移矩阵 两行三列数据
matShift = np.float32([[1,0,100],[0,1,200]])# 2*3
# 目标图片warpAffine,完成矩阵的映射。
# 参数1: 原图片 参数2: 移位矩阵 参数3: 当前图片的高宽
dst = cv2.warpAffine(img,matShift,(height,width)) # 1 data 2 matshift 3 info
# 移位 矩阵运算

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

mark

原始图片和移位后图片

图片位移的算法原理

  • 分析api实现原理
  • 分析像素移动实现原理

偏移矩阵

[1,0,100],[0,1,200]  拆分为两个矩阵 2行*2列 2行*1列

[[1,0],[0,1]]  2*2   A(矩阵的前两个元素)
[[100],[200]]  2*1   B(矩阵的第三个元素)

完成矩阵的运算

输入的xy定义为C

计算公式: A*C+B = [[1*x+0*y],[0*x+1*y]]+[[100],[200]]
= [[x+100],[y+200]]

效果为: 沿着x轴向右了100,沿着y轴向下了200

A(2,2) 乘以 C(2,1) 会变成一个(2,1) 然后(2,1)加(2,1)还是(2,1)

>得到新的x,y.描述当前移位之后的矩阵

结果: (10,20)->(110,220)

对于矩阵来讲,想当于每个x加上100,y加上200

通过源代码实现图片的位移

import cv2
import numpy as np
# 读图
img = cv2.imread('image0.jpg',1)
# 展示图
cv2.imshow('src',img)
# 获取图片信息
imgInfo = img.shape
# 定义一个空模板,大小和原始图片一模一样大
dst = np.zeros(img.shape,np.uint8)

height = imgInfo[0]
width = imgInfo[1]

for i in range(0,height):
    # 宽右移100像素
    for j in range(0,width-100):
        # 目标图像i值不变,j值来自原图像加100
        dst[i,j+100]=img[i,j]
cv2.imshow('dst',dst)
cv2.waitKey(0)

mark

图片镜像

完成图片的翻转

沿着红线,每个坐标的x不变,y轴沿着红线从图片最低端实现翻转

现在的y轴坐标等于 整个图片高度的两倍减去(y-1)

实现步骤:

  1. 创建一个足够大的"画板" 宽度与原来保持一致,宽度是原来的两倍
  2. 将一副图像分别从前向后,从后向前绘制
  3. 绘制中心分割线
import cv2
import numpy as np
img = cv2.imread('image0.jpg',1)
cv2.imshow('src',img)
imgInfo = img.shape
# 旧图片的info信息
height = imgInfo[0]
width = imgInfo[1]
deep = imgInfo[2]

# 新图片的info信息
newImgInfo = (height*2,width,deep)
# 创建空白模板
dst = np.zeros(newImgInfo,np.uint8)# uint8

for i in range(0,height):
    for j in range(0,width):
        # 绘制上半部分
        dst[i,j] = img[i,j]
        # 下半部分: x值不变, y值变为 = 2*h - y -1
        dst[height*2-i-1,j] = img[i,j]
# 添加分割线
for i in range(0,width):
    dst[height,i] = (0,0,255)# BGR
cv2.imshow('dst',dst)
cv2.waitKey(0)

mark

利用移位公式进行图片缩放

定义一个两行三列的矩阵[[A1 A2 B1],[A3 A4 B2]]

拆分矩阵: 拆分成两个(2,2)和一个(2,1)矩阵

[[A1 A2],[A3 A4]] [[B1],[B2]]

计算新的x和y值:

  • newX = A1*x + A2*y+ B1
  • newY = A3*x + A4*y+ B2

实现缩放功能

  • x->x*0.5 y->y*0.5

将矩阵中的A1 A4设置为0.5, B1,B2设置为0 就等价于缩放xy 0.5

  • newX = 0.5*x
  • newY = 0.5*x
import cv2
import numpy as np
img = cv2.imread('image0.jpg',1)
cv2.imshow('src',img)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]

# 缩放矩阵(2,3)
matScale = np.float32([[0.5,0,0],[0,0.5,0]])

# 仿射方法 原始数据,缩放矩阵,最终生成图片的宽高信息
dst = cv2.warpAffine(img,matScale,(int(width/2),int(height/2)))

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

mark

图片的仿射变换

仿射变换就是将图像上每个像素点按照一定的规律映射到新的位置上

求解新的x和新的y的过程。和我们之前讲的矩阵变换非常的像。

但是仿射变换,有时候没有很明确的公式,而是1通过图片上三个点的拉伸映射出新的x值,新的y值。

mark

通过对于图片三个顶点的拉伸,实现仿射变换

为什么是三个点: 三个点可以唯一的确定一个平面

实现功能

import cv2
import numpy as np
img = cv2.imread('image0.jpg',1)
cv2.imshow('src',img)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]

# src 3->dst 3  原图上(左上角 左下角 右上角) 转换到新图片上三个点
# 原图三个点
matSrc = np.float32([[0,0],[0,height-1],[width-1,0]])
# 新图上的位置
matDst = np.float32([[50,50],[300,height-200],[width-300,100]])
# 组合: 定义一个仿射变换矩阵。
# getAffineTransform获得仿射变换矩阵。参数一:原图的点,参数二: 新图片的点
matAffine = cv2.getAffineTransform(matSrc,matDst) # mat 1 src 2 dst

# 使用仿射变换 第一个参数: 图片信息 第二个: 仿射变换矩阵 第三个:宽高信息
dst = cv2.warpAffine(img,matAffine,(width,height))
cv2.imshow('dst',dst)
cv2.waitKey(0)

mark

图片旋转

前面我们分别通过源代码,opencvapi形式,矩阵加减乘除操作形式。

几何变换中的图片旋转

import cv2
import numpy as np
# 图片载入
img = cv2.imread('image0.jpg',1)
# 展示
cv2.imshow('src',img)
# 图片信息获取
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]

# 定义一个旋转矩阵 2*3 
# getRotationMatrix2D 获取旋转矩阵
matRotate = cv2.getRotationMatrix2D((height*0.5,width*0.5),45,0.5)
# mat rotate 参数1 旋转center点 2 旋转的angle(角度) 3 scale(缩放系数)

# 为什么一个矩阵旋转的列子,要进行缩放0.5设置让它不超出边界

# 100*100 25 四个角会超出。
dst = cv2.warpAffine(img,matRotate,(height,width))
cv2.imshow('dst',dst)
cv2.waitKey(0)

mark

讲过仿射变换,图片完成了45度的旋转

如果设置缩放系数为1,超出边界位置不显示。

总结

  • 图片缩放
  • 剪切
  • 位移
  • 镜像
  • 旋转
  • 仿射变换: 位移 旋转 缩放
  • 如何使用opencv的api
  • 算法原理
  • 自己编写源代码实现

图片缩放:

  1. 通过opencv api方式cv2.resize()
  2. 图片缩放的最近邻域插值和双线性插值(算法原理)
  3. 自己编写最近邻域插值源码

几何变换的实质就是矩阵运算,给矩阵不同的系数得到不同的功能。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏iOSer成长记录

OpenGL ES(四) 变换

1232
来自专栏应兆康的专栏

OpenCV+TensorFlow 人工智能图像处理 (2)

[[1, 0, 100], [0, 1, 200]] 转变为2个矩阵: [[1, 0], [0, 1]] 和 [[100], [200]] 分别对...

792
来自专栏null的专栏

简单易学的机器学习算法——在线顺序极限学习机OS-ELM

   这篇文章主要是前面整理的,就直接上图了。 ? ? ? ? ? ? ? 实验: # coding:UTF-8 ################# # OS_...

9235
来自专栏用户2442861的专栏

openCV—图像几何变换

983
来自专栏PaddlePaddle

汇合层

深度学习基础理论-CNN篇 汇合层 ? 图 卷积神经网络第 L 层输入xl 示意图 本节讨论第L 层操作为汇合(pooling)时的情况。通常使用的汇合操作...

27211
来自专栏Flutter入门

Android OpenGL ES(四)-为平面图添加滤镜

之前我们通过YUV数据格式的处理知道,只要保留Y的数据,就是灰度的图片。但是OpenGL中处理的是RGB格式的数据,我们要如何去取得灰度图呢? 我们可以通过公...

1323
来自专栏清墨_iOS分享

OpenGL ES-3D图形变换知识

1222
来自专栏书山有路勤为径

Image Representation & Classification(图像表示与分类)

RGB channels Visualize the levels of each color channel. Pay close attention to...

832
来自专栏数值分析与有限元编程

可视化 | MATLAB划分均匀矩形网格

之前发过一个划分均匀三角形网格的例子。下面结合一个悬臂梁说说如何在规则区域划分均匀矩形网格。 ? 将一个矩形平面区域划分成相同大小的矩形。X方向等分nex,Y方...

4039
来自专栏有趣的Python

4- OpenCV+TensorFlow 入门人工智能图像处理-灰度化处理

图片特效及线段文字的绘制 特效1: 灰度处理 ? mark 完成彩色图片灰度化。彩色图片有三个颜色通道RGB 灰度图片也是三通道的话,RGB值相等。 单通...

4059

扫码关注云+社区