图像处理那点事儿之一凌波微步

1.简介

本文内容参考B站-机器视觉及图像识别
不懂图像处理的图像算法工程师都是耍流氓,本文均属于作者个人看法,仅供参考。
其实学习处理图像,就像是追女孩子。刚开始会有点恐惧,面对那么多华丽丽的技巧,心中不由的会问自己我配吗。接触一段时间以后,觉得也不过如此,再华丽的算法也有瑕疵和一些小任性。最后到手了,你明白真正的爱是懂她,包容她。郭敬明说:“我颠倒了整个世界,只为摆正你的倒影”。我现在虽然还只是小菜鸟一枚,但是对于所有的华丽丽,我已经不再恐惧。下面我们将按照追女神的套路,来学习这门技术,只是为了让枯燥的学习变得有意思。

1.空间转换

图像处理的核心在于将图像转换为矩阵,然后对于矩阵进行修改,再把修改完的矩阵转换成图像。主要分为以下几个方面:图像的空间转换 、图像特效、美化效果。
空间转换是对图像的位置信息进行处理,所以说要追她你先得知道她在哪里,如何去改变她的位置,看个电影喝个茶。

1.图像缩放:

缩放就是缩和放,顾名思义我们要处理的就是如何由原来的像素值生目标像素值。
效果如下:我们把她变小了
原始图片
在这里插入图片描述

实现方式 首先我们直接调用opencv接口来实现,直接用resize即可

import cv2
img = cv2.imread('tangwei.jpg')
print(img.shape)
height = img.shape[0]
width = img.shape[1]
des_height = int(height*0.5)
des_width = int(width*0.5)
img_des = cv2.resize(img,(des_width,des_height))
cv2.imwrite('tangwei-1.jpg',img_des)
cv2.imshow('tangwei',img_des)
cv2.waitKey(0)

插值:插值一般分为两种:最近邻域插值和双线性插值。最近邻域插值就是取离目标点最近的原图上点的像素值作为该点的像素值;要说双线性插值就得先了解线性插值,线性插值的原理是,离自己最近的两个点的值乘以各自所占的比例之和,双线性插值就是水平和垂直方向进行两次线性插值。上面的resize默认使用的就是双线性插值,下面代码展示了最近邻域插值:

#最近邻域插值
import cv2
import numpy as np
#读取原始图片 定义目标图片形状 为新图片像素赋值
#读取原始图片
img = cv2.imread('tangwei.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width =  imgInfo[1]
#定义目标图片形状
height_dest = int(height/2)
width_dest = int(width/2)
#np.uint8 取值为0-255
img_dest = np.zeros((height_dest,width_dest,3),np.uint8)
#为新图片像素赋值
for i in range(0,height_dest):
    for j in range(0,width_dest):
        i_new = int(i*(height/height_dest))
        j_new = int(j*(width/width_dest))
        img_dest[i,j] = img[i_new,j_new]
cv2.imshow('tangwei',img_dest)
cv2.waitKey(0)

2.图片剪切

剪切就是用图像矩阵进行一个切片操作,无聊,无味,简单,我很喜欢!
在这里插入图片描述

import cv2
img = cv2.imread('tangwei.jpg',1)
imgInfo =  img.shape
img_crop = img[300:400,300:400]
cv2.imshow('img',img_crop)
cv2.waitKey(0)
### 3.图像位移

位移就是把原来x处的值,替换到x+n处;如果我们的移动距离为n,那么图片0—n处的值将会变为空。
在这里插入图片描述

#API调用
import cv2
import numpy as np
img = cv2.imread('tangwei.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width =  imgInfo[1]
#仿射变化公式[[1x+0y+100],[0x+1y+200]]=[x,y]
matShit = np.float32([[1,0,100],[0,1,200]])
dat = cv2.warpAffine(img,matShit,(height,width))
cv2.imshow('tangwei',dat)
cv2.waitKey(0)

#源码
import cv2
import numpy as np
img = cv2.imread('tangwei.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
img_dest  = np.zeros((imgInfo),np.uint8)
#位移相当于将原图像映射到一个新的图像
#新图像的(x+距离,y+距离)=(x,y)
#原图像超出距离的部分被剪裁掉
for i in range(0,height-100):
    for j in range(0,width-100):
        img_dest[i+100,j+100] = img[i,j]
cv2.imshow('tangwei',img_dest)
cv2.waitKey(0)

4.镜像

镜像效果,是把原来的图像宽或者搞扩大两倍。其中第一部分是原图的内容,第二部分内容正好和原图相反。比如垂直镜像,那么第二部分像素的值就是 2*height-height 的值。
在这里插入图片描述

#垂直镜像
import cv2
import numpy as np
#1.读取原图 
#2.定义目标图片 height_dest = height*2 width_dest = width
#3.为目标图片赋值 0--height = height  height--(height*2-1-height)
#4.分割线 height--red
#5.展示图片

#1.读取原图 
img = cv2.imread('liqin.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
deep = imgInfo[2]
#2.定义目标图片
img_dest = np.zeros((height*2,width,deep),np.uint8)
#3.为目标图片赋值
for i in range(0,height):
    for j in range(0,width):
        img_dest[i,j]=img[i,j]
        img_dest[height*2-i-1,j] = img[i,j]
#4.分割线
img_dest[height,:] =(0,0,255)
cv2.imshow('tangwei',img_dest)
cv2.waitKey(0)

#水平镜像
import cv2
import numpy as np
#1.读取原图 
#2.定义目标图片 height_dest = height*2 width_dest = width
#3.为目标图片赋值 0--height = height  height--(height*2-1-height)
#4.分割线 height--red
#5.展示图片

#1.读取原图 
img = cv2.imread('liqin.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
deep = imgInfo[2]
#2.定义目标图片
img_dest = np.zeros((height,width*2,deep),np.uint8)
#3.为目标图片赋值
for i in range(0,height):
    for j in range(0,width):
        img_dest[i,j]=img[i,j]
        img_dest[i,width*2-1-j] = img[i,j]
#4.分割线
img_dest[:,height] =(128,128,128)#bgr
cv2.imshow('tangwei',img_dest)
cv2.waitKey(0)

###5.仿射变换
原图左上、左下、右上三个点;目标图左上、左下、右上三个点;调用API得到仿射矩阵,可以理解为一种原图到目标图的映射关系,进行仿射生成目标图像
在这里插入图片描述

#仿射变换
import cv2
import numpy  as np
#仿射变换 1.原图 左上 左下 右上 三个点 目标图 左上 左下 右上 三个点
#2.获取仿射矩阵 3.调用API生成仿射后图片
img =  cv2.imread('liqin.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
#原图 左上 左下 右上 三个点
src_dat = np.float32([[0,0],[0,height-1],[width-1,0]])
#目标图 左上 左下 右上 三个点
dest_dat = np.float32([[0,100],[400,400],[400,200]])
#获取仿射矩阵
affine_dat = cv2.getAffineTransform(src_dat,dest_dat)
print(affine_dat)
#仿射变换
dest_img = cv2.warpAffine(img,affine_dat,(width,height))
cv2.imshow('tangwei',dest_img)
cv2.waitKey(0)  

6.旋转

旋转的基本原理和仿射很像,得到一个旋转矩阵,然后进行仿射矩阵
在这里插入图片描述

#旋转图片
#1.得到旋转矩阵 2.进行仿射变换
import cv2
import numpy as np
img =  cv2.imread('liqin.jpg')
img_info = img.shape
height = img_info[0]
width = img_info[1]
rotation_dat = cv2.getRotationMatrix2D((height*0.5,width*0.5),45,0.5)
img_dest = cv2.warpAffine(img,rotation_dat,(width,height))
cv2.imshow('dest',img_dest)
cv2.waitKey(0)

7.实用技巧之等比例缩放

等比例缩放就是缩放图片,并且保持原始图片的比例不变,一般实现方式是将长边缩放到目标长度,短边按照长边的比例进行缩放,对于缺失的部分进行补0。该方法见于YOLOV3中的图片处理,对于YOLOV3来说图像缩放完成之后,会按照相同的方式对于box框进行调整,保证box位置准确。
在这里插入图片描述
在这里插入图片描述

#实现方式一 PIL
#等比例缩放
#原理:将长边缩放到416 短边按照长边的比例进行缩放 超出的部分进行填充128
#保证原始图像的比例
#步骤 1.计算w h 缩放的比例 进行缩放 2.定义蒙版图片416*416 3.将原始图片粘贴到蒙版上
from PIL import Image
w = 416
h = 416
image = Image.open('tangwei.jpg')
iw,ih = image.size
scale = min(w/iw,h/ih)
sw  = int(iw*scale)
sh = int(ih*scale)
#粘贴左上角的位置
dx = (w-sw)//2
dy = (h-sh)//2
image = image.resize((sw,sh))
#定义蒙版图片
new_image  =  Image.new('RGB',(w,h),(128,128,128))
new_image.paste(image,(dx,dy))
new_image.save('tangwei_scale.jpg')

#实现方式二opencv+numpy
import cv2
import numpy as np
img = cv2.imread('tangwei.jpg',1)
cv2.imshow('img',img)
img_info = img.shape
h = 416
w =  416
height = img_info[0]
width = img_info[1]
dest = np.zeros((416,416,3),np.uint8)+128
scale = min(h/height,w/width)
sh =  int(height*scale)
sw = int(width*scale)
#//表示整除
dx = (w-sw)//2
dy = (h-sh)//2
img = cv2.resize(img,(sw,sh))
for i in range(dy,sh-dy):
    for j in range(dx,sw-dx):
        dest[i,j] =  img[i,j]
cv2.imshow('dest',dest)
cv2.waitKey(0)

至此,我们的空间变换就告一段落了。广告时间,我有一个梦想,就是能在自己的博客中把自己喜欢的歌都推荐给大家。懂音乐的心灵都属于善良!
仁慈的父我已坠入 看不见罪的国度 请原谅我的自负
没人能说没人可说 好难承受 荣耀的背后刻着一道孤独
闭上双眼我又看见 当年那梦的画面 天空是蒙蒙的雾
父亲牵着我的双手 轻轻走过 清晨那安安静静的石板路《周杰伦-以父之名》
如果不满足,请期待下一篇——图像处理那点事儿之二美轮美奂

猜你喜欢

转载自blog.csdn.net/gaobing1993/article/details/108098934