图像处理基础
Opencv介绍
计算机视觉处理开源软件库
由Intel公司俄罗斯团队发起并参与和维护的一个计算机视觉处理开源软件库,
在诸多方面都有着卓越的表现:
- 编程语言:多数模块基于C++实现,少部分基于C语言实现,同时提供了
Python、Ruby、MATLAB等语言的接口 - 跨平台:可自由地运行在Linux、Windows和Mac OS等桌面平台,Android、
IOS、BlackBerray等移动平台 - 活跃的开发团队:目前已更新至OpenCV4.0
- 丰富的API:完善的传统计算机视觉算法,涵盖主流机器学习算法,同时添加了
对深度学习的支持
现在的智能手机基本都有用到HDR,按下快门的一瞬间手机实际上从低曝光到高曝光拍了多张照片。 做到即看到前景的亮出,也可以看到背景的暗处
HDR也作为一种标准被视频采用。
自动图像拼接:全景图像拍摄
OpenCv模块介绍
OpenCV提供了许多内置的用于图像处理和计算机视觉相关操作的基础数据结构,它们都包含在core模块中
OpenCV包含的模块中,core、highgui、imgproc是最基础的模块
常用的OpenCV基本数据结构有以下几种:
-
Mat类:矩阵元素(可以与numpy的矩阵互通)
-
Point类:坐标点x和y
-
Size类:尺寸,width和height
-
Rect类:矩形的左上角坐标x和y以及宽width和高height
-
Scalar类:RGB通道和alpha通道
-
Vec类:向量,一维矩阵
-
Range类:用于指定一个连续的子序列
图像读取与保存
#载入Opencv库
import cv2
#图像读取
img = cv2.imread('sight.jpg')
#图片保存
cv2.imwrite('sight.jpg', img)
图像显示
#基本显示
from matplotlib import pyplot as plt
plt.imshow(img)
plt.show()
#调整图片大小 (仅为显示的大小,而不是图像本身的大小)
img1 = cv2.imread('cat.jpg')
plt.figure(figsize=(8, 6))
plt.imshow(img)
plt.show()
#设置坐标轴标签
plt.xlabel('x')
plt.ylabel('y')
#显示子图
plt.subplot(121) #前两位‘12’ 代表了1行2列 第三位‘1’表示子图的编号
plt.imshow(img1)
plt.subplot(122)
plt.imshow(img1)
plt.show()
#设置图标题
plt.title()
#设置坐标轴范围
plt.xlim(0, 1200)
plt.ylim(1200, 0)
# 显示色彩对照表
plt.colorbar()
# 显示风格设置
plt.style.use('seaborn-whitegrid')
图像格式转换
RGB颜色模型
-
三原色,肉眼可见的所有色彩均由这三种色彩混合叠加而成
-
RGB的颜色混合方式就好像有红(R)、绿(G)、蓝(B)三盏灯相互叠合的时候,色彩相混,而亮度却等于加和
ps:RGB与BGR唯一区别在于计算机计算颜色时哪个通道在前,RGB是(红,绿,蓝),BGR是(蓝,绿,红)。
- 红、绿、蓝三个颜色通道每种色各分为256阶亮度,在0时“灯”最弱—而在255时“灯”最亮
Oled 不是采用RGB连续排列的方式,而是采用批排列的方式,它显示的颜色会更加的艳丽。
HSV色彩模型
-
HSV是一种将RGB色彩空间中的点在倒圆锥体中表示的方法
-
HSV即色相、饱和度、明度
-
HSV颜色空间,更类似于人类感觉颜色的方式,封装了关于颜色的信息:“这是什么颜色?深浅如何?明暗如何?”
其他模型
HSL与HSV色彩模型
HSV色彩模型(Hue 色相, Saturation 饱和度,Value 明度)
HSL色彩模型(Hue 色相, Saturation 饱和度,Lightness 亮度)
两者的意义大体一样,只是在饱和度,亮度的取值轴有不同的意义
YCrCb即YUV
与RGB视频信号传输相比,它最大的优点在于只需占用极少的频宽
其中“Y”表示明亮度,而“U”和“V” 表示的则是色度,作用是描述影像色彩及饱和度,用于指定像素的颜色
灰度图
任何颜色都有红、绿、蓝三原色组成,若某点的颜色为RGB(R,G,B),通过下面几种方法,可将其转换为灰度:
1.浮点算法:Gray=R0.3+G0.59+B0.11
2.整数方法:Gray=(R30+G59+B11)/100
3.移位方法:Gray =(R76+G151+B*28)>>8
4.平均值法:Gray=(R+G+B)/3
5.仅取绿色:Gray=G
通过上述任一种方法求得Gray后,将原来的RGB(R,G,B)中的R,G,B统一用Gray替换,形成新的颜色RGB(Gray,Gray,Gray),替换原来的RGB(R,G,B),就得到灰度图了(这样可以使得灰度图得以显示)
灰度图舍弃了很多其它信息,保留了关键的梯度信息,在很多机器学习任务里有重要应用
# BGR转为灰度图
cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# RGB转为BGR
cv2.cvtColor(img,cv2.COLOR_RGB2BGR)
# RGB转为HSV
cv2.cvtColor(img,cv2.COLOR_RGB2HSV)
# BGR转为HLS
cv2.cvtColor(img,cv2.COLOR_RGB2HLS)
# BGR转为YCrCb
cv2.cvtColor(img,cv2.COLOR_RGB2YCrCb)
图像的缩放与翻转
#图像缩放
cv2.resize(img, dsize=(800, 600))
在numpy中 (行数,列数),这个resize里面的为(列数,行数)
#图像翻转
cv2.flip(img, flipCode=0)
cv2.flip(img, flipCode=1)
cv2.flip(img, flipCode=-1)
# 通道拆分
由于OpenCV读取图片默认使用通道顺序为BGR,因此在通道拆分时的顺序为B,G,R
rgb = cv2.imread('RGB.png')
B, G, R = cv2.split(rgb)
# 通道重组
而Matplotlib的默认通道顺序为RGB,因此在重组时画图时按R,G,B的顺序即可
plt.imshow(cv2.merge([R, G, B]))
# 图像旋转
这里涉及到图像放射变换的知识,解析几何里面有,课后补充
M = cv2.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),45,0.75)
dst = cv2.warpAffine(rgb,M,(cols,rows))
plt.imshow(dst)
wardAffine()放射变换
作业:
# 导入必要的库
import cv2
import matplotlib.pyplot as plt
import pandas as pd
# 获取图片尺寸
size = img.shape
cols = size[0]
rows = size[1]
# 创建大小为(10, 10)的图形,返回Figure对象img_new
img_new = plt.figure(figsize = (10, 10))
M = cv2.getRotationMatrix2D(((cols-1)/2.0, (rows-1)/2.0), 45, 0.5)
fig = cv2.warpAffine(img, M, (cols, rows))
# 图像缩放
plt.imshow(cv2.cvtColor(cv2.resize(fig, dsize = (1000, 800)), cv2.COLOR_BGR2RGB))
# 设置横轴标签
plt.xlabel('Length',fontsize=15)
# 设置纵轴标签
plt.ylabel('Width',fontsize=15)
# 设置图标题
plt.title('Dog',fontsize=20)
直方图均衡化
图像处理领域中利用图像直方图对对比度进行调整的方法
把原始图的直方图变换为均匀分布的形式,从而增加了像素灰度值的动态范围,达到增强图像整体对比度的效果
彩色图像直方图均衡化
B, G, R = cv2.split(rgb)
R2 = cv2.equalizeHist(R)
G2 = cv2.equalizeHist(G)
B2 = cv2.equalizeHist(B)
plt.imshow(cv2.merge([R2, G2, B2]))
边缘检测
- 边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点
- 有许多用于边缘检测的方法, 他们大致可分为两类:基于搜索和基于零交叉
- 基于搜索的边缘检测方法首先计算边缘强度, 通常用一阶导数表示,然后计算估计边缘的局部方向,通常采用梯度的方向,并利用此方向找到局部梯度模的最大值
- 基于零交叉的方法找到由图像得到的二阶导数的零交叉点来定位边缘,通常用拉普拉斯算子或非线性微分方程的零交叉点
有助于我们理解深度学习里面的卷积操作,边缘检测就是在利用卷积核去提取图像的边缘信息。
标识数字图像中亮度变化明显的点
cv2.Canny(image, threshold1, threshold2)
参数说明:image:像素矩阵
threshold1 threshold2:阈值1和阈值2,用于进一步筛选边缘信息
作业2
# 导入必要的库
import cv2
import matplotlib.pyplot as plt
# 创建大小为(10, 8)的图形,返回Figure对象img_new
img_new = plt.figure(figsize = (10, 8))
plt.title('Panda',fontsize=15)
plt.xticks([])
plt.yticks([])
B,G,R = cv2.split(img)
R2 = cv2.equalizeHist(R)
G2 = cv2.equalizeHist(G)
B2 = cv2.equalizeHist(B)
plt.imshow(cv2.merge([R2, G2, B2]))