python处理图片数据?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python处理图片数据?相关的知识,希望对你有一定的参考价值。
请问这种图片是如何生成的?
生成一张纯色的图片
先设置图片的颜色,接着利用Image模块的new方法新生成一张图片,png格式的图片需要设置成rgba,类似的还有rgb,L(灰度图等),尺寸设定为640,480,这个可以根据自己的情况设定,颜色同样如此。
批量生成图片
上面生成了一张图片,那要生成十张图片呢,这种步骤一样,只是颜色改变的,利用循环就可以解决。首先创建一个颜色列表,把要生成的图片颜色放进去。接着循环获取不同的颜色,保存的时候利用字符串拼接的方法改变图片的名字。
本地生成的图片
封装成函数
前面的方法已经可以批量生成图片了,为了通用性强一点,我们可以封装成函数,把哪些可以改变的参数单独抽离出来。尺寸也同样,使用的时候,可以根据自己的需要定义颜色列表和尺寸。当然还有加一些提示用语和报错兼容性,这里就不讲了。
本地生成的图片
参考技术A 目录1.机器是如何存储图像的?
2.在Python中读取图像数据
3.从图像数据中提取特征的方法#1:灰度像素值特征
4.从图像数据中提取特征的方法#2:通道的平均像素值
5.从图像数据中提取特征的方法#3:提取边缘
是一张数字8的图像,仔细观察就会发现,图像是由小方格组成的。这些小方格被称为像素。
但是要注意,人们是以视觉的形式观察图像的,可以轻松区分边缘和颜色,从而识别图片中的内容。然而机器很难做到这一点,它们以数字的形式存储图像。请看下图:
机器以数字矩阵的形式储存图像,矩阵大小取决于任意给定图像的像素数。
假设图像的尺寸为180 x 200或n x m,这些尺寸基本上是图像中的像素数(高x宽)。
这些数字或像素值表示像素的强度或亮度,较小的数字(接近0)表示黑色,较大的数字(接近255)表示白色。通过分析下面的图像,读者就会弄懂到目前为止所学到的知识。
下图的尺寸为22 x 16,读者可以通过计算像素数来验证:
图片源于机器学习应用课程
刚才讨论的例子是黑白图像,如果是生活中更为普遍的彩色呢?你是否认为彩色图像也以2D矩阵的形式存储?
彩色图像通常由多种颜色组成,几乎所有颜色都可以从三原色(红色,绿色和蓝色)生成。
因此,如果是彩色图像,则要用到三个矩阵(或通道)——红、绿、蓝。每个矩阵值介于0到255之间,表示该像素的颜色强度。观察下图来理解这个概念:
图片源于机器学习应用课程
左边有一幅彩色图像(人类可以看到),而在右边,红绿蓝三个颜色通道对应三个矩阵,叠加三个通道以形成彩色图像。
请注意,由于原始矩阵非常大且可视化难度较高,因此这些不是给定图像的原始像素值。此外,还可以用各种其他的格式来存储图像,RGB是最受欢迎的,所以笔者放到这里。读者可以在此处阅读更多关于其他流行格式的信息。
用Python读取图像数据
下面开始将理论知识付诸实践。启动Python并加载图像以观察矩阵:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from skimage.io import imread, imshow
image = imread('image_8_original.png', as_gray=True)
imshow(image)
#checking image shape
image.shape, image
(28,28)
矩阵有784个值,而且这只是整个矩阵的一小部分。用一个LIVE编码窗口,不用离开本文就可以运行上述所有代码并查看结果。
下面来深入探讨本文背后的核心思想,并探索使用像素值作为特征的各种方法。
方法#1:灰度像素值特征
从图像创建特征最简单的方法就是将原始的像素用作单独的特征。
考虑相同的示例,就是上面那张图(数字‘8’),图像尺寸为28×28。
能猜出这张图片的特征数量吗?答案是与像素数相同!也就是有784个。
那么问题来了,如何安排这784个像素作为特征呢?这样,可以简单地依次追加每个像素值从而生成特征向量。如下图所示:
下面来用Python绘制图像,并为该图像创建这些特征:
image = imread('puppy.jpeg', as_gray=True)
image.shape, imshow(image)
(650,450)
该图像尺寸为650×450,因此特征数量应为297,000。可以使用NumPy中的reshape函数生成,在其中指定图像尺寸:
#pixel features
features = np.reshape(image, (660*450))
features.shape, features
(297000,)
array([0.96470588, 0.96470588, 0.96470588, ..., 0.96862745, 0.96470588,
0.96470588])
这里就得到了特征——长度为297,000的一维数组。很简单吧?在实时编码窗口中尝试使用此方法提取特征。
但结果只有一个通道或灰度图像,对于彩色图像是否也可以这样呢?来看看吧!
方法#2:通道的平均像素值
在读取上一节中的图像时,设置了参数‘as_gray = True’,因此在图像中只有一个通道,可以轻松附加像素值。下面删除参数并再次加载图像:
image = imread('puppy.jpeg')
image.shape
(660, 450, 3)
这次,图像尺寸为(660,450,3),其中3为通道数量。可以像之前一样继续创建特征,此时特征数量将是660*450*3 = 891,000。
或者,可以使用另一种方法:
生成一个新矩阵,这个矩阵具有来自三个通道的像素平均值,而不是分别使用三个通道中的像素值。
下图可以让读者更清楚地了解这一思路:
这样一来,特征数量保持不变,并且还能考虑来自图像全部三个通道的像素值。
image = imread('puppy.jpeg')
feature_matrix = np.zeros((660,450))
feature_matrix.shape
(660, 450)
现有一个尺寸为(660×450×3)的三维矩阵,其中660为高度,450为宽度,3是通道数。为获取平均像素值,要使用for循环:
for i in range(0,iimage.shape[0]):
for j in range(0,image.shape[1]):
feature_matrix[i][j] = ((int(image[i,j,0]) + int(image[i,j,1]) + int(image[i,j,2]))/3)
新矩阵具有相同的高度和宽度,但只有一个通道。现在,可以按照与上一节相同的步骤进行操作。依次附加像素值以获得一维数组:
features = np.reshape(feature_matrix, (660*450))
features.shape
(297000,)
方法#3:提取边缘特征
请思考,在下图中,如何识别其中存在的对象:
识别出图中的对象很容易——狗、汽车、还有猫,那么在区分的时候要考虑哪些特征呢?形状是一个重要因素,其次是颜色,或者大小。如果机器也能像这样识别形状会怎么样?
类似的想法是提取边缘作为特征并将其作为模型的输入。稍微考虑一下,要如何识别图像中的边缘呢?边缘一般都是颜色急剧变化的地方,请看下图:
笔者在这里突出了两个边缘。这两处边缘之所以可以被识别是因为在图中,可以分别看到颜色从白色变为棕色,或者由棕色变为黑色。如你所知,图像以数字的形式表示,因此就要寻找哪些像素值发生了剧烈变化。
假设图像矩阵如下:
图片源于机器学习应用课程
该像素两侧的像素值差异很大,于是可以得出结论,该像素处存在显著的转变,因此其为边缘。现在问题又来了,是否一定要手动执行此步骤?
当然不!有各种可用于突出显示图像边缘的内核,刚才讨论的方法也可以使用Prewitt内核(在x方向上)来实现。以下是Prewitt内核:
获取所选像素周围的值,并将其与所选内核(Prewitt内核)相乘,然后可以添加结果值以获得最终值。由于±1已经分别存在于两列之中,因此添加这些值就相当于获取差异。
还有其他各种内核,下面是四种最常用的内核:
图片源于机器学习应用课程
现在回到笔记本,为同一图像生成边缘特征:
#importing the required libraries
import numpy as np
from skimage.io import imread, imshow
from skimage.filters import prewitt_h,prewitt_v
import matplotlib.pyplot as plt
%matplotlib inline
#reading the image
image = imread('puppy.jpeg',as_gray=True)
#calculating horizontal edges using prewitt kernel
edges_prewitt_horizontal = prewitt_h(image)
#calculating vertical edges using prewitt kernel
edges_prewitt_vertical = prewitt_v(image)
imshow(edges_prewitt_vertical, cmap='gray')
Python数据分析与挖掘————图像的处理
系列文章目录
文章目录
前言
在大数据流行的今天,对数据的处理以及分析都成了至关重要的方面。二我们这节所要学的就是对图片的处理。利用代码去处理一些图片。以及认识图片的本质。
图片的马赛克
我们都知道,在生活中我们有时候为了不暴露我们的信息。照片有时就会用马赛克的方式来隐藏我们的基本面貌信息。虽然现在手机推出了很多的软件可以对图片进行马赛克处理,但是大多数的软件马赛克都是已经设定好的,无法更改他们的值。而今天我们就可以用到Python中的matplotlib模块来实现图片的马赛克。
一.安装matplotlib,numpy等模块
python的编写有人用的时VS code,也有pycharm编译器。这里介绍vs code编译器。
一.按住win+R键,打开控制端,输入cmd命令;
二.在打开的用户控制界面输入pip install [模块]
命令;
如上图一样,将需要下载的模块输入,下载成功后就可以使用模块。而对于使用pycharm编译器的同学,就打开pycharm的终端,输入pip install [模块]
就可以了。
三.使用模块
我们主要使用的时matplotlib中的image,故我们导入模块;
import matplotlib.image as mpimg
import math
import numpy as np
import matplotlib.pyplot as plt
导入模块后,我们就可以进行图片的处理了.
二.马赛克图片
一.导入图片
matplotlib.image中的imread()函数就是用来读取图片的编码的。我们可以提前将要使用的图片放在该目录下,也可直接导入,这里博主就使用上次爬虫得到的图片。具体的图片你自己根据自己的情况来定
data_jpg=mpimg.imread('D:\\CSDN图片\\work.jpg') #导入图片,解码
我们打印一下他的值,我们会发现图片解码后就是一个三维数组。而我们对他的操作都是这个数组的操作。
二.定位区域
我们对需要打马赛克的位置进行定位,(imshow()函数
)
我们会发现我们导入的图片的周围出现了刻度,我们可以根据他上面的刻度来估计我们要进行打码的位置。找到打码的位置后,进行切割;
data1=data_jpg[50:320,150:350]
然后我们就会得到一个经过切割过的图片。我们现在就对这张图片进行像素进行细分割。
data1=data1[::27,::40]
根据自己的需要,定义分割的值,这里就表示了把图片的像素以27(y轴),40(x轴)的间隔进行切割为一个像素。就会形成马赛克。
三.图片的合成
最后将上面已经马赛克化的图片区域拷贝到原图片中就可以了;
for i in range(10):
for j in range(5):
data2[50+27*i:50+27+27*i,150+40*j:150+40+40*j]=data1[i,j]
最后,将图片显示出来就可以了,如果需要保存,就使用savefig()
函数即可;
现在我们来看看最后的效果;
源代码展示;
import matplotlib.image as mpimg
import math
import numpy as np
import matplotlib.pyplot as plt
data_jpg=mpimg.imread('D:\\CSDN图片\\work.jpg')
#plt.imshow(data_jpg)
#马赛克;
data2=data_jpg.copy()
data1=data_jpg[50:320,150:350]
#plt.imshow(data1)
data1=data1[::27,::40]
#plt.imshow(data1)
for i in range(10):
for j in range(5):
data2[50+27*i:50+27+27*i,150+40*j:150+40+40*j]=data1[i,j]
plt.imshow(data2)
图片拼接
python中队图片的处理,除了可以打马赛克,还可以对其进行变色,虚拟化,灰图像处理,图片拼接等功能;
concatenate()函数
图片的拼接就是用concatenate()函数实现;
import matplotlib.image as mpimg
import math
import numpy as np
import matplotlib.pyplot as plt
data_jpg=mpimg.imread('D:\\CSDN图片\\work.jpg')
data3=np.concatenate([data_jpg,data_jpg],axis=1)
plt.imshow(data3)
图像的灰度化
一.max()方法
上文提到的,图片的组成就是一个三维数组,其中的数字代表了他们的图像特点。所以,图像的灰度化,也就可以通过改变他们的位置,值,维度来改变图片的颜色,形状.
我们可以看下面的例子;
import matplotlib.image as mpimg
import math
import numpy as np
import matplotlib.pyplot as plt
data_jpg=mpimg.imread('D:\\CSDN图片\\work.jpg')
print(data_jpg)
[[[215 221 211]
[215 221 211]
[215 221 211]
...
[204 189 182]
[203 188 181]
[202 187 180]]
[[215 221 211]
[215 221 211]
[215 221 211]
...
[204 189 182]
[203 188 181]
[202 187 180]]
[[215 221 211]
[215 221 211]
[215 221 211]
...
[204 189 182]
[203 188 181]
[201 186 179]]
...
...
...
[188 150 137]
[189 151 138]
[189 151 138]]]
data_jpg=mpimg.imread("D:\\CSDN图片\\work.jpg")
#最大值法;
s=np.max(data_jpg,axis=-1)#axis取-1就是为了得到最里面的值;
plt.imshow(s,cmap='gray') #cmap参数表示最后的颜色,gray时灰色;
效果展示;
二.min()方法
和max()方法相似,所以这里不做过多的介绍,就直接粘贴代码;
data_jpg=mpimg.imread("D:\\CSDN图片\\work.jpg")
sss=np.min(data_jpg,axis=-1)
plt.imshow(sss,cmap='gray')
三.平均值法mean()函数
data_jpg=mpimg.imread("D:\\CSDN图片\\work.jpg")
#最大值法;
s=np.max(data_jpg,axis=-1)
plt.imshow(s,cmap='gray')
效果展示;
和上面的方法所得出的效果基本相似。所以,掌握其中一种方法即可.
四.加权平均值法
和平均值法不一样的是,加权平均值法可以根据自己给的数据不同的灰度化;
data_jpg=mpimg.imread("D:\\CSDN图片\\work.jpg")
weight=[0.01,0.01,0.01] #这里的值自己更改,值越大,灰度化颜色偏深,反之则偏浅.
ss=np.dot(data_jpg,weight)
plt.imshow(ss,cmap='gray')
图片的分割
有时候我我们只需要图片其中的一小部分,那我们就可以通过分割函数split()
函数来实现;
one,data4,two=np.split(data_jpg,indices_or_sections=[100,400],axis=1) #中间的参数表示我们分割的区间;
plt.imshow(data4)
plt.imshow(one)
plt.imshow(two)
效果展示;
总结
本节我要介绍的就这些了,对于图片的处理还有很多的方式,这里就先不过多的介绍,后面我会继续更新。利用代码实现图片的处理,会有很大的灵活使用空间,不局限于手机软件的限制,所以掌握这些方式也是有很大的益处.
源代码放在了下面,有兴趣的同学可以看一下.
源代码
import matplotlib.image as mpimg
import math
import numpy as np
import matplotlib.pyplot as plt
data=mpimg.imread("./onetemp.jpg")
data1=data.copy()
#打马赛克;
#第一步,找出要打马赛克的位置;
data2=data1[200:900,100:800]
#第二步,将图片比例的收缩;
data2=data2[::35,::35]
print(data2.shape)
datatemp=data1.copy()
#第三步,替换,将现有的替换到原来的,记住两个尺寸不一样;
for i in range(20):
for j in range(20):
datatemp[200+35*i:200+35*i+35,100+35*j:100+35*j+35]=data2[i,j]
plt.imshow(datatemp)
#图片的拼接;
data4=np.concatenate([data,data])#axis=1时,并排着;
plt.imshow(data4)
data5=np.concatenate([data,data],axis=1)
plt.imshow(data5)
#图片切割;
one,two,three=np.split(data,indices_or_sections=[400,600],axis=1)
plt.imshow(one)
plt.imshow(two)
plt.imshow(three)
#图像灰度化;
#第一种方法,最小值法;
data=mpimg.imread('./onetemp.jpg')
#data=np.min(data,axis=-1)
#plt.imshow(data,cmap='gray')
#第二种方法,最小值法;
data1=np.max(data,axis=-1)
#plt.imshow(data1,cmap='gray')
#第三种,平均值法;
data3=np.mean(data,axis=-1)#等价于data.mean()函数;
#plt.imshow(data3,cmap='gray')
#第四种方法,加权平均值法,dot函数;
weight=[0.299,0.345,0.456]
data6=np.dot(data,weight)
plt.imshow(data6,cmap='gray')
data_jpg=mpimg.imread('D:\\CSDN图片\\work.jpg')
print(data_jpg)
#plt.imshow(data_jpg)
#马赛克;
data2=data_jpg.copy()
data1=data_jpg[50:320,150:350]
#plt.imshow(data1)
data1=data1[::27,::40]
#plt.imshow(data1)
for i in range(10):
for j in range(5):
data2[50+27*i:50+27+27*i,150+40*j:150+40+40*j]=data1[i,j]
plt.imshow(data2)
#照片的合集;
import matplotlib.image as mpimg
import math
import numpy as np
import matplotlib.pyplot as plt
data_jpg=mpimg.imread('D:\\CSDN图片\\work.jpg')
data3=np.concatenate([data_jpg,data_jpg],axis=1)
plt.imshow(data3)
#图片的切割;
one,data4,two=np.split(data_jpg,indices_or_sections=[100,400],axis=1)
plt.imshow(data4)
#plt.imshow(one)
#plt.imshow(two)
#图像的灰度化;
data_jpg=mpimg.imread("D:\\CSDN图片\\work.jpg")
#最大值法;
s=np.max(data_jpg,axis=-1)
plt.imshow(s,cmap='gray')
#加权平均值法;
data_jpg=mpimg.imread("D:\\CSDN图片\\work.jpg")
weight=[0.31,0.41,0.53]
ss=np.dot(data_jpg,weight)
plt.imshow(ss,cmap='gray')
#平均值法;
smp=np.mean(data_jpg,axis=-1)
plt.imshow(smp,cmap='gray')
#最小值法;
sss=np.min(data_jpg,axis=-1)
plt.imshow(sss,cmap='gray')
以上是关于python处理图片数据?的主要内容,如果未能解决你的问题,请参考以下文章