通信系统仿真

崔春雷

目录

  • 1 第一单元: MATLAB基础
    • 1.1 课程说明与资料
      • 1.1.1 作业参考答案
      • 1.1.2 移动22级作业答案
    • 1.2 MATLAB安装与运行环境
      • 1.2.1 MATLAB介绍
    • 1.3 基本数据类型:数值类型
    • 1.4 基本数据类型:字符类型
    • 1.5 数据类型转换与输出
    • 1.6 数组与矩阵基础
      • 1.6.1 矩阵运算进阶
    • 1.7 数组与矩阵常用函数
    • 1.8 matlab中的逻辑运算
    • 1.9 实验: MATLAB常用数学函数
      • 1.9.1 实验 作业答案
    • 1.10 元胞数组
    • 1.11 结构体数组
      • 1.11.1 结构体进阶
      • 1.11.2 元胞数组与结构体数组对比
      • 1.11.3 map 容器
    • 1.12 附录:MATLAB常用基础命令
    • 1.13 拓展内容:实时脚本
      • 1.13.1 实时脚本示例
    • 1.14 课程作业与答案
      • 1.14.1 《通信系统仿真》期末考试
  • 2 第二单元:Matlab 程序设计
    • 2.1 顺序结构程序
    • 2.2 分支结构—— if语句
    • 2.3 分支结构—— switch语句
    • 2.4 循环结构—— while语句
    • 2.5 循环结构—— for语句
    • 2.6 图像处理基础
    • 2.7 Matlab的函数
      • 2.7.1 函数内容的课外扩展
    • 2.8 本章实验:for循环的应用
      • 2.8.1 素数问题
        • 2.8.1.1 素数的螺旋线排列
      • 2.8.2 3X+1猜想
      • 2.8.3 7 行代码计算 π
    • 2.9 排序算法
      • 2.9.1 冒泡排序
      • 2.9.2 选择排序
      • 2.9.3 插入排序
      • 2.9.4 快速排序
      • 2.9.5 基数排序
      • 2.9.6 计数排序
      • 2.9.7 堆排序
    • 2.10 动态规划算法
      • 2.10.1 动态规划编程实例
      • 2.10.2 动态规划:01背包问题
      • 2.10.3 动态规划常见题目分析
      • 2.10.4 动态规划题目分析2
    • 2.11 常用算法简介
      • 2.11.1 剪枝算法
      • 2.11.2 二分查找
      • 2.11.3 递归算法
      • 2.11.4 回溯算法
        • 2.11.4.1 Leetcode回溯题目合集
        • 2.11.4.2 回溯算法总结
        • 2.11.4.3 回溯法解数独问题
        • 2.11.4.4 DFS与BFS
          • 2.11.4.4.1 DFS/BFS原理
          • 2.11.4.4.2 BFS的应用:Dijkstra算法
      • 2.11.5 n 皇后问题专题
      • 2.11.6 双指针算法
      • 2.11.7 数组模拟链表(约瑟夫环)
      • 2.11.8 Hash(哈希表)
      • 2.11.9 图论与路径规划
        • 2.11.9.1 迪杰斯特拉算法
        • 2.11.9.2 A*算法
          • 2.11.9.2.1 A*算法的MATLAB实现
        • 2.11.9.3 RRT路径规划算法
          • 2.11.9.3.1 RRT算法 MATLAB代码
          • 2.11.9.3.2 参考资料
      • 2.11.10 数据结构
        • 2.11.10.1 数据结构例题
      • 2.11.11 前缀和 差分 双指针
      • 2.11.12 位运算
      • 2.11.13 常用算法代码模板
    • 2.12 练习题库
    • 2.13 code
      • 2.13.1 简易计算器gui代码
      • 2.13.2 五子棋
      • 2.13.3 连连看小游戏
      • 2.13.4 递归算法与汉诺塔
      • 2.13.5 有理数的小数循环节
    • 2.14 MATLAB编程风格
      • 2.14.1 向量化编程专题
  • 3 第三单元:Matlab 图形图像处理
    • 3.1 二维图形绘图基础
    • 3.2 二维图形绘图进阶
    • 3.3 三维图形绘图
      • 3.3.1 MATLAB绘图小结
        • 3.3.1.1 用matlab绘制好看图像
    • 3.4 MATLAB高级绘图
    • 3.5 文件操作
    • 3.6 Matlab图像处理进阶
      • 3.6.1 补充:Matlab图像处理常用函数
      • 3.6.2 RGB/HSV/HSI颜色模型
      • 3.6.3 图片切换动画效果
      • 3.6.4 图像连通域标记
      • 3.6.5 图像旋转与插值
      • 3.6.6 图像的形态学
      • 3.6.7 空间滤波
        • 3.6.7.1 图像中常见的噪声类型与滤波方法
        • 3.6.7.2 matlab中的滤波函数
        • 3.6.7.3 BM3D 去噪算法
        • 3.6.7.4 双边滤波
      • 3.6.8 图像的频域处理
    • 3.7 本章总结
    • 3.8 实验 : matlab 绘图练习1
    • 3.9 实验: matlab 绘图练习2
    • 3.10 实验 :数学函数图像绘制
    • 3.11 实验:绘图综合练习
    • 3.12 实验:曲线拟合
    • 3.13 实验:牛顿法求解方程的根
    • 3.14 实验:信号的傅里叶变换
      • 3.14.1 傅里叶变换、小波变换、希尔伯特变换
      • 3.14.2 新建目录
    • 3.15 课外补充:图像处理基础1
    • 3.16 课外补充:图像处理基础2
    • 3.17 课外补充:图像处理基础3
    • 3.18 课外补充:PYTHON基础
  • 4 第五单元:MATLAB通信仿真
    • 4.1 现代通信系统的介绍
    • 4.2 模拟通信系统的仿真原理
    • 4.3 HDB3编解码的仿真实现
    • 4.4 SIMULINK和其模块简介
    • 4.5 数字通信系统的仿真原理
    • 4.6 模拟通信系统Simulink仿真
    • 4.7 数字通信系统Simulink仿真
    • 4.8 音频信号测处理与仿真
    • 4.9 图像数字水印技术
      • 4.9.1 三角函数到傅里叶变换再到语音识别与数字水印
    • 4.10 信息系统与算法
      • 4.10.1 递归算法
        • 4.10.1.1 递归与堆栈的关系
      • 4.10.2 哈希表
      • 4.10.3 双指针算法
        • 4.10.3.1 双指针算法实战
        • 4.10.3.2 双指针进阶:滑动窗口算法
      • 4.10.4 字符串匹配 KMP算法
        • 4.10.4.1 字符串匹配B-M算法
      • 4.10.5 快速傅里叶变换
      • 4.10.6 回溯算法
      • 4.10.7 动态规划
      • 4.10.8 分治算法
      • 4.10.9 Dijkstra算法
  • 5 第六单元: systemview通信仿真
    • 5.1 SystemView概述
    • 5.2 模拟通信系统 数字系统的仿真分析
    • 5.3 SystemView通信系统仿真进阶
    • 5.4 新建课程目录
  • 6 第四单元:MATLAB高级应用
    • 6.1 符号运算基础
      • 6.1.1 利用Matlab自动推导公式
    • 6.2 Matlab中的数值计算
      • 6.2.1 积分的计算
      • 6.2.2 龙格库塔:常微分方程的数值解法
      • 6.2.3 fmincon函数与非线性方程最小值
    • 6.3 统计、拟合、插值
      • 6.3.1 协方差与相关系数
    • 6.4 GUI设计初步
    • 6.5 matlab GUI界面编程
      • 6.5.1 gui实例
      • 6.5.2 gui编程中常用函数
      • 6.5.3 App Designer入门
    • 6.6 实验:GUI设计图像空间变换系统
    • 6.7 作业:利用GUI设计 计算器、信号发生器等
    • 6.8 MTALB数据导入方法
    • 6.9 课外补充:MATLAB的App会取代GUI吗?
    • 6.10 模拟退火算法matlab实现
    • 6.11 遗传算法的Matlab实现
      • 6.11.1 进化算法(Evolutionary Algorithm)及相关函数介绍
    • 6.12 粒子群算法 matlab实现
      • 6.12.1 粒子群算法及MATLAB实例仿真
    • 6.13 BP网络的应用
    • 6.14 matlab 结构体
    • 6.15 群智能算法合集
  • 7 拓展知识
    • 7.1 什么是算法的时间复杂度?
    • 7.2 Notepad++使用教程
    • 7.3 MATLAB常用函数总结
    • 7.4 MATLAB常用知识点总结
    • 7.5 MATLAB命令大全
    • 7.6 视频:MATLAB官方基础教程
    • 7.7 经典书籍:Matlab2012经典超强教程
    • 7.8 经典书籍:MATLAB揭秘(自学宝典)
    • 7.9 经典资料:MATLAB N个实用技巧
    • 7.10 Matlab编程小技巧
    • 7.11 寻优算法
      • 7.11.1 Dijkstra算法python实现
    • 7.12 PYTHON基础教程
      • 7.12.1 Python进阶
      • 7.12.2 Python小技巧
      • 7.12.3 Python总结
        • 7.12.3.1 Python循环语句总结
        • 7.12.3.2 24个顶级Python库
        • 7.12.3.3 魔法函数
      • 7.12.4 廖雪峰python
      • 7.12.5 正则表达式基础
      • 7.12.6 numpy
        • 7.12.6.1 101道Numpy习题
        • 7.12.6.2 Numpy简要语法教程
        • 7.12.6.3 Numpy实现全连接神经网络 (手写数字识别)
        • 7.12.6.4 图解NumPy
      • 7.12.7 matplotlib
        • 7.12.7.1 matplotlib练习50题
        • 7.12.7.2 Matplotlib速查表
        • 7.12.7.3 Matplotlib 实操指南
      • 7.12.8 Python3 模块 import
      • 7.12.9 Python 小项目
    • 7.13 参考资源:数据结构与算法
      • 7.13.1 十大经典排序算法总结
    • 7.14 机器学习概述
      • 7.14.1 反向传播算法
        • 7.14.1.1 反向传播的数学原理
      • 7.14.2 极大似然估计
        • 7.14.2.1 极大似然估计与最小二乘法
      • 7.14.3 Batch Normalization
        • 7.14.3.1 Batch Normalization&Dropout浅析
        • 7.14.3.2 ​BN层的梯度反向传播计算
        • 7.14.3.3 Batch Size的大小与神经网络的性能
        • 7.14.3.4 标准化和归一化
      • 7.14.4 主成分分析PCA与SVD奇异值分解
        • 7.14.4.1 岭回归 与 PCA
        • 7.14.4.2 PCA原理推导
        • 7.14.4.3 PCA原理新解
        • 7.14.4.4 svd
        • 7.14.4.5 PCA数学原理
      • 7.14.5 正则化
        • 7.14.5.1 L1、L2正则化和过拟合 总结
        • 7.14.5.2 L1 和 L2 正则化的直观解释
      • 7.14.6 SVM
        • 7.14.6.1 从零推导支持向量机(SVM)
        • 7.14.6.2 支持向量机(SVM)介绍
        • 7.14.6.3 SVM推导与实战
        • 7.14.6.4 支持向量机的直观理解
        • 7.14.6.5 浅显易懂的支持向量机SVM
      • 7.14.7 线性回归
      • 7.14.8 逻辑回归
      • 7.14.9 BP算法
        • 7.14.9.1 万能逼近——神经网络拟合任意函数原理
      • 7.14.10 激活与池化
        • 7.14.10.1 激活函数与损失函数 小结
      • 7.14.11 深度学习简述
        • 7.14.11.1 MATLAB2020深度学习实例
      • 7.14.12 损失函数与误差反向传播
        • 7.14.12.1 梯度下降与损失函数
      • 7.14.13 深度学习优化问题
      • 7.14.14 梯度下降法
        • 7.14.14.1 各类梯度下降算法的Python实现
        • 7.14.14.2 梯度下降的直观理解
        • 7.14.14.3 动量、RMSProp、Adam
      • 7.14.15 卷积的概念
        • 7.14.15.1 卷积的矩阵化算法
      • 7.14.16 局部连接
      • 7.14.17 RNN
      • 7.14.18 LSTM
      • 7.14.19 CNN-四大经典CNN技术浅析
      • 7.14.20 熵(Entropy)与交叉熵
      • 7.14.21 softmax函数详解
      • 7.14.22 自编码算法详细理解与代码实现
      • 7.14.23 pytorch
        • 7.14.23.1 ​PyTorch简介
          • 7.14.23.1.1 Pytorch快速入门资料
        • 7.14.23.2 CNN的PyTorch实现
        • 7.14.23.3 pytorch总结
        • 7.14.23.4 PyTorch trick 集锦
        • 7.14.23.5 在PyTorch上加载自定义数据集
        • 7.14.23.6 实战:Pytorch识别验证码
        • 7.14.23.7 实战:Transformer的最简洁pytorch实现
        • 7.14.23.8 使用PyTorch实现神经网络分类
      • 7.14.24 卷积神经网络CNN概述
        • 7.14.24.1 CNN 简易原理
        • 7.14.24.2 卷积神经网络CNN原理详解
        • 7.14.24.3 自己手写一个卷积神经网络
        • 7.14.24.4 CNN反向传播算法
        • 7.14.24.5 卷积计算、作用与思想
        • 7.14.24.6 用卷积神经网络CNN识别手写数字集
        • 7.14.24.7 卷积 池化 参数的计算
        • 7.14.24.8 im2col方法实现卷积算法
        • 7.14.24.9 卷积核的梯度计算
        • 7.14.24.10 卷积层反向传播推导及实现
        • 7.14.24.11 反向传输算法
          • 7.14.24.11.1 resnet残差网络
        • 7.14.24.12 CNN反向传播的MATLAB实现
      • 7.14.25 神经网络的调参技巧
      • 7.14.26 BP神经网络
        • 7.14.26.1 零开始搭建bp神经网络
        • 7.14.26.2 MATLAB自带的bp工具箱
        • 7.14.26.3 神经网络中偏置(bias)的作用
      • 7.14.27 聚类分析 k-means
        • 7.14.27.1 matlab做聚类分析(k-means)
        • 7.14.27.2 聚类模型探讨综述
        • 7.14.27.3 5种经典聚类算法
      • 7.14.28 深度学习的一些概念
      • 7.14.29 人工智能简述:AI的过去和现在
      • 7.14.30 k-NN(k近邻算法)
      • 7.14.31 神经网络中的优化器:BGD、SGD、MBGD、Momentum
      • 7.14.32 卷积神经网络的经典网络总结
        • 7.14.32.1 卷积神经网络中十大拍案叫绝的操作
      • 7.14.33 GAN 对抗样本攻击
      • 7.14.34 蒙特卡洛模拟
      • 7.14.35 dropout与随机部分连接
      • 7.14.36 Jupyter 等 IDE概览
      • 7.14.37 分类算法常用评价指标
      • 7.14.38 Inception 网络与不变性
      • 7.14.39 卷积神经网络的可视化
      • 7.14.40 隐马尔可夫模型HMM
        • 7.14.40.1 马尔科夫链
    • 7.15 MATLAB音频处理
      • 7.15.1 python处理音频信号
    • 7.16 图像处理
      • 7.16.1 图像处理中的指标
    • 7.17 代码集
    • 7.18 论文写作与阅读方法
      • 7.18.1 期刊投稿攻略
      • 7.18.2 论文排版教程
      • 7.18.3 SCI-HUB论文下载技巧
      • 7.18.4 几种论文写作神器,提高写作效率
      • 7.18.5 latex入门
      • 7.18.6 LaTeX教程
    • 7.19 机器学习常用的网站以及资源
      • 7.19.1 很详细的ML&DL学习博客
    • 7.20 SymPy 符号计算基本教程
  • 8 程序设计数学基础
    • 8.1 编程数学基础
      • 8.1.1 概率的历史
      • 8.1.2 概率
        • 8.1.2.1 常见概率分布
          • 8.1.2.1.1 二维正态分布
        • 8.1.2.2 蒙特卡罗方法
        • 8.1.2.3 置信区间
        • 8.1.2.4 协方差与相关系数
      • 8.1.3 矩阵 向量求导法则
      • 8.1.4 雅可比矩阵 海森矩阵
      • 8.1.5 矩阵的几种分解方式
      • 8.1.6 行列式和代数余子式
      • 8.1.7 向量
      • 8.1.8 矩阵的基本运算
      • 8.1.9 矩阵分析
      • 8.1.10 矩阵的LU分解
      • 8.1.11 矩阵奇异值分解(SVD)
        • 8.1.11.1 SVD分解2
        • 8.1.11.2 SVD分解逐步推导
        • 8.1.11.3 奇异值与特征值的意义
      • 8.1.12 随机向量
        • 8.1.12.1 随机过程简述
      • 8.1.13 投影矩阵和最小二乘
      • 8.1.14 知乎数学精选集
        • 8.1.14.1 高数问题集
      • 8.1.15 小波变换
      • 8.1.16 程序设计数学基础1:高等数学
      • 8.1.17 程序设计数学基础2:线性代数
      • 8.1.18 程序设计数学基础3:概率论和数理统计
      • 8.1.19 向量的距离与相似度计算
      • 8.1.20 复数
      • 8.1.21 高等数学——幂级数
      • 8.1.22 无穷小的本质
      • 8.1.23 数列极限和收敛性
      • 8.1.24 不定积分技巧总结
    • 8.2 有趣的数学题目
    • 8.3 高等数学
      • 8.3.1 泰勒级数
  • 9 路径规划与智能算法
    • 9.1 常见路径规划算法简介
    • 9.2 Dijkstra算法详细
  • 10 教学文档
    • 10.1 授课计划
    • 10.2 课程标准
课外补充:图像处理基础1

                        python图片处理技术



用python简单处理图片(1):打开\显示\保存图像

一提到数字图像处理,可能大多数人就会想到matlab,但matlab也有自身的缺点:

1、不开源,价格贵

2、软件容量大。一般3G以上,高版本甚至达5G以上。

3、只能做研究,不易转化成软件。

因此,我们这里使用python这个脚本语言来进行数字图像处理。

要使用python,必须先安装python,一般是2.7版本以上,不管是在windows系统,还是linux系统,安装都是非常简单的。

要使用python进行各种开发,就必须安装对应的库。这和matlab非常相似,只是matlab里面叫工具箱(toolbox),而python里面叫库或包。安装这些库,一般都是使用pip来安装。

使用python进行数字图片处理,还得安装Pillow包。虽然python里面自带一个PIL(python images library), 但这个库现在已经停止更新了,所以使用Pillow, 它是由PIL发展而来的。

pip install Pillow

一、图片的打开与显示

from PIL import Image
img=Image.open('d:/dog.png')
img.show()

虽然使用的是Pillow,但它是由PIL fork而来,因此还是要从PIL中进行import. 使用open()函数来打开图片,使用show()函数来显示图片。

这种图片显示方式是调用操作系统自带的图片浏览器来打开图片,有些时候这种方式不太方便,因此我们也可以使用另上一种方式,让程序来绘制图片。

from PIL import Image
import matplotlib.pyplot as plt
img=Image.open('d:/dog.png')
plt.figure("dog")
plt.imshow(img)
plt.show()

这种方法虽然复杂了些,但推荐使用这种方法,它使用一个matplotlib的库来绘制图片进行显示。matplotlib是一个专业绘图的库,相当于matlab中的plot,可以设置多个figure,设置figure的标题,甚至可以使用subplot在一个figure中显示多张图片。matplotlib 可以直接安装

pip install matplotlib

figure默认是带axis的,如果没有需要,我们可以关掉

plt.axis('off')

打开图片后,可以使用一些属性来查看图片信息,如

print img.size  #图片的尺寸
print img.mode  #图片的模式
print img.format  #图片的格式

显示结果为:

(558, 450)
RGBA
PNG

二、图片的保存

img.save('d:/dog.jpg')

就一行代码,非常简单。这行代码不仅能保存图片,还是转换格式,如本例中,就由原来的png图片保存为了jpg图片。





python数字图像处理(2):图像的读取、显示与保存

skimage提供了io模块,顾名思义,这个模块是用来图片输入输出操作的。为了方便练习,也提供一个data模块,里面嵌套了一些示例图片,我们可以直接使用。

引入skimage模块可用:

1
from skimage import io

一、从外部读取图片并显示

读取单张彩色rgb图片,使用skimage.io.imread(fname)函数,带一个参数,表示需要读取的文件路径。显示图片使用skimage.io.imshow(arr)函数,带一个参数,表示需要显示的arr数组(读取的图片以numpy数组形式计算)。

from skimage import io
img=io.imread('d:/dog.jpg')
io.imshow(img)

读取单张灰度图片,使用skimage.io.imread(fname,as_grey=True)函数,第一个参数为图片路径,第二个参数为as_grey, bool型值,默认为False

from skimage import io
img=io.imread('d:/dog.jpg',as_grey=True)
io.imshow(img)

二、程序自带图片

skimage程序自带了一些示例图片,如果我们不想从外部读取图片,就可以直接使用这些示例图片:

astronaut

宇航员图片

coffee

一杯咖啡图片

lena

lena美女图片

camera

拿相机的人图片

coins

硬币图片

moon

月亮图片

checkerboard

棋盘图片

horse

马图片

page

书页图片

chelsea

小猫图片

hubble_deep_field

星空图片

text

文字图片

clock

 时钟图片

immunohistochemistry

结肠图片

显示这些图片可用如下代码,不带任何参数

from skimage import io,data
img=data.lena()
io.imshow(img)

图片名对应的就是函数名,如camera图片对应的函数名为camera(). 这些示例图片存放在skimage的安装目录下面,路径名称为data_dir,我们可以将这个路径打印出来看看:

from skimage import data_dir
print(data_dir)

显示为: D:\Anaconda3\lib\site-packages\skimage\data

也就是说,下面两行读取图片的代码效果是一样的:

from skimage import data_dir,data,io
img1=data.lena()  #读取lean图片
img2=io.imread(data_dir+'/lena.png')  #读取lena图片

 

三、保存图片

使用io模块的imsave(fname,arr)函数来实现。第一个参数表示保存的路径和名称,第二个参数表示需要保存的数组变量。

from skimage import io,data
img=data.chelsea()
io.imshow(img)
io.imsave('d:/cat.jpg',img)

保存图片的同时也起到了转换格式的作用。如果读取时图片格式为jpg图片,保存为png格式,则将图片从jpg图片转换为png图片并保存。

 

四、图片信息

如果我们想知道一些图片信息,可以在spyder编辑器的右上角显示:

也可以直接以程序方式打印输出

复制代码

from skimage import io,data
img=data.chelsea()
io.imshow(img)
print(type(img))  #显示类型
print(img.shape)  #显示尺寸
print(img.shape[0])  #图片宽度
print(img.shape[1])  #图片高度
print(img.shape[2])  #图片通道数
print(img.size)   #显示总像素个数
print(img.max())  #最大像素值
print(img.min())  #最小像素值
print(img.mean()) #像素平均值

复制代码

结果输出:

<class 'numpy.ndarray'>
(300, 451, 3)
300
451
3
405900
231
0
115.305141661


用python简单处理图片(2):图像通道\几何变换\裁剪

一、图像通道

1、彩色图像转灰度图

复制代码

from PIL import Image
import matplotlib.pyplot as plt
img=Image.open('d:/ex.jpg')
gray=img.convert('L')
plt.figure("beauty")
plt.imshow(gray,cmap='gray')
plt.axis('off')
plt.show()

复制代码

使用函数convert()来进行转换,它是图像实例对象的一个方法,接受一个 mode 参数,用以指定一种色彩模式,mode 的取值可以是如下几种:

· 1 (1-bit pixels, black and white, stored with one pixel per byte)

· L (8-bit pixels, black and white)

· P (8-bit pixels, mapped to any other mode using a colour palette)

· RGB (3x8-bit pixels, true colour)

· RGBA (4x8-bit pixels, true colour with transparency mask)

· CMYK (4x8-bit pixels, colour separation)

· YCbCr (3x8-bit pixels, colour video format)

· I (32-bit signed integer pixels)

· F (32-bit floating point pixels)

2、通道分离与合并

复制代码

from PIL import Image
import matplotlib.pyplot as plt
img=Image.open('d:/ex.jpg')  #打开图像
gray=img.convert('L')   #转换成灰度
r,g,b=img.split()   #分离三通道
pic=Image.merge('RGB',(r,g,b)) #合并三通道
plt.figure("beauty")
plt.subplot(2,3,1), plt.title('origin')
plt.imshow(img),plt.axis('off')
plt.subplot(2,3,2), plt.title('gray')
plt.imshow(gray,cmap='gray'),plt.axis('off')
plt.subplot(2,3,3), plt.title('merge')
plt.imshow(pic),plt.axis('off')
plt.subplot(2,3,4), plt.title('r')
plt.imshow(r,cmap='gray'),plt.axis('off')
plt.subplot(2,3,5), plt.title('g')
plt.imshow(g,cmap='gray'),plt.axis('off')
plt.subplot(2,3,6), plt.title('b')
plt.imshow(b,cmap='gray'),plt.axis('off')
plt.show()

复制代码

二、裁剪图片

从原图片中裁剪感兴趣区域(roi),裁剪区域由4-tuple决定,该tuple中信息为(left, upper, right, lower)。 Pillow左边系统的原点(0,0)为图片的左上角。坐标中的数字单位为像素点。

复制代码

from PIL import Image
import matplotlib.pyplot as plt
img=Image.open('d:/ex.jpg')  #打开图像
plt.figure("beauty")
plt.subplot(1,2,1), plt.title('origin')
plt.imshow(img),plt.axis('off')

box=(80,100,260,300)
roi=img.crop(box)
plt.subplot(1,2,2), plt.title('roi')
plt.imshow(roi),plt.axis('off')
plt.show()

复制代码

用plot绘制显示出图片后,将鼠标移动到图片上,会在右下角出现当前点的坐标,以及像素值。

三、几何变换 

Image类有resize()、rotate()和transpose()方法进行几何变换。

 1、图像的缩放和旋转

dst = img.resize((128, 128))
dst = img.rotate(45) # 顺时针角度表示
2、转换图像
dst = im.transpose(Image.FLIP_LEFT_RIGHT) #左右互换
dst = im.transpose(Image.FLIP_TOP_BOTTOM) #上下互换
dst = im.transpose(Image.ROTATE_90)  #顺时针旋转
dst = im.transpose(Image.ROTATE_180)
dst = im.transpose(Image.ROTATE_270)
transpose()和rotate()没有性能差别。


python数字图像处理(3):图像像素的访问与裁剪

图片读入程序中后,是以numpy数组存在的。因此对numpy数组的一切功能,对图片也适用。对数组元素的访问,实际上就是对图片像素点的访问。

彩色图片访问方式为:

img[i,j,c]

i表示图片的行数,j表示图片的列数,c表示图片的通道数(RGB三通道分别对应0,1,2)。坐标是从左上角开始。

灰度图片访问方式为:

gray[i,j]

例1:输出小猫图片的G通道中的第20行30列的像素值

from skimage import io,data
img=data.chelsea()
pixel=img[20,30,1]
print(pixel)

输出为129

例2:显示红色单通道图片

from skimage import io,data
img=data.chelsea()
R=img[:,:,0]
io.imshow(R)

除了对像素进行读取,也可以修改像素值。

例3:对小猫图片随机添加椒盐噪声

复制代码

from skimage import io,data
import numpy as np
img=data.chelsea()

#随机生成5000个椒盐
rows,cols,dims=img.shape
for i in range(5000):
    x=np.random.randint(0,rows)
    y=np.random.randint(0,cols)
    img[x,y,:]=255
    
io.imshow(img)

复制代码

这里用到了numpy包里的random来生成随机数,randint(0,cols)表示随机生成一个整数,范围在0到cols之间。

用img[x,y,:]=255这句来对像素值进行修改,将原来的三通道像素值,变为255

 

通过对数组的裁剪,就可以实现对图片的裁剪。

例4:对小猫图片进行裁剪

from skimage import io,data
img=data.chelsea()
roi=img[80:180,100:200,:]
io.imshow(roi)

对多个像素点进行操作,使用数组切片方式访问。切片方式返回的是以指定间隔下标访问 该数组的像素值。下面是有关灰度图像的一些例子:

复制代码

img[i,:] = im[j,:] # 将第 j 行的数值赋值给第 i 行

img[:,i] = 100 # 将第 i 列的所有数值设为 100

img[:100,:50].sum() # 计算前 100 行、前 50 列所有数值的和

img[50:100,50:100] # 50~100 行,50~100 列(不包括第 100 行和第 100 列)

img[i].mean() # 第 i 行所有数值的平均值

img[:,-1] # 最后一列

img[-2,:] (or im[-2]) # 倒数第二行

复制代码

最后我们再看两个对像素值进行访问和改变的例子:

例5:将lena图片进行二值化,像素值大于128的变为1,否则变为0

复制代码

from skimage import io,data,color
img=data.lena()
img_gray=color.rgb2gray(img)
rows,cols=img_gray.shape
for i in range(rows):
    for j in range(cols):
        if (img_gray[i,j]<=0.5):
            img_gray[i,j]=0
        else:
            img_gray[i,j]=1
io.imshow(img_gray)

复制代码

这个例子,使用了color模块的rgb2gray()函数,将彩色三通道图片转换成灰度图。转换结果为float64类型的数组,范围为[0,1]之间。

 例6:

from skimage import io,data
img=data.chelsea()
reddish = img[:, :, 0] >170
img[reddish] = [0, 255, 0]
io.imshow(img)

这个例子先对R通道的所有像素值进行判断,如果大于170,则将这个地方的像素值变为[0,255,0], 即G通道值为255,R和B通道值为0。

用python简单处理图片(4):图像中的像素访问

前面的一些例子中,我们都是利用Image.open()来打开一幅图像,然后直接对这个PIL对象进行操作。如果只是简单的操作还可以,但是如果操作稍微复杂一些,就比较吃力了。因此,通常我们加载完图片后,都是把图片转换成矩阵来进行更加复杂的操作。

python中利用numpy库和scipy库来进行各种数据操作和科学计算。我们可以通过pip来直接安装这两个库

pip install numpy
pip install scipy

以后,只要是在python中进行数字图像处理,我们都需要导入这些包:

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

打开图像并转化为矩阵,并显示:

复制代码

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img=np.array(Image.open('d:/lena.jpg'))  #打开图像并转化为数字矩阵
plt.figure("dog")
plt.imshow(img)
plt.axis('off')
plt.show()

复制代码

调用numpy中的array()函数就可以将PIL对象转换为数组对象。

查看图片信息,可用如下的方法:

print img.shape  
print img.dtype 
print img.size 
print type(img)

如果是RGB图片,那么转换为array之后,就变成了一个rows*cols*channels的三维矩阵,因此,我们可以使用

img[i,j,k]

来访问像素值。

例1:打开图片,并随机添加一些椒盐噪声

复制代码

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img=np.array(Image.open('d:/ex.jpg'))

#随机生成5000个椒盐
rows,cols,dims=img.shape
for i in range(5000):
    x=np.random.randint(0,rows)
    y=np.random.randint(0,cols)
    img[x,y,:]=255
    
plt.figure("beauty")
plt.imshow(img)
plt.axis('off')
plt.show()

复制代码

 

例2:将lena图像二值化,像素值大于128的变为1,否则变为0

复制代码

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img=np.array(Image.open('d:/pic/lena.jpg').convert('L'))

rows,cols=img.shape
for i in range(rows):
    for j in range(cols):
        if (img[i,j]<=128):
            img[i,j]=0
        else:
            img[i,j]=1
            
plt.figure("lena")
plt.imshow(img,cmap='gray')
plt.axis('off')
plt.show()

复制代码

 

如果要对多个像素点进行操作,可以使用数组切片方式访问。切片方式返回的是以指定间隔下标访问 该数组的像素值。下面是有关灰度图像的一些例子:

复制代码

img[i,:] = im[j,:] # 将第 j 行的数值赋值给第 i 行

img[:,i] = 100 # 将第 i 列的所有数值设为 100

img[:100,:50].sum() # 计算前 100 行、前 50 列所有数值的和

img[50:100,50:100] # 50~100 行,50~100 列(不包括第 100 行和第 100 列)

img[i].mean() # 第 i 行所有数值的平均值

img[:,-1] # 最后一列

img[-2,:] (or im[-2]) # 倒数第二行

复制代码

 

用python简单处理图片(5):图像直方图

我们先来看两个函数reshape和flatten:

假设我们先生成一个一维数组:

vec=np.arange(15)
print vec

显示为:

[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

如果我们要把这个一维数组,变成一个3*5二维矩阵,我们可以使用reshape来实现

mat= vec.reshape(3,5)
print mat

显示为

[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]

现在如果我们返过来,知道一个二维矩阵,要变成一个一维数组,就不能用reshape了,只能用flatten. 我们来看两者的区别

a1=mat.reshape(1,-1)  #-1表示为任意,让系统自动计算
print a1
a2=mat.flatten()
print a2

显示为:

a1:  [[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]]
a2:  [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

可以看出,用reshape进行变换,实际上变换后还是二维数组,两个方括号,因此只能用flatten.

我们要对图像求直方图,就需要先把图像矩阵进行flatten操作,使之变为一维数组,然后再进行统计。

一、画灰度图直方图

绘图都可以调用matplotlib.pyplot库来进行,其中的hist函数可以直接绘制直方图。

调用方式:

n, bins, patches = plt.hist(arr, bins=50, normed=1, facecolor='green', alpha=0.75)

hist的参数非常多,但常用的就这五个,只有第一个是必须的,后面四个可选

arr: 需要计算直方图的一维数组

bins: 直方图的柱数,可选项,默认为10

normed: 是否将得到的直方图向量归一化。默认为0

facecolor: 直方图颜色

alpha: 透明度

返回值 :

n: 直方图向量,是否归一化由参数设定

bins: 返回各个bin的区间范围

patches: 返回每个bin里面包含的数据,是一个list

复制代码

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img=np.array(Image.open('d:/pic/lena.jpg').convert('L'))

plt.figure("lena")
arr=img.flatten()
n, bins, patches = plt.hist(arr, bins=256, normed=1, facecolor='green', alpha=0.75)  
plt.show()

复制代码

 

二、彩色图片直方图

实际上是和灰度直方图一样的,只是分别画出三通道的直方图,然后叠加在一起。

复制代码

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
src=Image.open('d:/ex.jpg')
r,g,b=src.split()

plt.figure("lena")
ar=np.array(r).flatten()
plt.hist(ar, bins=256, normed=1,facecolor='r',edgecolor='r',hold=1)
ag=np.array(g).flatten()
plt.hist(ag, bins=256, normed=1, facecolor='g',edgecolor='g',hold=1)
ab=np.array(b).flatten()
plt.hist(ab, bins=256, normed=1, facecolor='b',edgecolor='b')
plt.show()

复制代码

由此可见,matplotlib的画图功能是非常强大的,直方图只是其中非常小的一部分,更多的请参看官方文档:


http://matplotlib.org/api/pyplot_summary.html


python数字图像处理(4):图像数据类型及颜色空间转换

一、图像数据类型及转换

在skimage中,一张图片就是一个简单的numpy数组,数组的数据类型有很多种,相互之间也可以转换。这些数据类型及取值范围如下表所示:

Data typeRange
uint80 to 255
uint160 to 65535
uint320 to 232
float-1 to 1 or 0 to 1
int8-128 to 127
int16-32768 to 32767
int32-231 to 231 - 1

一张图片的像素值范围是[0,255], 因此默认类型是unit8, 可用如下代码查看数据类型:

from skimage import io,data
img=data.chelsea()
print(img.dtype.name)

在上面的表中,特别注意的是float类型,它的范围是[-1,1]或[0,1]之间。一张彩色图片转换为灰度图后,它的类型就由unit8变成了float

1、unit8转float

from skimage import data,img_as_float
img=data.chelsea()
print(img.dtype.name)
dst=img_as_float(img)
print(dst.dtype.name)

输出:

uint8
float64

2、float转uint8

from skimage import img_as_ubyte
import numpy as np
img = np.array([0, 0.5, 1], dtype=float)
print(img.dtype.name)
dst=img_as_ubyte(img)
print(dst.dtype.name)

输出:

float64
uint8

float转为unit8,有可能会造成数据的损失,因此会有警告提醒。

除了这两种最常用的转换以外,其实有一些其它的类型转换,如下表:

Function nameDescription
img_as_floatConvert to 64-bit floating point.
img_as_ubyteConvert to 8-bit uint.
img_as_uintConvert to 16-bit uint.
img_as_intConvert to 16-bit int.

 

二、颜色空间及其转换

如前所述,除了直接转换可以改变数据类型外,还可以通过图像的颜色空间转换来改变数据类型。

常用的颜色空间有灰度空间、rgb空间、hsv空间和cmyk空间。颜色空间转换以后,图片类型都变成了float型。

所有的颜色空间转换函数,都放在skimage的color模块内。

例:rgb转灰度图

from skimage import io,data,color
img=data.lena()
gray=color.rgb2gray(img)
io.imshow(gray)

其它的转换,用法都是一样的,列举常用的如下:

skimage.color.rgb2grey(rgb)

skimage.color.rgb2hsv(rgb)

skimage.color.rgb2lab(rgb)

skimage.color.gray2rgb(image)

skimage.color.hsv2rgb(hsv)

skimage.color.lab2rgb(lab)

 实际上,上面的所有转换函数,都可以用一个函数来代替

skimage.color.convert_colorspace(arrfromspacetospace)

表示将arr从fromspace颜色空间转换到tospace颜色空间。

例:rgb转hsv

from skimage import io,data,color
img=data.lena()
hsv=color.convert_colorspace(img,'RGB','HSV')
io.imshow(hsv)

在color模块的颜色空间转换函数中,还有一个比较有用的函数是

skimage.color.label2rgb(arr), 可以根据标签值对图片进行着色。以后的图片分类后着色就可以用这个函数。

例:将lena图片分成三类,然后用默认颜色对三类进行着色

复制代码

from skimage import io,data,color
import numpy as np
img=data.lena()
gray=color.rgb2gray(img)
rows,cols=gray.shape
labels=np.zeros([rows,cols])
for i in range(rows):
    for j in range(cols):
        if(gray[i,j]<0.4):
            labels[i,j]=0
        elif(gray[i,j]<0.75):
            labels[i,j]=1
        else:
            labels[i,j]=2
dst=color.label2rgb(labels)
io.imshow(dst)

复制代码

python数字图像处理(5):图像的绘制

实际上前面我们就已经用到了图像的绘制,如:

io.imshow(img)  

这一行代码的实质是利用matplotlib包对图片进行绘制,绘制成功后,返回一个matplotlib类型的数据。因此,我们也可以这样写:

import matplotlib.pyplot as plt
plt.imshow(img)

imshow()函数格式为:

matplotlib.pyplot.imshow(Xcmap=None)

X: 要绘制的图像或数组。

cmap: 颜色图谱(colormap), 默认绘制为RGB(A)颜色空间。

其它可选的颜色图谱如下列表:

颜色图谱描述
autumn红-橙-黄
bone黑-白,x线
cool青-洋红
copper黑-铜
flag红-白-蓝-黑
gray黑-白
hot黑-红-黄-白
hsvhsv颜色空间, 红-黄-绿-青-蓝-洋红-红
inferno黑-红-黄
jet蓝-青-黄-红
magma黑-红-白
pink黑-粉-白
plasma绿-红-黄
prism 红-黄-绿-蓝-紫-...-绿模式
spring洋红-黄
summer绿-黄
viridis蓝-绿-黄
winter蓝-绿

用的比较多的有gray,jet等,如:

plt.imshow(image,plt.cm.gray)
plt.imshow(img,cmap=plt.cm.jet)

在窗口上绘制完图片后,返回一个AxesImage对象。要在窗口上显示这个对象,我们可以调用show()函数来进行显示,但进行练习的时候(ipython环境中),一般我们可以省略show()函数,也能自动显示出来。

 skimage 

=
=

(type(dst))
io.show()

显示为:

可以看到,类型是'matplotlib.image.AxesImage'。显示一张图片,我们通常更愿意这样写:

import matplotlib.pyplot as plt
from skimage import io,data
img=data.astronaut()
plt.imshow(img)
plt.show()

 

matplotlib是一个专业绘图的库,相当于matlab中的plot,可以设置多个figure窗口,设置figure的标题,隐藏坐标尺,甚至可以使用subplot在一个figure中显示多张图片。一般我们可以这样导入matplotlib库:

import matplotlib.pyplot as plt

也就是说,我们绘图实际上用的是matplotlib包的pyplot模块。

一、用figure函数和subplot函数分别创建主窗口与子图

例:分开并同时显示宇航员图片的三个通道

复制代码

from skimage import data
import matplotlib.pyplot as plt
img=data.astronaut()
plt.figure(num='astronaut',figsize=(8,8))  #创建一个名为astronaut的窗口,并设置大小 

plt.subplot(2,2,1)     #将窗口分为两行两列四个子图,则可显示四幅图片
plt.title('origin image')   #第一幅图片标题
plt.imshow(img)      #绘制第一幅图片

plt.subplot(2,2,2)     #第二个子图
plt.title('R channel')   #第二幅图片标题
plt.imshow(img[:,:,0],plt.cm.gray)      #绘制第二幅图片,且为灰度图
plt.axis('off')     #不显示坐标尺寸

plt.subplot(2,2,3)     #第三个子图
plt.title('G channel')   #第三幅图片标题
plt.imshow(img[:,:,1],plt.cm.gray)      #绘制第三幅图片,且为灰度图
plt.axis('off')     #不显示坐标尺寸

plt.subplot(2,2,4)     #第四个子图
plt.title('B channel')   #第四幅图片标题
plt.imshow(img[:,:,2],plt.cm.gray)      #绘制第四幅图片,且为灰度图
plt.axis('off')     #不显示坐标尺寸

plt.show()   #显示窗口

复制代码

在图片绘制过程中,我们用matplotlib.pyplot模块下的figure()函数来创建显示窗口,该函数的格式为:

matplotlib.pyplot.figure(num=Nonefigsize=Nonedpi=Nonefacecolor=Noneedgecolor=None)

所有参数都是可选的,都有默认值,因此调用该函数时可以不带任何参数,其中:

num: 整型或字符型都可以。如果设置为整型,则该整型数字表示窗口的序号。如果设置为字符型,则该字符串表示窗口的名称。用该参数来命名窗口,如果两个窗口序号或名相同,则后一个窗口会覆盖前一个窗口。

figsize: 设置窗口大小。是一个tuple型的整数,如figsize=(8,8)

dpi: 整形数字,表示窗口的分辨率。

facecolor: 窗口的背景颜色。

edgecolor: 窗口的边框颜色。

用figure()函数创建的窗口,只能显示一幅图片,如果想要显示多幅图片,则需要将这个窗口再划分为几个子图,在每个子图中显示不同的图片。我们可以使用subplot()函数来划分子图,函数格式为:

matplotlib.pyplot.subplot(nrowsncolsplot_number)

nrows: 子图的行数。

ncols: 子图的列数。

plot_number: 当前子图的编号。

如:

plt.subplot(2,2,1)

则表示将figure窗口划分成了2行2列共4个子图,当前为第1个子图。我们有时也可以用这种写法:

plt.subplot(221)

两种写法效果是一样的。每个子图的标题可用title()函数来设置,是否使用坐标尺可用axis()函数来设置,如:

plt.subplot(221)
plt.title("first subwindow")
plt.axis('off')

 

二、用subplots来创建显示窗口与划分子图

除了上面那种方法创建显示窗口和划分子图,还有另外一种编写方法也可以,如下例: 

复制代码

import matplotlib.pyplot as plt
from skimage import data,color

img = data.immunohistochemistry()
hsv = color.rgb2hsv(img)

fig, axes = plt.subplots(2, 2, figsize=(7, 6))
ax0, ax1, ax2, ax3 = axes.ravel()

ax0.imshow(img)
ax0.set_title("Original image")

ax1.imshow(hsv[:, :, 0], cmap=plt.cm.gray)
ax1.set_title("H")

ax2.imshow(hsv[:, :, 1], cmap=plt.cm.gray)
ax2.set_title("S")

ax3.imshow(hsv[:, :, 2], cmap=plt.cm.gray)
ax3.set_title("V")

for ax in axes.ravel():
    ax.axis('off')

fig.tight_layout()  #自动调整subplot间的参数

复制代码

直接用subplots()函数来创建并划分窗口。注意,比前面的subplot()函数多了一个s,该函数格式为:

matplotlib.pyplot.subplots(nrows=1ncols=1)

nrows: 所有子图行数,默认为1。

ncols: 所有子图列数,默认为1。

返回一个窗口figure, 和一个tuple型的ax对象,该对象包含所有的子图,可结合ravel()函数列出所有子图,如:

fig, axes = plt.subplots(2, 2, figsize=(7, 6))
ax0, ax1, ax2, ax3 = axes.ravel()

创建了2行2列4个子图,分别取名为ax0,ax1,ax2和ax3, 每个子图的标题用set_title()函数来设置,如:

ax0.imshow(img)
ax0.set_title("Original image")

 

如果有多个子图,我们还可以使用tight_layout()函数来调整显示的布局,该函数格式为:

matplotlib.pyplot.tight_layout(pad=1.08h_pad=Nonew_pad=Nonerect=None)

所有的参数都是可选的,调用该函数时可省略所有的参数。

pad: 主窗口边缘和子图边缘间的间距,默认为1.08

h_pad, w_pad: 子图边缘之间的间距,默认为 pad_inches

rect: 一个矩形区域,如果设置这个值,则将所有的子图调整到这个矩形区域内。

一般调用为:

plt.tight_layout()  #自动调整subplot间的参数

 

三、其它方法绘图并显示

除了使用matplotlib库来绘制图片,skimage还有另一个子模块viewer,也提供一个函数来显示图片。不同的是,它利用Qt工具来创建一块画布,从而在画布上绘制图像。

例:

from skimage import data
from skimage.viewer import ImageViewer

img = data.coins()
viewer = ImageViewer(img)
viewer.show()

 

最后总结一下,绘制和显示图片常用到的函数有:

函数名功能调用格式
figure创建一个显示窗口plt.figure(num=1,figsize=(8,8)
imshow绘制图片plt.imshow(image)
show显示窗口plt.show()
subplot划分子图plt.subplot(2,2,1)
title设置子图标题(与subplot结合使用)plt.title('origin image')
axis是否显示坐标尺plt.axis('off')
subplots创建带有多个子图的窗口fig,axes=plt.subplots(2,2,figsize=(8,8))
ravel为每个子图设置变量ax0,ax1,ax2,ax3=axes.ravel()
set_title设置子图标题(与axes结合使用)ax0.set_title('first window')
tight_layout自动调整子图显示布局plt.tight_layout()



python数字图像处理(6):图像的批量处理

有些时候,我们不仅要对一张图片进行处理,可能还会对一批图片处理。这时候,我们可以通过循环来执行处理,也可以调用程序自带的图片集合来处理。

图片集合函数为:

skimage.io.ImageCollection(load_pattern,load_func=None)

这个函数是放在io模块内的,带两个参数,第一个参数load_pattern, 表示图片组的路径,可以是一个str字符串。第二个参数load_func是一个回调函数,我们对图片进行批量处理就可以通过这个回调函数实现。回调函数默认为imread(),即默认这个函数是批量读取图片。

先看一个例子:

import skimage.io as io
from skimage import data_dir
str=data_dir + '/*.png'
coll = io.ImageCollection(str)
print(len(coll))

显示结果为25, 说明系统自带了25张png的示例图片,这些图片都读取了出来,放在图片集合coll里。如果我们想显示其中一张图片,则可以在后加上一行代码:

io.imshow(coll[10])

显示为:

如果一个文件夹里,我们既存放了一些jpg格式的图片,又存放了一些png格式的图片,现在想把它们全部读取出来,该怎么做呢?

import skimage.io as io
from skimage import data_dir
str='d:/pic/*.jpg:d:/pic/*.png'
coll = io.ImageCollection(str)
print(len(coll))

注意这个地方'd:/pic/*.jpg:d:/pic/*.png' ,是两个字符串合在一起的,第一个是'd:/pic/*.jpg', 第二个是'd:/pic/*.png' ,合在一起后,中间用冒号来隔开,这样就可以把d:/pic/文件夹下的jpg和png格式的图片都读取出来。如果还想读取存放在其它地方的图片,也可以一并加进去,只是中间同样用冒号来隔开。

io.ImageCollection()这个函数省略第二个参数,就是批量读取。如果我们不是想批量读取,而是其它批量操作,如批量转换为灰度图,那又该怎么做呢?

那就需要先定义一个函数,然后将这个函数作为第二个参数,如:

复制代码

from skimage import data_dir,io,color

def convert_gray(f):
    rgb=io.imread(f)
    return color.rgb2gray(rgb)
    
str=data_dir+'/*.png'
coll = io.ImageCollection(str,load_func=convert_gray)
io.imshow(coll[10])

复制代码

这种批量操作对视频处理是极其有用的,因为视频就是一系列的图片组合

复制代码

from skimage import data_dir,io,color

class AVILoader:
    video_file = 'myvideo.avi'

    def __call__(self, frame):
        return video_read(self.video_file, frame)

avi_load = AVILoader()

frames = range(0, 1000, 10) # 0, 10, 20, ...
ic =io.ImageCollection(frames, load_func=avi_load)

复制代码

这段代码的意思,就是将myvideo.avi这个视频中每隔10帧的图片读取出来,放在图片集合中。

得到图片集合以后,我们还可以将这些图片连接起来,构成一个维度更高的数组,连接图片的函数为:

skimage.io.concatenate_images(ic)

带一个参数,就是以上的图片集合,如:

from skimage import data_dir,io,color

coll = io.ImageCollection('d:/pic/*.jpg')
mat=io.concatenate_images(coll)

使用concatenate_images(ic)函数的前提是读取的这些图片尺寸必须一致,否则会出错。我们看看图片连接前后的维度变化:

复制代码

from skimage import data_dir,io,color

coll = io.ImageCollection('d:/pic/*.jpg')
print(len(coll))      #连接的图片数量
print(coll[0].shape)   #连接前的图片尺寸,所有的都一样
mat=io.concatenate_images(coll)
print(mat.shape)  #连接后的数组尺寸

复制代码

显示结果:

2
(870, 580, 3)
(2, 870, 580, 3)

可以看到,将2个3维数组,连接成了一个4维数组

如果我们对图片进行批量操作后,想把操作后的结果保存起来,也是可以办到的。

例:把系统自带的所有png示例图片,全部转换成256*256的jpg格式灰度图,保存在d:/data/文件夹下

改变图片的大小,我们可以使用tranform模块的resize()函数,后续会讲到这个模块。

复制代码

from skimage import data_dir,io,transform,color
import numpy as np

def convert_gray(f):
     rgb=io.imread(f)    #依次读取rgb图片
     gray=color.rgb2gray(rgb)   #将rgb图片转换成灰度图
     dst=transform.resize(gray,(256,256))  #将灰度图片大小转换为256*256
     return dst
    
str=data_dir+'/*.png'
coll = io.ImageCollection(str,load_func=convert_gray)
for i in range(len(coll)):
    io.imsave('d:/data/'+np.str(i)+'.jpg',coll[i])  #循环保存图片

复制代码

 结果:



python数字图像处理(7):图像的形变与缩放

图像的形变与缩放,使用的是skimage的transform模块,函数比较多,功能齐全。

1、改变图片尺寸resize

函数格式为:

skimage.transform.resize(imageoutput_shape)

image: 需要改变尺寸的图片

output_shape: 新的图片尺寸

复制代码

from skimage import transform,data
import matplotlib.pyplot as plt
img = data.camera()
dst=transform.resize(img, (80, 60))
plt.figure('resize')

plt.subplot(121)
plt.title('before resize')
plt.imshow(img,plt.cm.gray)

plt.subplot(122)
plt.title('before resize')
plt.imshow(dst,plt.cm.gray)

plt.show()

复制代码

将camera图片由原来的512*512大小,变成了80*60大小。从下图中的坐标尺,我们能够看出来:

 

2、按比例缩放rescale

函数格式为:

skimage.transform.rescale(image, scale[, ...])

scale参数可以是单个float数,表示缩放的倍数,也可以是一个float型的tuple,如[0.2,0.5],表示将行列数分开进行缩放

from skimage import transform,data
img = data.camera()
print(img.shape)  #图片原始大小 
print(transform.rescale(img, 0.1).shape)  #缩小为原来图片大小的0.1倍
print(transform.rescale(img, [0.5,0.25]).shape)  #缩小为原来图片行数一半,列数四分之一
print(transform.rescale(img, 2).shape)   #放大为原来图片大小的2倍

结果为:

(512, 512)
(51, 51)
(256, 128)
(1024, 1024)

3、旋转 rotate

skimage.transform.rotate(image, angle[, ...],resize=False)

angle参数是个float类型数,表示旋转的度数

resize用于控制在旋转时,是否改变大小 ,默认为False

复制代码

from skimage import transform,data
import matplotlib.pyplot as plt
img = data.camera()
print(img.shape)  #图片原始大小
img1=transform.rotate(img, 60) #旋转90度,不改变大小 
print(img1.shape)
img2=transform.rotate(img, 30,resize=True)  #旋转30度,同时改变大小
print(img2.shape)   

plt.figure('resize')

plt.subplot(121)
plt.title('rotate 60')
plt.imshow(img1,plt.cm.gray)

plt.subplot(122)
plt.title('rotate  30')
plt.imshow(img2,plt.cm.gray)

plt.show()

复制代码

显示结果:

4、图像金字塔

以多分辨率来解释图像的一种有效但概念简单的结构就是图像金字塔。图像金字塔最初用于机器视觉和图像压缩,一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低的图像集合。金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似。当向金字塔的上层移动时,尺寸和分辨率就降低。

在此,我们举一个高斯金字塔的应用实例,函数原型为:

skimage.transform.pyramid_gaussian(image, downscale=2)
downscale控制着金字塔的缩放比例

复制代码

import numpy as np
import matplotlib.pyplot as plt
from skimage import data,transform

image = data.astronaut()  #载入宇航员图片
rows, cols, dim = image.shape  #获取图片的行数,列数和通道数
pyramid = tuple(transform.pyramid_gaussian(image, downscale=2))  #产生高斯金字塔图像
#共生成了log(512)=9幅金字塔图像,加上原始图像共10幅,pyramid[0]-pyramid[1]

composite_image = np.ones((rows, cols + cols / 2, 3), dtype=np.double)  #生成背景

composite_image[:rows, :cols, :] = pyramid[0]  #融合原始图像

i_row = 0
for p in pyramid[1:]:
    n_rows, n_cols = p.shape[:2]
    composite_image[i_row:i_row + n_rows, cols:cols + n_cols] = p  #循环融合9幅金字塔图像
    i_row += n_rows

plt.imshow(composite_image)
plt.show()

复制代码

上右图,就是10张金字塔图像,下标为0的表示原始图像,后面每层的图像行和列变为上一层的一半,直至变为1

除了高斯金字塔外,还有其它的金字塔,如:

skimage.transform.pyramid_laplacian(image, downscale=2):