【学习笔记】opencv的python接口 几何变换

先跑一下示例代码:
平移:


import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('66.png')
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
mode = imgInfo[2]

dst = np.zeros(imgInfo, np.uint8)

for i in range( height ):
    for j in range( width - 100 ):
        dst[i, j + 0] = img[i, j]

cv.imshow('image', dst)
cv.waitKey(0)

【学习笔记】opencv的python接口 几何变换_第1张图片
其中 dst[i, j + 0] = img[i, j]是控制平移的距离的,可以看到上面的右边黑色的一块是平移的效果,如果写成dst[i,j+100] = img[i,j]则效果为:
【学习笔记】opencv的python接口 几何变换_第2张图片

缩放:


import cv2 as cv
import numpy as np

img=cv.imread('me1.jpg')
# 下面的 None 本应该是输出图像的尺寸,但是因为后边我们设置了缩放因子
# 因此这里为 None
res=cv.resize(img,None,fx=2,fy=2,interpolation=cv.INTER_CUBIC)
#OR
# 这里呢,我们直接设置输出图像的尺寸,所以不用设置缩放因子
height,width=img.shape[:2]
res=cv.resize(img,(2*width,1*height),interpolation=cv.INTER_CUBIC)
while(1):
    cv.imshow('res',res)
    cv.imshow('img',img)
    if cv.waitKey(1) & 0xFF == 27:
        break
cv.destroyAllWindows()

自己修改了一下width和height前面的系数,运行结果:
【学习笔记】opencv的python接口 几何变换_第3张图片
效果大概就是图片明显被拉长了。然后这个系数只能是整数,感觉有点不实用

关于旋转

示例代码是:

img = cv.imread('messi5.jpg',0)
rows,cols = img.shape
# cols-1 and rows-1 are the coordinate limits.
M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
dst = cv.warpAffine(img,M,(cols,rows))

我运行了以后显示:
【学习笔记】opencv的python接口 几何变换_第4张图片
查了一下大概是shape有三个返回值,然后我修改了其中一句话,加上了显示的代码,代码改为:

rols,cols,color = img.shape
M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
dst = cv.warpAffine(img,M,(cols,rows))
cv.imshow("ye",dst)
cv.waitKey()

运行能成功了,效果:
【学习笔记】opencv的python接口 几何变换_第5张图片

仿射变换:

介绍:
仿射变换是指在向量空间中进行一次线性变换(乘以一个矩阵)并加上一个平移(加上一个向量),变换为另一个向量空间的过程。在有限维的情况下,每个仿射变换可以由一个矩阵A和一个向量b给出,它可以写作A和一个附加的列b。**一个仿射变换对应于一个矩阵和一个向量的乘法,而仿射变换的复合对应于普通的矩阵乘法,**只要加入一个额外的行到矩阵的底下,这一行全部是0除了最右边是一个1,而列向量的底下要加上一个1.
我们能够用仿射变换来表示:

旋转 (线性变换)
平移 (向量加)
缩放操作 (线性变换)
示例代码:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('1.jpg')
rows,cols,ch = img.shape
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = cv.getAffineTransform(pts1,pts2)
dst = cv.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

然后记录一下其中出现的函数和库:
1.Matplotlib 是 Python 的绘图库。 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案.
2.getAffineTransform函数

函数作用:
主要用于生成仿射变换矩阵
一个任意的仿射变换都能表示为 乘以一个矩阵 (线性变换) 接着再 加上一个向量 (平移).
3.warpAffine函数使用如下矩阵进行图像转换
在这里插入图片描述
4.个人觉得np.float32就是生成一个矩阵,用pts1保存
5.subplot(nrows,ncols,plot_number) 如subplot(2,3,4)可以写成sublot(234)

效果:
【学习笔记】opencv的python接口 几何变换_第6张图片

透视变换:
代码:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('1.jpg')
rows,cols,ch = img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv.getPerspectiveTransform(pts1,pts2)
dst = cv.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

【学习笔记】opencv的python接口 几何变换_第7张图片
感觉就是截取了其中一部分然后放大了?

重映射

img = cv2.imread("p7.jpg",cv2.IMREAD_UNCHANGED)
rows,cols = img.shape[:2]
msx = np.ones((rows,cols),np.float32)*200
msy = np.ones((rows,cols),np.float32)*100
dst = cv2.remap(img,msx,msy,cv2.INTER_LINEAR)
cv2.imshow("i",img)
cv2.imshow("d",dst)

mapx:用来指定列的参数均为200
mapy:用来指定行的参数均为100
在函数 cv2.remap()中,参数map1和参数map2用来说明反向映射,map1针对的是坐标x,map2针对的是坐标y。
参数map1指代的是像素点所在位置的列号,参数map2指代的是像素点所在位置的行号。
【学习笔记】opencv的python接口 几何变换_第8张图片

用remap实现翻转

代码:

img = np.random.randint(0,256,size=[4,5],dtype=np.uint8)
i1 = np.zeros(img.shape,np.float32) #x坐标轴的值保持不变
i2 = np.zeros(img.shape,np.float32) # y坐标轴为总行号-1-当前行号
rows,cols = img.shape
for i in range(rows):
    for j in range(cols):
        i1.itemset((i,j),j)
        i2.itemset((i,j),rows - i -1)

RST = cv2.remap(img,i1,i2,cv2.INTER_LINEAR)
print(RST)
print(img)

注意函数: i1.itemset((i,j),j)
【学习笔记】opencv的python接口 几何变换_第9张图片

交换x和y轴

img = np.random.randint(0,256,size=[4,5],dtype=np.uint8)
i1 = np.zeros(img.shape,np.float32) #x坐标轴的值保持不变
i2 = np.zeros(img.shape,np.float32) # y坐标轴为总行号-1-当前行号
rows,cols = img.shape
for i in range(rows):
    for j in range(cols):
        i1.itemset((i,j),i)
        i2.itemset((i,j),j)

RST = cv2.remap(img,i1,i2,cv2.INTER_LINEAR)
print(RST)
print(img)

【学习笔记】opencv的python接口 几何变换_第10张图片
结果出现了0,可见行列数不一样时运算中存在值无法映射的情况,无法完成映射的值被处理为0了

练习题:

​ 将下面纸张通过变换调节至正中央水平竖直放置,最终呈现的图片效果上要保留白纸外的区域:


代码:


import cv2 as cv

img = cv.imread('shu.png')
rows,cols,color = img.shape
# cols-1 and rows-1 are the coordinate limits.
scale_percent =100
M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),-140,1)
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)

resized = cv.resize(img, dim, interpolation = cv.INTER_AREA);
dst = cv.warpAffine(resized,M,(cols,rows))
cv.namedWindow("enhanced",0);
#cv.resizeWindow("enhanced", 500, 480);

cv.imshow("enhanced",dst)
cv.waitKey()

其中scale_percent =100
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)
是用来调整图片大小的。

自己修改了一下窗口大小,不然有点太大
效果:
【学习笔记】opencv的python接口 几何变换_第11张图片
另外两边不是竖直的无能为力了(这个纸应该是拍照角度原因四个角不是九十度)

你可能感兴趣的:(opencv学习,opencv,计算机视觉)