计算机视觉加强之几何变换

版权声明:作者已开启版权声明,如转载请注明转载地址。 https://blog.csdn.net/qq_34829447/article/details/84980659

计算机视觉加强之几何变换

一.图像几何变换概述

几何变换的实质就是矩阵的运算,根据矩阵的不同从而实现不同的变换

1.图片缩放

  • imageInfo:图片宽、高、通道个数等
  • 缩放
    • 等比例缩放:宽高比不变
    • 任意比例缩放:图片拉伸 非拉伸

2.图片剪切

  • 根本思路:拿到图片矩阵中的数据,根据数据完成剪切【本质是对矩阵的操作】

3.图片位移

  • 根本思路:根据矩阵实现图片的映射变化

4.图片镜像

  • 实现步骤
    • 创建一个足够大的画板
    • 将一副图像分别从前向后、从后向前绘制
    • 绘制中心分割线

5.仿射变换:位移 旋转 缩放

二.图片缩放实例

1.开发思路

  • 拿到图片的原始数据(图片的加载)
  • 获取图片的信息(图片的宽度、高度)
  • 调用resize方法完成图片的缩放
  • 检查最终的结果

2.实例代码

import cv2
img = cv2.imread('test.JPG',1)
imgInfo = img.shape
print(imgInfo)#打印图片的宽度 高度 颜色组成方式
height = imgInfo[0]
width = imgInfo[1]
mode = imgInfo[2]#颜色组成方式为3,表示一个像素点由3个基本颜色组成
#1.有放大和缩小两种情况
#2.根据比例有等比例缩放和非等比例缩放,与原图片的宽高比相同称为等比例
dstHeight = int(height*0.1)
dstWidth = int(width*0.1)
#在OpenCV中有四种常见的图片缩放方法
#1.最近领域插值
#2.双线性插值——我们采用
#3.像素关系重采样
#4.立方插值
dst = cv2.resize(img,(dstWidth,dstHeight))
cv2.imshow('image',dst)
cv2.waitKey(0)

3.最近邻域插值法与双线性插值法

  • 目标图形上的点都来自于原图形

    • src 10*20 dst 5*10
    • dst <- src
    • (1,2) <- (2,4)其中dst x 1 -> src x 2 newX
    • newX = x*(src 行/目标 行)newX = 1*(10/5) = 2
    • newY = y*(src 列/目标 列)newY = 2*(20/10) = 4
    • 如结果为12.3我们取12的方法称之为最近邻域插值法(取距离指定值最近的像素)
  • 双线性插值法如下图所示

在这里插入图片描述

  • A1、A2 = 20% * 下 + 80%*上
  • B1、B2 = 30% * 右 + 70%*左
  • 计算方法一:最终点 = A1 * 70% + A2*20%
  • 计算方法二:最终点 = B1 * 80% + B2*20%

4.源码实现最近邻域插值法图片缩放

  • 实现步骤

    • 获得图片info
    • 创建空白模板
    • 重设xy坐标
  • 实例代码

    import cv2
    import numpy as np #使用numpy创建空白模板
    #获得图片信息
    img = cv2.imread("image0.jpg",1)
    imgInfo = img.shape #通过img.shape拿到当前图片的信息
    height = imgInfo[0]
    width = imgInfo[1]
    dstHeight = int(height*0.1)
    dstWidth = int(width*0.1)
    #创建空白模板
    dstImage = np.zeros((dstHeight,dstWidth,3),np.uint8) #np.uint8的范围为0-255
    for i in range(0,dstHeight):#对应行信息
        for j in range(0,dstWidth):#对应列信息
            iNew = int(i*(height*1.0/dstHeight))
            jNew = int(j*(width*1.0/dstWidth))
            dstImage[i,j] = img[iNew,jNew]
    cv2.imshow('dst',dstImage)
    cv2.waitKey(0)
    

三.图片剪切

1.开发思路

  • x轴从100剪切到200
  • y轴从100剪切到300

2.实例代码

import cv2
img = cv2.imread('image0.jpg',1)
imgInfo = img.shape
dst = img[100:200,100:300]#x轴值从100到200,y轴值从100到300
cv2.imshow('image',dst)
cv2.waitKey(0)

四.图片移位

1.开发思路

  • 如何使用OpenCV API实现移位的功能
  • 了解移位的算法原理
  • 通过源码实现移位

2.实例代码

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的矩阵,float32表示32类型,水平方向上移动100个像素,垂直方向上移动200个像素
dst = cv2.warpAffine(img,matShift,(height,width)) #完成当前矩阵的映射,参数:原始图片的data信息;移位矩阵;图片的info信息
#完成矩阵的移位,实际是矩阵的运算
cv2.imshow('dst',dst)
cv2.waitKey(0)

3.图像移位的算法原理

  • 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
  • 基于像素级别的实现原理
    • (10,20) -> (110,220)

4.源码实现图像位移

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 r in range(0,height-200):
    for j in range(0,width-100):
        dst[i+200,j+100] = img[i,j] #表示总宽度不变,向右移动100;总高度不变,向下移动200
cv2.imshow('image',dst)
cv2.waitKey(0)

五.图片镜像

1.开发思路

  • 完成图片的上下反转,每个像素点的x坐标不变,y坐标 = 高度*2-y初始高
  • 创建画板,宽度一致,高度两倍,将图片从上到下绘制
  • 绘制到中间时,将图片从后向前绘制
  • 绘制中间的分割线

2.实例代码

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]
deep = imgInfo[2]#颜色深度,表示RGB3种颜色
newImageInfo = (height*2,width,deep)
dst = np.zeros(newImageInfo,np.uint8)
for i in range(0,height):
    for j in range(0,width):
        #绘制上半部分
        dst[i,j] = img[i,j]
        #绘制下半部分 x值不变,y变为高度的两倍-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)

六.图片缩放

1.回顾图片位移实现原理

  • 定义矩阵[[A1,A2,B1],[A3,A4,B2]]
  • 拆分矩阵[[A1,A2],[A3,A4]] [[B1],[B2]]
  • 矩阵运算获得新的x坐标newX = A1*x + A2*y +B1
  • 矩阵运算获得新的y坐标newY = A3*x + A4*y +B2

2.分析图片缩放实现原理

  • 如缩放0.5
  • x->x*0.5 y->y*0.5
  • newX = 0.5*x ; newY = 0.5*y

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]
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)

七.图片的仿射变换

仿射变换就是原图片上的点按照新的规律映射到新的图片上,即求解新的x和新的y,通常情况下没有明确的公式进行计算,而是通过左上角左下角和右上角的点的拉伸实现对图片的仿射变换【三点确定唯一的平面】

1.开发思路

  • 将原图上的三个点映射到目标图片上三个新的位置上[左上角,左下角,右上角]

2.实现代码

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表示原始图片上的三个点
matSrc = np.float32([[0,0],[0,height-1],[width-1,0]])
#matDst表示对于matSrc上的三个点,在新的dst上的位置
matDst = np.float32([[50,50],[300,height-200],[width-300,100]])
#组合两个矩阵
matAffine = cv2.getAffineTransform(matSrc,matDst) #得到矩阵组合,本质上是一个mat,参数:src中左上角、左下角及右上角的矩阵;原来图片上三个点在dst上的位置
dst = cv2.warpAffine(img,matAffine,(width,height))
cv2.imshow('dst',dst)
cv2.waitKey(0)

八.图片旋转

1.开发思路

  • 定义旋转矩阵,并初始化
  • 调用仿射方法,完成仿射变换

2.实例代码

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]
#定义旋转矩阵,并初始化
matRotate = cv2.getRotationMatrix2D((height*0.5,width*0.5),45,0.5) #描述旋转矩阵,参数:旋转中心点;旋转角度;缩放的系数
#调用仿射方法,完成仿射变换
dst = cv2.warpAffine(img,matRotate,(width,height))
cv2.imshow('dst',dst)
cv2.waitKey(0)

猜你喜欢

转载自blog.csdn.net/qq_34829447/article/details/84980659
今日推荐