图像几何变换

几何变换
在齐次坐标下,改变位置,不改变像素值

图像缩放

1.调用API

import cv2
import numpy as np

# 图像缩放:你得有缩放的比例吧
img = cv2.imread('image0.jpg', 1)
# 调用API
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dstHeight = int(height*0.5)
dstWidth = int(width*0.5)
dst2 = cv2.resize(img, (dstWidth, dstHeight)) #(列数,行数)
cv2.imshow('image', dst2)
cv2.waitKey(0)
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)

2.算法自己实现
缩放算法:最近领域插值法,双线性插值法
算法原理:
参考:算法原理
写一下自己的理解
首先缩放就是计算新图像像素点在原图的位置
在这里插入图片描述

最近邻域插值法:新计算出的像素点在原图中的位置是(15.2,22.3)
最近邻就是取原图中(15,22)像素点的像素放入到新图像中。简单粗暴

双线性插值:取(15.2,22.3)最近的4个点(15,22),(15,23),(16,22),(16,23)将这4个点的像素值按照一定的比例加在一起,算出一个新的像素值放到新图像中。精巧
这个比例如何计算(线性插值,当然是线性的了)
直观的感受就是(15.2,22.3)这个点的像素值应该更接近(15,22)
公式:0.7(0.8(15,22)+0.2(16,22))+0.3(0.8(15,23)+0.2(16,23))
看图

def resizeNew(image,new_size):
    '''
    :param image: 原图像矩阵
    :param new_size: 新图像的大小,和API保持一直
    :return: 
    '''
    # 原图像的大小
    imgInfo=image.shape
    height=imgInfo[0]
    width=imgInfo[1]
    # 缩放后图像的大小
    dstWidth,dstHeight=new_size
    # 创建新图像大小的矩阵
    dstImage=np.zeros((dstHeight,dstWidth,3),np.uint8)
    # 新图像的像素大小,应按照缩放比例从原图像中抽取
    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]=image[iNew,jNew]
    return dstImage
def resize(src, new_size):
    dst_w, dst_h = new_size # 目标图像宽高
    src_h, src_w = src.shape[:2] # 源图像宽高
    if src_h == dst_h and src_w == dst_w:
        return src.copy()
    scale_x = float(src_w) / dst_w # x缩放比例
    scale_y = float(src_h) / dst_h # y缩放比例
    # 遍历目标图像,插值
    dst = np.zeros((dst_h, dst_w, 3), dtype=np.uint8)
    for n in range(3): # 对channel循环
        for dst_y in range(dst_h): # 对height循环
            for dst_x in range(dst_w): # 对width循环
                # 目标在源上的坐标 说是按照几何中心对称找的中心点
                src_x = (dst_x + 0.5) * scale_x - 0.5
                src_y = (dst_y + 0.5) * scale_y - 0.5
                # 计算在源图上四个近邻点的位置
                # np.floor 返回不大于输入参数的最大整数。
                src_x_0 = int(np.floor(src_x))
                src_y_0 = int(np.floor(src_y))
                src_x_1 = min(src_x_0 + 1, src_w - 1)
                src_y_1 = min(src_y_0 + 1, src_h - 1)
                # 双线性插值
                value0 = (src_x_1 - src_x) * src[src_y_0, src_x_0, n] + (src_x - src_x_0) * src[src_y_0, src_x_1, n]
                value1 = (src_x_1 - src_x) * src[src_y_1, src_x_0, n] + (src_x - src_x_0) * src[src_y_1, src_x_1, n]
                dst[dst_y, dst_x, n] = int((src_y_1 - src_y) * value0 + (src_y - src_y_0) * value1)
    return dst

这个计算量太大,特别慢。还是直接调用API吧

图像剪切

import cv2
img = cv2.imread('image0.jpg', 1)
# 图像剪切
# 截切的位置
src=img[100:200,100:200]  # 裁剪坐标为[y0:y1, x0:x1]
cv2.imshow('jianqie',src)
cv2.waitKey(0)

要剪切的区域,查看像素坐标系
在这里插入图片描述

知识点:世界坐标、相机坐标、图像坐标、像素坐标的原理
图像上,相机中,现实世界位置一一对应

图像平移

'''矩阵计算'''
import cv2
import numpy as np

# 1 API 2 算法原理 3 源代码
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 正数就是下右,负数是上左
dst = cv2.warpAffine(img, matShift, ( width,height),borderValue =0)  # 1 data 2 mat变换矩阵 3 info
# 移位 矩阵
cv2.imshow('dst', dst)
cv2.waitKey(0)


def shift(image, h, w):
    imgInfo = image.shape
    dst = np.zeros(image.shape, np.uint8)# 0--255
    height = imgInfo[0]
    width = imgInfo[1]
    for i in range(0, height - h):
        for j in range(0, width - w):
        # for循环相当于剪切了
        	# 把像素对应过去
            dst[i + h, j + w] = img[i, j]  # 图像下右移动
            # dst[i, j] = img[i + h, j + w]  # 上左
    return dst
dst = shift(img, 200, 100)  # h=>y,w=>x
cv2.imshow('dst', dst)
cv2.waitKey(0)

仿射变换

# 图像仿射
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]])
#组合
# 仿射矩阵
matAffine = cv2.getAffineTransform(matSrc,matDst)# mat 1 src 2 dst
print(matAffine)
dst = cv2.warpAffine(img,matAffine,(width,height))
cv2.imshow('dst',dst)
cv2.waitKey(0)

仿射变换
图像的旋转加拉升
1.3个点确定一个平面
2.cv2.getAffineTransform根据变换前后的两个点对应,输出的就是仿射矩阵M
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]
deep = imgInfo[2]
# newImgInfo = (height*2,width,deep)
newImgInfo = (height,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-i-1,j] = img[i,j]
        # 水平翻转
        dst[i , width-j-1] = img[i, j]
import cv2
import numpy as np
img = cv2.imread('image0.jpg',1)
img1=cv2.flip(img,1)
cv2.imshow('flip',img1)
cv2.waitKey(0)

#cv2.flip(src, flipCode[, dst]) → dst
#src: 原始图像矩阵;
#dst: 变换后的矩阵;
#flipMode: 翻转模式,有三种模式
#0 --- 垂直方向翻转; 1----- 水平方向翻转; -1:水平、垂直方向同时翻转
#flipCode==0垂直翻转(沿X轴翻转),flipCode>0水平翻转(沿Y轴翻转),flipCode<0水平垂直翻转(先沿X轴翻转,再沿Y轴翻转,等价于旋转180°)

图像旋转

# 图像旋转
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
#第一个参数旋转中心,第二个参数旋转角度,第三个参数:缩放比例
matRotate = cv2.getRotationMatrix2D((height*0.5,width*0.5),45,1)# mat rotate 1 center 2 angle 3 scale
print(matRotate)
#100*100 25
dst = cv2.warpAffine(img,matRotate,(height,width))
cv2.imshow('dst',dst)
cv2.waitKey(0)

所有的变换操作都可以转换为矩阵的计算
几何变换矩阵原理
cv2.warpAffine
src - 输入图像。
M - 变换矩阵。
dsize - 输出图像的大小。
flags - 插值方法的组合(int 类型!)
borderMode - 边界像素模式(int 类型!)
borderValue - (重点!)边界填充值; 默认情况下,它为0。
上述参数中:M作为仿射变换矩阵,一般反映平移或旋转的关系,为InputArray类型的2×3的变换矩阵。
flages表示插值方式,默认为 flags=cv2.INTER_LINEAR,表示线性插值,此外还有:cv2.INTER_NEAREST(最近邻插值) cv2.INTER_AREA (区域插值) cv2.INTER_CUBIC(三次样条插值) cv2.INTER_LANCZOS4(Lanczos插值)

cv2.warpPerspective
cv2.getAffineTransform
根据前后变换的两个点得到仿射矩阵
cv2.getRotationMatrix2D
这个函数需要三个参数,旋转中心,旋转角度,旋转后图像的缩放比例
参考
写的详细

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值