【Computer Vision】图像数据预处理详解
活动地址:[CSDN21天学习挑战赛](https://marketing.csdn.net/p/bdabfb52c5d56532133df2adc1a728fd)
作者简介:在校大学生一枚,华为云享专家,阿里云星级博主,腾云先锋(TDP)成员,云曦智划项目总负责人,全国高等学校计算机教学与产业实践资源建设专家委员会(TIPCC)志愿者,以及编程爱好者,期待和大家一起学习,一起进步~
.
博客主页:ぃ灵彧が的学习日志
.
本文专栏:人工智能
.
专栏寄语:若你决定灿烂,山无遮,海无拦
.
文章目录
【Computer Vision】图像数据预处理详解前言什么是计算机视觉?什么是图像分类? 一、单通道、多通道图像读取(一)、单通道图像(二)、图像大小与像素值输出(三)、三通道图像读取(四)、使用cv2.split()分离颜色通道 二、图像的通道转换(一)、颜色空间转换(二)、图片属性 三、图像拼接与缩放(一)、图像分割(二)、图像拼接(三)、图像几何变换 四、图像二值化处理阈值分割 五、图像归一化处理总结
前言
什么是计算机视觉?
计算机视觉(Computer Vision)又称为机器视觉(Machine Vision),顾名思义就是要让计算机能够去“看”人类眼中的世界并进行理解和描述。
什么是图像分类?
图像分类是计算机视觉中为图像分配一个标签,其核心是向计算机输入一张图像,计算机能够从给定的分类集合中为图像分配一个标签。这里的标签来自预定义的可能类别集,例如,我们预定义类别集合categories={‘猫’,‘狗’,‘其他’},然后我们输入一张图片,计算机给出这副图片的类别标签‘猫’,或者给出这幅图片属于每个类别标签的概率{‘猫’:0.9,‘狗’:0.04,‘其他’:0.06},这样就完成了一个图像分类任务。
一、单通道、多通道图像读取
单通道图:俗称灰度图,每个像素点只能有有一个值表示颜色,它的像素值在0到255之间,0是黑色,255是白色,中间值是一些不同等级的灰色,如下图1所示:
三通道图每个像素点都有3个值表示 ,所以就是3通道。也有4通道的图。如下图2所示,例如RGB图片即为三通道图片,RGB色彩模式是工业界的一种颜色标准,是通过对红®、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。
(一)、单通道图像
引入依赖包%matplotlib inlineimport numpy as npimport cv2import matplotlib.pyplot as pltimport paddlefrom PIL import Image
读取单通道图像 img = Image.open('lena-gray.jpg')
展示图片 display(img)print(img)print(img.size)
运行结果如图3所示:
(二)、图像大小与像素值输出
将图片转为矩阵表示# 将图片转为矩阵表示img_np = np.array(img)print("图像尺寸:", img_np.shape)print("图像矩阵:\n", img_np)
将矩阵保存成文本,数字格式为整数 # 将矩阵保存成文本,数字格式为整数# np.savetxt('lena_gray.txt', np.array(img), fmt='%4d')np.savetxt('lena_gray.txt', img, fmt='%4d')
三通道图像 多通道读取方式与单通道一样,直接用Image.open()打开即可。
读取彩色图像img = Image.open('lena.jpg')# 将图片转为矩阵表示img_np = np.array(img)print("图像尺寸:", img_np.shape)print("图像矩阵:\n", img_np)
运行结果如下图4、5所示:
(三)、三通道图像读取
读取彩色图像# 使用PIL分离颜色通道r,g,b = img.split()
2.获取r通道转的灰度图
# 获取r通道转的灰度图print(r,'\n',g,'\n',b)print(type(r))
输出结果如下图6所示:
展示各通道图像# 获取第一个通道转的灰度图r = img.getchannel(0)# 获取第二个通道转的灰度图display(img.getchannel(1))# 获取b通道转的灰度图b# 获取第二个通道转的灰度图display(img.getchannel(2))# 将矩阵保存成文本,数字格式为整数np.savetxt('lena-r.txt', r, fmt='%4d')np.savetxt('lena-g.txt', g, fmt='%4d')np.savetxt('lena-b.txt', b, fmt='%4d')
获取到的R、G、B三个通道的图像展示如图7、8、9所示:
(四)、使用cv2.split()分离颜色通道
# 引入依赖包%matplotlib inlineimport cv2import matplotlib.pyplot as pltimg = cv2.imread('lena.jpg')# 通道分割b, g, r = cv2.split(img)# 通道合并RGB_Image=cv2.merge([b,g,r])RGB_Image = cv2.cvtColor(RGB_Image, cv2.COLOR_BGR2RGB)plt.figure(figsize=(12,12))#显示各通道信息plt.subplot(141)plt.imshow(RGB_Image,'gray')plt.title('RGB_Image')plt.subplot(142)plt.imshow(r,'gray')plt.title('R_Channel')plt.subplot(143)plt.imshow(g,'gray')plt.title('G_Channel')plt.subplot(144)plt.imshow(b,'gray')plt.title('B_Channel')
输出结果如图10所示:
二、图像的通道转换
(一)、颜色空间转换
最常用的颜色空间转换如下:
RGB或BGR到灰度(COLOR_RGB2GRAY,COLOR_BGR2GRAY)
RGB或BGR到YcrCb(或YCC)(COLOR_RGB2YCrCb,COLOR_BGR2YCrCb)
RGB或BGR到HSV(COLOR_RGB2HSV,COLOR_BGR2HSV)
RGB或BGR到Luv(COLOR_RGB2Luv,COLOR_BGR2Luv)
灰度到RGB或BGR(COLOR_GRAY2RGB,COLOR_GRAY2BGR)
颜色转换其实是数学运算,如灰度化最常用的是:gray=R0.299+G0.587+B*0.114。
BGR图像转换为灰度图像
img = cv2.imread('lena.jpg')# 转换为灰度图img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 保存灰度图cv2.imwrite('img_gray.jpg', img_gray)
GBR图像转换为RGB图像 # 加载彩色图img = cv2.imread('lena.jpg', 1)# 将彩色图的BGR通道顺序转成RGBimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 显示图片plt.imshow(img)#打印图片形状print(img.shape)
输出结果如下图11所示:
(二)、图片属性
打印图片形状:# 打印图片的形状print(img.shape)# 形状中包括行数、列数和通道数height, width, channels = img.shapeprint('图片高度:{},宽度:{},通道数:{}'.format(height,width,channels))
输出结果如下图12所示:
BGR转RGB# 加载灰度图img = cv2.imread('lena.jpg',1)# plt.imshow(img)# 将彩色图的BGR通道顺序转成RGBimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)plt.imshow(img)
输出结果如下图13所示:
加载彩色图# 加载彩色图img = cv2.imread('lena.jpg', 1)# 将彩色图的BGR通道直接转为灰度图img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)plt.imshow(img,'gray')img.shape
输出结果如下图14所示:
三、图像拼接与缩放
图像拼接,顾名思义就是将两张图片拼接在一起成为一张图像。本部分先将一张图片从中间切割成两张图片,然后再进行拼接。
(一)、图像分割
%matplotlib inlineimport numpy as npimport cv2import matplotlib.pyplot as plt path3 = 'test.jpg' img3 = cv2.imread(path3)# the image heightsum_rows = img3.shape[0]print(img3.shape)# print(sum_rows)# the image lengthsum_cols = img3.shape[1]# print(sum_cols)part1 = img3[0:sum_rows, 0:int(sum_cols/2)]print(part1.shape)part2 = img3[0:sum_rows, int(sum_cols/2):sum_cols]print(part2.shape)plt.figure(figsize=(12,12))#显示各通道信息plt.subplot(121)plt.imshow(part1)plt.title('Image1')plt.subplot(122)plt.imshow(part2)plt.title('Image2')
分隔后形成的图片如下图15所示:
(二)、图像拼接
img1 = part1img2 = part2# new imagefinal_matrix = np.zeros((254, 510, 3), np.uint8)# change final_matrix[0:254, 0:255] = img1final_matrix[0:254, 255:510] = img2 plt.subplot(111)plt.imshow(final_matrix)plt.title('final_img')
拼接后的图像展示如图16所示:
(三)、图像几何变换
实现旋转、平移和缩放图片
OpenCV函数:cv2.resize(), cv2.flip(), cv2.warpAffine()
缩放图片
缩放就是调整图片的大小,使用cv2.resize()函数实现缩放。可以按照比例缩放,也可以按照指定的大小缩放: 我们也可以指定缩放方法interpolation,更专业点叫插值方法,默认是INTER_LINEAR,全部可以参考:InterpolationFlags
缩放过程中有五种插值方式:
cv2.INTER_NEAREST 最近邻插值
cv2.INTER_LINEAR 线性插值
cv2.INTER_AREA 基于局部像素的重采样,区域插值
cv2.INTER_CUBIC 基于邻域4x4像素的三次插值
cv2.INTER_LANCZOS4 基于8x8像素邻域的Lanczos插值
转换为RGB格式
img = cv2.imread('cat.png')img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)print(img.shape)# 按照指定的宽度、高度缩放图片res = cv2.resize(img, (400, 500))plt.imshow(res)
输出结果如下图17所示:
图像缩放# 按照比例缩放,如x,y轴均放大一倍res2 = cv2.resize(img, None, fx=5, fy=2, interpolation=cv2.INTER_LINEAR)plt.imshow(res2)
缩放后效果如图18所示:
四、图像二值化处理
使用固定阈值、自适应阈值和Otsu阈值法"二值化"图像OpenCV函数:cv2.threshold()
, cv2.adaptiveThreshold()
阈值分割
固定阈值分割很直接,一句话说就是像素点值大于阈值变成一类值,小于阈值变成另一类值。
cv2.threshold()
用来实现阈值分割,ret是return value缩写,代表当前的阈值。函数有4个参数:
参考资料:基于opencv的固定阈值分割_自适应阈值分割
import cv2# 灰度图读入img = cv2.imread('lena.jpg', 0)# 颜色通道转换img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)ret, th = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)# 阈值分割plt.imshow(th)
输出结果如图19所示:
五、图像归一化处理
数据的标准化是指将数据按照比例缩放,使之落入一个特定的区间。将数据通过去均值,实现中心化。处理后的数据呈正态分布,即均值为零。
首先明确两个知识点:
知识点 01:均值(mean,average)【解释】
代表一组数据在分布上的集中趋势和总体上的平均水平;常说的中心化(Zero-Centered)或者零均值化(Mean-Subtraction),就是把每个数据都减去均值;
【公式】
知识点 02:标准差(Standard Deviation)【解释】
代表一组数据在分布上的离散程度;方差是标准差的平方【公式】
import numpy as npfrom PIL import Imagefrom paddle.vision.transforms import functional as Fimg = np.asarray(Image.open('lena.jpg'))mean = [0.31169346, 0.25506335, 0.12432463] std = [0.34042713, 0.29819837, 0.1375536]normalized_img = F.normalize(img, mean, std, data_format='HWC')normalized_img = Image.fromarray(np.uint8(normalized_img))plt.imshow(normalized_img)
输出结果如下图20所示:
总结
本系列文章内容为根据清华社出版的《机器学习实践》所作的相关笔记和感悟,其中代码均为基于百度飞桨开发,若有任何侵权和不妥之处,请私信于我,定积极配合处理,看到必回!!!
最后,引用本次活动的一句话,来作为文章的结语~( ̄▽ ̄~)~:
【学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。】
ps:更多精彩内容还请进入本文专栏:人工智能,进行查看,欢迎大家支持与指教啊~( ̄▽ ̄~)~