图像处理之opencv图片几何变化操作大全

微笑、不失礼 提交于 2020-02-08 09:30:23

1、opencv读取图片

  • cv2.imread()方法封装了4个步骤,分别为:
    • 1、文件的读取 2、封装格式解析 3、数据解码 4、数据加载
import cv2

# 1、文件的读取  2、封装格式解析   3、数据解码   4、数据加载
img = cv2.imread('image1.jpg', 1) #1表示彩色图片
#图片展示
cv2.imshow('image', img)

#释放资源
cv2.waitKey(0)
cv2.destroyAllWindows()


2、opencv保存图片

import cv2

# 1、文件的读取  2、封装格式解析   3、数据解码   4、数据加载
img = cv2.imread('image1.jpg', 1) #1表示彩色图片
#图片保存
# 1、jpg,png 文件头   2、文件数据
cv2.imwrite('image1.png', img)#返回结果为True,表示写入成功


3、图像质量压缩

3.1、有损压缩——jpg格式

  • 参数cv2.IMWRITE_JPEG_QUALITY的压缩范围是0~100,有损压缩以牺牲图片像素为前提
import cv2
img = cv2.imread('image1.jpg', 1)

cv2.imwrite('imageTest.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 0])

在这里插入图片描述

3.2、无损压缩——png格式

  • cv2.IMWRITE_PNG_COMPRESSION 压缩比0~9
import cv2
img = cv2.imread('image1.jpg', 1)
cv2.imwrite('imageTest.png', img, [cv2.IMWRITE_PNG_COMPRESSION, 0])#压缩比0~9

总结: jpg的0 压缩比高 0~100; png的0 压缩比低 0 ~ 9
在这里插入图片描述

4、像素操作

4.1、像素值的读取

import cv2
img = cv2.imread('image1.jpg', 1)
#采集图片坐标为(100,100)的像素点,返回方式为元组
(b, g, r) = img[100, 100]
print (b, g, r)
232 240 240

4.2、像素值的写入

import cv2
img = cv2.imread('image1.jpg', 1)

# 绘制一条(100,100) ————> (100,600)的坚状红线
for i in range(1,500):
    img[100+i, 100] = (0, 0, 255)#和坐标系方向相反,[100+i, 100]=[y, x]
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述



5、图片缩放

5.1、查看图片宽高

import cv2
img = cv2.imread('image1.jpg', 1)

imgInfo = img.shape#返回值为图片的高,宽和颜色组成
print (imgInfo)
height = imgInfo[0]
width = imgInfo[1]
mode = imgInfo[2]
print ("图片的高度=%s,宽度=%s,颜色组成为:%s"%(height, width, mode))
(736, 1022, 3)
图片的高度=736,宽度=1022,颜色组成为:3

5.2、等比例缩放

  • 宽高各缩放一半

5.2.1、直接定义比率

detHeight = int(height*0.5)
detWidth = int(width*0.5)
newSet = cv2.resize(img, (detWidth, detHeight))
cv2.imshow('image', newSet)
cv2.waitKey(0)
cv2.destroyAllWindows()

5.2.2、使用cv2.warpAffine()方法映射

import cv2
import numpy as np

img = cv2.imread('image1.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]])#2行3列矩阵;横向移动100px,纵向移动200px
#cv2.warpAffine()实现原像素的映射
dst = cv2.warpAffine(img, matScale, (int(width//2), int(height//2)))# 1 data; 2 mat; 3 info
cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果图片


5.2、非等比例缩放

  • 一共有4种:最近临域插值、双线性插值、像素关系重采样、立方插值
  • 默认是双线性插值

5.2.1、最近临域插值

  • src=(10 Х 20) ——> dst=(5 Х 10)
  • (1,2) <—— (2,4)
  • newX = x*(src行 / dst行) ——> newX = 1 * (10/5) = 2
  • newY = y*(src列 / dst列) ——> newY = 1 * (20/10) = 4
import cv2
import numpy as np

img = cv2.imread('image1.jpg', 1)
imgInfo = img.shape#返回值为图片的高,宽和颜色组成
print (imgInfo)
height = imgInfo[0]
width = imgInfo[1]
mode = imgInfo[2]
print ("图片的高度=%s,宽度=%s,颜色组成为:%s"%(height, width, mode))
detHeight = int(height/2)
detWidth = int(width/2)

dstImage = np.zeros((detHeight, detWidth, 3), np.uint8)#创建一个画布
for i in range(0, detHeight):#行
    for j in range(0, detWidth):#列
        iNew = int(i*(height* 1.0/detHeight))
        jNew = int(j*(width* 1.0/detWidth))
        dstImage[i, j] = img[iNew, jNew]
    cv2.imwrite('./newImage.jpg', dstImage)
cv2.imshow('dst',dstImage)
cv2.waitKey(0)
cv2.destroyAllWindows()

5.2.2、双线性插值

- A1 = 20% X 上 + 80% x 下; A2 = 20% X 上 + 80% x 下;
- B1 = 30% X 左 + 70% x 右; B2 = 20% X 左 + 80% x 右;
- 最终点1 = A1 x 30% + A2 x 70%
- 最终点2 = B1 x 20% + B2 x 80%

在这里插入图片描述


6、图片剪切

import cv2
img = cv2.imread('image1.jpg', 1)
detImage = img[100:200, 100:300]#剪切像素点
cv2.imshow('CutImage', detImage)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

7、图片位移

7.1、使用opencv方法位移图片

import cv2
import numpy as np

img = cv2.imread('image1.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列矩阵;横向移动100px,纵向移动200px
#cv2.warpAffine()实现原像素的映射
dst = cv2.warpAffine(img, matShift, (height, width))# 1 data; 2 mat; 3 info

cv2.imshow('dst', dst)

cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述


7.2、使用数组方法位移图片

import cv2
import numpy as np

img = cv2.imread('image1.jpg', 1)
cv2.imshow('src', img)
# 获取图片宽高
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros(img.shape, np.uint8)#定义一个空数组
for i in range(0, height):
    for j in range(0, width-100):
        dst[i, j+100] = img[i, j]
        
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

8、图片镜像

实现步骤:

  1. 创建一个足够大的”画板
  2. 将一副图像分别从前向后、 从后向前绘制
  3. 绘制中心分割线
import cv2
import numpy as np

img = cv2.imread('image2.jpg', 1)
cv2.imshow('src', img)
# 获取图片宽高
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
deep = imgInfo[2]
#定义新图片的信息
newImgInfo = (height*2, width, deep)
dst = np.zeros(newImgInfo, np.uint8)#定义一个空数组,作为画布大小
# 向画布写入像素点
for i in range(0, height):
    for j in range(0, width):
        dst[i, j] = img[i, j]#绘制上面一张图片
        #绘制下面张图片,高正好是上面移动像素的一半,宽保持不变;y = 2*h-i-1
        dst[height*2-i-1,j] = img[i,j]
for i in range(0, width):
    dst[height, i] = (0,0,255)#在图片中间画一条红线
        
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述



9、仿射变换

  • 仿射变换包括:位移、旋转、缩放、变形

9.1、图片旋转

在这里插入图片描述

9.2、图片变形

  • 要领:操作图片的三个角(左上角,左下角,右上角)变化
  • cv2.getAffineTransform()完成组合
  • cv2.warpAffine()完成映射
import cv2
import numpy as np

img = cv2.imread('image2.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], [200,height-100], [width-100,50]])
# 仿射变换矩阵——>组合
matAffine = cv2.getAffineTransform(matSrc, matDst)# 1 src,2 dst
dst = cv2.warpAffine(img, matAffine,(width,height))

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

在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!