01_Numpy的图片处理(读取,变换,保存)

2023-10-31

Numpy的图片处理(读取,变换,保存)

使用Numpy的ndarray可以读取图片文件,并且可以对图片进行各种各样的处理。
例如:图片像素值的读取,替换,随机剪裁,拼接等等都可以使用ndarray。对于已经习惯使用Numpy的人们来说,已经可以不使用OpenCV进行图像处理。

即便是使用OpenCV进行图片处理的时候,OpenCV图像的读取也是使用的ndarray形式,所以直接使用Numpy将会更加的方便与快捷。

在此:对图片文件的基础读取,保存方法进行介绍

  • Numpy图片文件的读取方法
  • Numpy图片文件的保存方法

和一些Numpy的图像处理的实例进行介绍

  • 像素值的读取和修改
  • 图片的单色化和图片的拼接
  • 减色处理
  • 二值化处理
  • 四则演算
  • 切片修剪
  • 按切片或函数的拆分
  • 切片粘贴
  • Alpha混合和遮罩处理
  • 旋转和上/下/左/右 反转
    等等进行说明。

图片文件读取(Numpy的ndarray形式)


使用以下的图片为例。
在这里插入图片描述
np.array中调用PIL.Image.open()函数进行读取,并且可以查看数据的类型和形状(shape,行(高),列(宽),色(通道数))等信息。
需要注意的是色(通道数)的读取顺序是RGB(红,绿,蓝)。而OpenCV的cv2.imread()的读取顺序是(BGR),稍有不同。

from PIL import Image
import numpy as np

im = np.array(Image.open('./data/01/lena.jpg'))

print(type(im))
# <class 'numpy.ndarray'>

print(im.dtype)
# uint8

print(im.shape)
# (225, 400, 3)

convert(‘L’)函数可以把图片转换成黑白图片(灰度图)之后,将图片作为2维数据进行读取。
此时形状只剩下了行(高)和列(宽)。

im_gray = np.array(Image.open('./data/01/lena.jpg').convert('L'))

print(im_gray.shape)
# (225, 400)

使用np.asarray()同样可以返回得到一个ndarray的数组。但是使用np.array()返回的是一个允许被更改的ndarray,np.asarray()返回的ndarra不允许被更改。

'''np.array()'''
print(im.flags.writeable)
# True

print(im[0, 0, 0])
# 109

im[0, 0, 0] = 0

print(im[0, 0, 0])
# 0
'''np.asarray()'''
im_as = np.asarray(Image.open('./data/01/lena.jpg'))

print(type(im_as))
# <class 'numpy.ndarray'>

print(im_as.flags.writeable)
# False

# im_as[0, 0, 0] = 0
# ValueError: assignment destination is read-only

图片的数据类型是以uint8(8位无符号整型)进行的读取。若想以float类型进行读取时,可以使用astype()进行转换,或者指定np.array()和np.asarray()的第2个参数(指定类型的读取)。

im_f = im.astype(np.float64)
print(im_f.dtype)
# float64

im_f = np.array(Image.open('./data/01/lena.jpg'), np.float64)
print(im_f.dtype)
# float64

图片文件保存(Numpy的ndarray形式)


使用Image.fromarray()函数读取ndarray数据时,可以得到一个PIL.Image类型的文件。再使用save()函数可以将其保存下来。被保存的文件格式,将根据其指定的扩展名自动进行判别。

pil_img = Image.fromarray(im)
print(pil_img.mode)
# RGB

pil_img.save('./data/01/lena_save_pillow.jpg')

黑白图片的保存也可以。

pil_img_gray = Image.fromarray(im_gray)
print(pil_img_gray.mode)
# L

pil_img_gray.save('./data/01/lena_save_pillow_gray.jpg')

简洁的写法

Image.fromarray(im).save('./data/01/lena_save_pillow.jpg')
Image.fromarray(im_gray).save('./data/01/lena_save_pillow_gray.jpg')

float类型进行保存时,有可能会出现错误。此时,需要将其类型转换成uint8之后,再保存。

# pil_img = Image.fromarray(im_f)
# TypeError: Cannot handle this data type

pil_img = Image.fromarray(im_f.astype(np.uint8))
pil_img.save('./data/01/lena_save_pillow.jpg')

使用astype()进行类型转换保存的时候,不会进行比例的缩放,所以当像素值为0.0-1.0之间的时候,需要先将其乘以255,再保存。

像素值的读取和修改


index[]可以取得指定坐标点的像素值。指定的顺序是行,列。xy的话,y,x的顺序指定。原点(0,0)为图片的左上角。

from PIL import Image
import numpy as np

im = np.array(Image.open('./data/01/lena.jpg'))

print(im.shape)
# (225, 400, 3)

print(im[100, 150])
# [111  81 109]

print(type(im[100, 150]))
# <class 'numpy.ndarray'>

上述的实例中,(y,x)=(100,150)为第100行,150列的像素值。和上述的一样,使用Pillow,ndarray数组读取时,颜色的排列读取顺序为RGB,(R,G,B)=(110,81,109)。

R, G, B = im[100, 150]

print(R)
# 111

print(G)
# 81

print(B)
# 109

index[]指定像素值的读取。

print(im[100, 150, 0])
# 111

print(im[100, 150, 1])
# 81

print(im[100, 150, 2])
# 109

修改像素值的时候,可以RGB三色同时进行修改,或者单色修改。

im[100, 150] = (0, 50, 100)

print(im[100, 150])
# [  0  50 100]

im[100, 150, 0] = 150

print(im[100, 150])
# [150  50 100]

在实际的日常操作中,通常是对图片整体或者是切片的部分进行操作,对单个像素值的操作并不常见。

图片的单色化和拼接


其他的像素值修改为0,单色图片的生成,以及横向的图片拼接。

from PIL import Image
import numpy as np

im = np.array(Image.open('./data/01/lena_square.png'))

im_R = im.copy()
im_R[:, :, (1, 2)] = 0
im_G = im.copy()
im_G[:, :, (0, 2)] = 0
im_B = im.copy()
im_B[:, :, (0, 1)] = 0

# 向的图片拼接
im_RGB = np.concatenate((im_R, im_G, im_B), axis=1)
# im_RGB = np.hstack((im_R, im_G, im_B))
# im_RGB = np.c_['1', im_R, im_G, im_B]

pil_img = Image.fromarray(im_RGB)
pil_img.save('./data/01/lena_numpy_split_color.jpg')

处理结果
在这里插入图片描述

像素值的反转


用像素值的最大值(uint8类型)255减去其像素值。

import numpy as np
from PIL import Image

im = np.array(Image.open('./data/01/lena_square.png').resize((256, 256)))

im_i = 255 - im

Image.fromarray(im_i).save('./data/01/lena_numpy_inverse.jpg')

在这里插入图片描述
减色处理


用//求其舍去余数值之后,再次相乘。则像素值为离散值,并且可以减少颜色的数量。

import numpy as np
from PIL import Image

im = np.array(Image.open('./data/01/lena_square.png').resize((256, 256)))

im_32 = im // 32 * 32
im_128 = im // 128 * 128

im_dec = np.concatenate((im, im_32, im_128), axis=1)

Image.fromarray(im_dec).save('./data/01/lena_numpy_dec_color.png')

在这里插入图片描述
二值化处理


设定一个中间值,对图片进行非黑即白的二值化处理
在这里插入图片描述

四则运算


乘法,除法,累乘等计算。
函数可以对图片全体进行计算,所以无需使用for等循环函数。

from PIL import Image
import numpy as np

im = np.array(Image.open('./data/01/lena_square.png'))

im_1_22 = 255.0 * (im / 255.0)**(1 / 2.2)
im_22 = 255.0 * (im / 255.0)**2.2

im_gamma = np.concatenate((im_1_22, im, im_22), axis=1)

pil_img = Image.fromarray(np.uint8(im_gamma))
pil_img.save('./data/01/lena_numpy_gamma.jpg')

在这里插入图片描述
计算的结果ndarray类型为float类型。所以最后保存时,需要先转换成uint8类型之后,再保存。

切片修剪


指定范围的矩形切片。

from PIL import Image
import numpy as np

im = np.array(Image.open('./data/01/lena_square.png'))

print(im.shape)
# (512, 512, 3)

im_trim1 = im[128:384, 128:384]
print(im_trim1.shape)
# (256, 256, 3)

Image.fromarray(im_trim1).save('./data/01/lena_numpy_trim.jpg')

在这里插入图片描述
以左上角为原点,指定宽和高的裁剪。

def trim(array, x, y, width, height):
    return array[y:y + height, x:x+width]

im_trim2 = trim(im, 128, 192, 256, 128)
print(im_trim2.shape)
# (128, 256, 3)

Image.fromarray(im_trim2).save('./data/01/lena_numpy_trim2.jpg')

在这里插入图片描述
按切片或函数的拆分


可以使用切片分割图片。与从图片边裁进行裁剪相同。

from PIL import Image
import numpy as np

im = np.array(Image.open('./data/01/lena_square.png').resize((256, 256)))

print(im.shape)
# (256, 256, 3)

im_0 = im[:, :100]
im_1 = im[:, 100:]

print(im_0.shape)
# (256, 100, 3)

print(im_1.shape)
# (256, 156, 3)

Image.fromarray(im_0).save('./data/01/lena_numpy_split_0.jpg')
Image.fromarray(im_1).save('./data/01/lena_numpy_split_1.jpg')

在这里插入图片描述
在这里插入图片描述
横向分割函数为np.hsplit()。第二个参数为整数值时,将进行相等的分割。

im_0, im_1 = np.hsplit(im, 2)

print(im_0.shape)
# (256, 128, 3)

print(im_1.shape)
# (256, 128, 3)

第二个参数值为列表时,在那个值的位置处进行分割。

im_0, im_1, im_2 = np.hsplit(im, [100, 150])

print(im_0.shape)
# (256, 100, 3)

print(im_1.shape)
# (256, 50, 3)

print(im_2.shape)
# (256, 106, 3)

np.hsplit()和np.vsplit()指定第二个参数值时,不能进行等份分割时,便会发生错误。此时,用np.array_split()的话,会自动调节尺寸,进行分割。

# im_0, im_1, im_2 = np.hsplit(im, 3)
# ValueError: array split does not result in an equal division

im_0, im_1, im_2 = np.array_split(im, 3, axis=1)

print(im_0.shape)
# (256, 86, 3)

print(im_1.shape)
# (256, 85, 3)

print(im_2.shape)
# (256, 85, 3)

切片粘贴


切片可以将一个矩阵中的矩形区域替换到另一个矩阵中去。
比如:图片的一部分粘贴到全图片中。

import numpy as np
from PIL import Image

src = np.array(Image.open('./data/01/lena_square.png').resize((128, 128)))
dst = np.array(Image.open('./data/01/lena_square.png').resize((256, 256))) // 4

dst_copy = dst.copy()
dst_copy[64:128, 128:192] = src[32:96, 32:96]

Image.fromarray(dst_copy).save('data/dst/lena_numpy_paste.jpg')

在这里插入图片描述

dst_copy = dst.copy()
dst_copy[64:192, 64:192] = src

Image.fromarray(dst_copy).save('./data/01/lena_numpy_paste_all.jpg')

在这里插入图片描述
Alpha混合和遮罩处理

由于可以很容易的对矩阵中的每个元素进行操作,因此可以对2个图片进行混合和遮罩处理。
在这里插入图片描述

选择 上/下/左/右 反转


矩阵的旋转,反转等函数的应用效果。
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

01_Numpy的图片处理(读取,变换,保存) 的相关文章

随机推荐

  • 交互设计实用指南系列11-减少记忆负担

    http ued taobao org blog 2010 03 交互设计实用指南系列11 减少记忆负担 科普 辞海 中 记忆 的定义是 人脑对经验过的事物的识记 保持 再现或再认 记忆是人类一个非常重要的心理活动 它是人类很多其他思维活动
  • 【HJ72】百钱买百鸡问题

    题目描述 公元前五世纪 我国古代数学家张丘建在 算经 一书中提出了 百鸡问题 鸡翁一值钱五 鸡母一值钱三 鸡雏三值钱一 百钱买百鸡 问鸡翁 鸡母 鸡雏各几何 现要求你打印出所有花一百元买一百只鸡的方式 输入描述 输入任何一个整数 即可运行程
  • 从浏览器地址栏输入url到显示页面的步骤

    浏览器输入URL到渲染过程解析 从浏览器地址栏输入url到显示页面的步骤 从浏览器地址栏输入url到显示页面的步骤 目录 1 概述 2 DNS域名解析 3 三次握手与四次挥手 4 DOM CSSOM 渲染树的构建 渲染与绘制 1 概述 浏览
  • Mac里的airdrop传输文件

    01 两方打开 02 设置对所有人可以发现 03 右键需要传输的文件 04 选择共享 airdrop 05 点击页面上的名称 开始传输 note 可以传输 app文件 这样可以大大节省下载安装所要耗费的时间 word只要一分钟就能从从无到有
  • 机器学习_深度学习毕设题目汇总——图像生成

    下面是该类的一些题目 题目 基于生成式对抗网络的无监督图像生成研究 用于图像生成的机器学习算法在人像合成中的研究与应用 可抵抗相机抖动的高动态图像生成算法研究 图像生成诗歌的端到端模型研究 基于GANs的脑部MRI图像生成方法研究 基于GA
  • 问二十四:分类说明JUC包常用类有哪些?

    JUC中常用类汇总 JUC的atomic包下运用了CAS的AtomicBoolean AtomicInteger AtomicReference等原子变量类 JUC的locks包下的AbstractQueuedSynchronizer AQ
  • 【Ensemble Learning】第 3 章:混合模型

    在第2章中 您学习了如何以不同方式划分和混合训练数据以构建集成模型 其性能优于在未划分数据集上训练的模型 在本章中 您将学习不同的组装方法 与混合训练数据方法不同 混合模型方法在不同的机器学习模型中使用相同的数据集 然后以不同的方式组合结果
  • pads win10显示不全

    打开注册表 WIN R 1 路径 HKEY LOCAL MACHINE SOFTWARE Microsoft Windows NT CurrentVersion Fonts 将原来的 Microsoft YaHei TrueType Mic
  • C++ Vector容器的push_back( )与pop_back( )函数

    C Vector容器的push back 与pop back 函数 push back pop back 参考链接 push back 函数将一个新的元素加到vector的最后面 位置为当前最后一个元素的下一个元素 push back 在V
  • java IDEA加密/解密 源码

    package tool import org apache commons codec binary Base64 import org bouncycastle jce provider BouncyCastleProvider imp
  • Git如何Check Out出指定文件或者文件夹

    原文 http www handaoliang com a 20140506 195406 html 在进行项目开发的时候 有时候会有这样的需求那就是 我们只希望从Git仓库里取指定的文件或者文件夹出来 在SVN里面 这非常容易实现 因为S
  • 实训9——门磁报警

    实验九 门磁报警 一 实验目的 通过门磁传感器 判断三种开门方式 1 正常开门 就是有正常开门方式 例指纹开门 蓝牙开门后 主人打开门 触发门磁 2 门未关好 在正常开门后 主人没有即使关门 会引发门未关好报警 3 有人撬门 非正常开门 即
  • [Python人工智能] 十五.无监督学习Autoencoder原理及聚类可视化案例详解

    从本专栏开始 作者正式研究Python深度学习 神经网络及人工智能相关知识 前一篇文章详细讲解了循环神经网络LSTM RNN如何实现回归预测 通过sin曲线拟合实现如下图所示效果 本篇文章将分享无监督学习Autoencoder的原理知识 然
  • 用户增长漫谈二

    除了功能迭代 增量开发配套敏捷理念 这里重要谈一个概念 宏观 微观上都有可取之处 品牌架构 反应企业意愿 个性 未来可能性留存 兼容不同利益群体方式进程商业活动 主品牌 标识性弱 但是个性强烈 业务 产品特性底的处理方式 以资金 实力彰显
  • MyBatis 学习笔记(八)---源码分析篇--SQL 执行过程详细分析

    前言 在面试中我们经常会被到MyBatis中 占位符与 占位符的区别 大多数的小伙伴都可以脱口而出 会对值进行转义 防止SQL注入 而 则会原样输出传入值 不会对传入值做任何处理 本文将通过源码层面分析为啥 可以防止SQL注入 源码解析 首
  • JS逆向爬虫案例分享

    某域网站数据爬取之反爬策略JS逆向分析 本次分享解析某域网站数据的反爬机制 此次只做技术分享 如有侵权 请联系删除 1 分析网 首先打开网站发送请求 点击F12 发送请求发现电脑端并没有接口返回数据 即返回切换手机端观察 点解F12观察找到
  • Mplayer 1.0pre5 安装纪实

    一开始装了个realone gold 版 但是怎么弄都没有声音 没有办法 只能硬着头皮装mplayer 了 刚刚接触linux 真的是什么也不懂 连看个电影也得费这么大的事 搞了一天 终于算是能看到图像和声音来 现在是只其然 但不怎么知所以
  • 【医学图像分割】读论文系列 1

    医学图像分割 读论文系列 1 文章目录 医学图像分割 读论文系列 1 Title Introduction Abstract Keyword Method Experiment Conclusion Title 标题 Noisy Label
  • JS - 手写节流、防抖

    目录 节流 解释 手写实现 全部计时器实现 Date now 时间戳实现 混合 防抖 解释 手写实现 节流 解释 节流 throttle 是指让某一个函数的触发次数在一定时间内限定在一定范围内 最常的情况是一定时间内只触发最初的一次 常用在
  • 01_Numpy的图片处理(读取,变换,保存)

    Numpy的图片处理 读取 变换 保存 使用Numpy的ndarray可以读取图片文件 并且可以对图片进行各种各样的处理 例如 图片像素值的读取 替换 随机剪裁 拼接等等都可以使用ndarray 对于已经习惯使用Numpy的人们来说 已经可