Python skimage快速图像处理(二)——Numpy速成
Python skimage快速图像处理(二)——Numpy速成
- 简介
- Numpy索引
- 彩色图像
- 坐标约定
- 数组维数的顺序
- 时间维度
简介
图像在scikit-images
中用Numpy矩阵表示。因此,可以使用标准的NumPy方法来实现许多常见的操作:
from skimage import data
camera = data.camera()
type(camera)
<type ‘numpy.ndarray’>
查看图像的形状和像素数量:
camera.shape
(512, 512)
camera.size
262144
查看图像像素值的统计信息:
camera.min(), camera.max()
(0, 255)
118.31400299072266
表示图像的Numpy数组可以是不同的整数或浮点数类型。查看图像数据类型及其含义获得详细信息和scikit-images
如何处理不同数据类型。
Numpy索引
Numpy索引可用于查看像素值或修改它们:
camera[10, 20] # 获取第10行第20列的像素值
153
camera[3, 10] = 0 #将第3行第20列的像素值设为0
注意,在Numpy索引中,第一个维度(camera.shape[0]
)对应行,第二个维度(camera .shape[1]
)对应列,原点(camera[0,0]
)位于左上角。它匹配矩阵/线性代数表示法,但与笛卡尔坐标(x, y)相反。详细信息,参阅坐标约定。
除了单个像素外,还可以使用Numpy的切片功能访问/修改整个像素集的值:
camera[:10] = 0 #将头10行设为黑色0
掩码(布尔值掩码索引,可理解为PS中的蒙版):
mask = camera < 87
camera[mask] = 255 # 当掩码为真时设置该像素为白色255
花式索引(索引集索引):
import numpy as np
inds_r = np.arange(len(camera)) # 0到511的矩阵
inds_c = 4 * inds_r % len(camera) # 0到511,间距为4的矩阵
camera[inds_r, inds_c] = 0
当您需要选择一组像素执行操作时,掩码非常有用。掩码可以是与图像形状相同的布尔数组,或可向图像形状传递的形状。
例如,定义一个感兴趣的区域,一个圆:
nrows, ncols = camera.shape
row, col = np.ogrid[:nrows, :ncols] #快速产生二维行向量和列向量
cnt_row, cnt_col = nrows / 2, ncols / 2 #取半径
outer_disk_mask = ((row - cnt_row)**2 + (col - cnt_col)**2 > (nrows / 2)**2) # 蒙版为当前坐标位置大于半径范围
camera[outer_disk_mask] = 0 # 当掩码为真时设置该像素为黑色255
查看图像
from skimage import io
%matplotlib inline
io.imshow(camera)
Numpy的布尔运算可以定义更复杂的掩码:
lower_half = row > cnt_row
lower_half_disk = np.logical_and(lower_half, outer_disk_mask)
camera = data.camera()
camera[lower_half_disk] = 0
io.imshow(camera)
彩色图像
上述所有内容对彩色图像同样适用。彩色图像是再多一个维度的Numpy数组:
cat = data.chelsea()
io.imshow(cat)
type(cat)
numpy.ndarray
cat.shape
(300, 451, 3)
这表明变量cat
是一个300×451像素的图像,有三个通道(红、绿、蓝)。如前所述,我们可以获取并设置像素值:
cat[10, 20]
array([151, 129, 115], dtype=uint8)
cat[50, 60] = 0 #将第50行,第60列的像素设为黑色
cat[50, 61] = [0, 255, 0] # 将第50行,第60列的像素设为绿色[red, green, blue]
同样地,可以对2D多通道图像使用2D布尔蒙版:
cat = data.chelsea()
reddish = cat[:, :, 0] > 160 # 红色的值大于160(0red 1green 2blue)
cat[reddish] = [0, 255, 0] #设为绿色
io.imshow(cat)
坐标约定
因为scikit-image
使用Numpy数组表示图像,所以坐标约定必须匹配。二维灰度图(如上图camera)通过行、列,缩写为(row, col)
或(r, c)
进行索引,左上角像素的索引为(0,0)
。
在库的各个部分,你还将看到用rr
和cc
引用行和列坐标。我们将这个约定与(x, y)
区别开来,(x, y)
通常表示标准的笛卡尔坐标,其中x
是横坐标,y
是纵坐标,原点在左下角。例如,Matplotlib轴使用这种坐标。
对于多通道图像,最后一个维用于彩色通道,用channel
或ch
表示。
最后,对于立体3D图像,如视频、磁共振成像(MRI)扫描、共聚焦显微镜等,我们将第一个维度称为plane
,缩写为pln
或p
。
约定总结如下:
图片类型 | 约定 |
---|---|
二维灰度图 | (row, col) |
二维多通道(如RGB) | (row, col, ch) |
三维灰度 | (pln, row, col) |
三维多通道 | (pln, row, col, ch) |
scikit-image
中的许多函数可以直接对3D图像进行操作(以下代码执行时间略久):
im3d = np.random.rand(100, 1000, 1000) # 生成随机矩阵
from skimage import morphology
from scipy import ndimage as ndi
seeds = ndi.label(im3d < 0.1)[0] # 标记小于0.1的值
ws = morphology.watershed(im3d, seeds) # 分水岭算法
然而,多数情况下,第三个空间维度的分辨率低于其他两个维度。一些scikit-image
函数提供了一个间距关键字spacing
参数来帮助处理这类数据:
from skimage import segmentation
slics = segmentation.slic(im3d, spacing=[5, 1, 1], multichannel=False) #k-means聚类分割图像
其他情况,处理必须在plane
维度上完成。当第一个维度为plane
(与约定一致),可以使用以下语法:
from skimage import filters
edges = np.empty_like(im3d)
for pln, image in enumerate(im3d):# 迭代第一个维度edges[pln] = filters.sobel(image) #Sobel变换
数组维数的顺序
尽管坐标轴的标记可能看起来很随意,但是它对操作的速度有很大的影响。这是因为现代处理器不会从内存中仅检索一项,而是检索整个相邻块(称为预取的操作)。因此,处理内存中相邻的元素比处理分散的元素要快,即使操作的数量相同:
def in_order_multiply(arr, scalar):for plane in list(range(arr.shape[0])):arr[plane, :, :] *= scalardef out_of_order_multiply(arr, scalar):for plane in list(range(arr.shape[2])):arr[:, :, plane] *= scalar
import time
im3d = np.random.rand(100, 1024, 1024)
t0 = time.time(); x = in_order_multiply(im3d, 5); t1 = time.time()
print("%.2f seconds" % (t1 - t0))
0.08 seconds
s0 = time.time(); x = out_of_order_multiply(im3d, 5); s1 = time.time()
print("%.2f seconds" % (s1 - s0))
1.65 seconds
print("Speedup: %.1fx" % ((s1 - s0) / (t1 - t0)))
Speedup: 21.3x
当最后/最右边的维度变得更大时,加速效果更显著。在开发算法时考虑数据局部性是值得的。特别地,scikit-image
默认使用C-连续数组。当使用嵌套循环时,数组的最后/最右边的维度应该位于计算的最内层循环中。在上面的例子中,*=
numpy操作符遍历所有剩余的维度。
时间维度
虽然scikit-image
目前还没有提供专门处理时变3D数据的函数,但它与Numpy数组的兼容性使我们能够很自然地处理形如(t, pln, row, col, ch)的5D数组:
# 伪代码
for timepoint in image5d:# Each timepoint is a 3D multichannel imagedo_something_with(timepoint)
对上表进行补充如下:
数据类型类型 | 约定 |
---|---|
二维灰度图 | (row, col) |
二维多通道(如RGB) | (row, col, ch) |
三维灰度 | (pln, row, col) |
三维多通道 | (pln, row, col, ch) |
二维彩色视频 | (t, row, col, ch) |
三维多通道视频 | (t, pln, row, col, ch) |
Python skimage快速图像处理(二)——Numpy速成相关推荐
- python 怎么快速分辨一个numpy矩阵(数组)是几维的?
比如这个数组: [[[0, 1], [2, 3]], [[4, 5], [6, 7]]] 它的最外层有三个括号"[]", 所以它就是三维数组 当然, 你也可以直接使用: print ...
- 【Python数据挖掘课程】六.Numpy、Pandas和Matplotlib包基础知识
前面几篇文章采用的案例的方法进行介绍的,这篇文章主要介绍Python常用的扩展包,同时结合数据挖掘相关知识介绍该包具体的用法,主要介绍Numpy.Pandas和Matplotlib三个包.目录: ...
- [Python图像处理] 二十八.OpenCV快速实现人脸检测及视频中的人脸
该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...
- python 图像分析自然纹理方向与粗细代码_python skimage图像处理(二)
python skimage图像处理(二) 图像简单滤波 对图像进行滤波,可以有两种效果:一种是平滑滤波,用来抑制噪声:另一种是微分算子,可以用来检测边缘和特征提取. skimage库中通过filte ...
- Python一:【skimage】图像处理库的应用,不使用opencv的情况
python作为简单高效又很强大的一门编程语言,scikit-image是python中处理图像的一个库,对大多数的图像处理算法进行了封装,用户只需调用相关的接口即可实现想要的效果. 所以,本章节主要 ...
- python skimage图像处理(一)
python skimage图像处理(一) This blog is from: https://www.cnblogs.com/wangxiaocvpr/p/11656603.html 基于pyth ...
- 【图像处理】python skimage 图像处理
因本人刚开始写博客,学识经验有限,如有不正之处望读者指正,不胜感激:也望借此平台留下学习笔记以温故而知新.这是关于 Python 中 skimage 包用法的详解转载. 本文转自 python数字图像 ...
- python skimage图像处理
python skimage图像处理(一) jiandanjinxin关注 22017.09.26 14:31:04字数 5,913阅读 103,968 本文转自 python数字图像处理 基于pyt ...
- 基于python的快速傅里叶变换FFT(二)
基于python的快速傅里叶变换FFT(二) 本文在上一篇博客的基础上进一步探究正弦函数及其FFT变换. 知识点 FFT变换,其实就是快速离散傅里叶变换,傅立叶变换是数字信号处理领域一种很重要的算 ...
最新文章
- Python3 如何优雅地使用正则表达式(详解五)
- centos下性能分析工具perf的安装和简单使用
- url的三个js编码函数escape(),encodeURI(),encodeURIComponent()简介
- jdbc中如何实现模糊查询
- VTK:Filtering之ImplicitBoolean
- Python(1)-源起、设计目标、设计哲学、特点
- mysql ddl查询语句_SQL基础-----DDL
- 研发管理(2)---七个工作法则
- 【Elasticsearch】Elasticsearch 索引生命周期管理
- vue中父子组件先后渲染_Vue中父子组件执行的先后顺序
- 浅谈WebService的版本兼容性设计
- 你想面试运维看一下你合格了吗?
- 国内的9家域名顶级注册商
- PHP制作面包屑,thinkPHP制作面包屑方法
- GBase 8c查看数据
- postgresql tips
- GetLastError 错误码大全(转载)
- 转:Processing 编程学习指南
- 在请求分页存储管理方案中,若某用户空间为16个页面,页长1KB,现有页表如下,则逻辑地址0A1F(H)所对应的物理地址为( )。
- python怎么应用在机械领域的国家砝码_2020尔雅通识课Python璇█搴旂敤答案获取...