文章目录

  • 1、PIL与Matplotlib
  • 1.1 图像的显示
  • 1.2 基本图像操作
  • 1.3 绘制点、线
  • 2、numpy
  • 2.1 对图像像素值进行处理
  • 2.2 直方图均衡
  • 2.3 图像平均
  • 2.4 PCA
  • 3、Scipy
  • 3.1 图像模糊
  • 3.2 图像导数
  • 3.3 形态学:对象计数
  • 4、图像去噪


1、PIL与Matplotlib

1.1 图像的显示

一般,图像的显示方法有两种,一种img.show()的方式将图像显示出来,这种方法只能利用电脑上的图片等进行观察,另一种方法是使用 plt.imshow() 方法进行画图,它在显示可以将灰度图像按照灰度值的高低映射成彩色图像。

#法一
from PIL import Image
img=Image.open('d:/imdata/coins.png')
img.show()
#法二
from PIL import Image
import matplotlib.pyplot as plt
img=Image.open('d:/coins.png')
plt.figure("coins") 
plt.imshow(img)
plt.show()

python灰度图怎么变成彩色 python 灰度图像转彩色_去噪


如上图,经过matplotlib工具提供的函数进行图像显示时,灰度图会被映射为彩色图像。要想显示出灰度图像,只需将plt.imshow(img)改为plt.imshow(img,cmap=‘gray’)即可。

python灰度图怎么变成彩色 python 灰度图像转彩色_python灰度图怎么变成彩色_02

1.2 基本图像操作

借助python工具,我们可以对图像进行一些简单的处理,如旋转、调整图像尺寸、反向处理、灰度变换、复制粘贴等等。

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

img =Image.open('d:/imdata/onion.png')
plt.figure()# 子图
plt.subplot(231)# 原图
plt.imshow(img)
plt.subplot(232)# 将图像缩放至 256 * 256
plt.imshow(img.resize((256, 256)))
plt.subplot(233)# 将图像转为灰度图
plt.imshow(img.convert('L'),cmap='gray')
plt.subplot(234)# 旋转图像
plt.imshow(img.rotate(45))
img2 =255-array(Image.open('d:/imdata/onion.png'))
plt.subplot(235)
plt.imshow(img2)
#复制图像某一区域
box=(50,50,100,100)
region=img.crop(box)
#旋转后粘贴到原区域
region=region.transpose(Image.ROTATE_180)
img.paste(region,box)
plt.subplot(236)
plt.imshow(img)
plt.show()

python灰度图怎么变成彩色 python 灰度图像转彩色_去噪_03

1.3 绘制点、线

可以用plot()函数进行点、线的绘制。如:

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

#读取图像到数组中并绘制图像
im=array(Image.open('d:\imdata\onion.png'))
plt.imshow(im) 
#选取一些点用红色星来标记
x=[50,50,100,100]
y=[50,100,50,100]
plt.plot(x, y, 'r*')
#绘制连接前两个点的线,默认蓝色
plt.plot(x[:2],y[:2])
plt.show()

python灰度图怎么变成彩色 python 灰度图像转彩色_ci_04

2、numpy

numpy工具可以将图像转为数组对象,方便我们进行后续操作,是非常有用的一个工具包。

2.1 对图像像素值进行处理

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

im=array(Image.open('d:\imdata\onion.png').convert('L'))
plt.subplot(131)
plt.imshow(im,cmap='gray') 
#将图像像素值变换到200~250之间
im2=(50/255)*im+200
plt.subplot(132)
plt.imshow(im2,cmap='gray')
#对图像像素值求平方后得到的图像
im3=255*(im/255)**2
plt.subplot(133)
plt.imshow(im3,cmap='gray')
#array()变换的反操作,用fromarray()函数完成 
pil_im=Image.fromarray(im)
plt.show()

python灰度图怎么变成彩色 python 灰度图像转彩色_python灰度图怎么变成彩色_05

2.2 直方图均衡

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

def histeq(im, nbr_bins=256):
    # 计算图像直方图
    imhist, bins = histogram(im.flatten(), nbr_bins, normed=True)
    # 累计分布函数
    cdf = imhist.cumsum()
    cdf = 255 * cdf / cdf[-1]
    im2 = interp(im.flatten(), bins[:-1], cdf)
    return im2.reshape(im.shape), cdf

im = array(Image.open('d:/imdata/onion.png').convert('L'))
im2,cdf=histeq(im)
#显示中文
plt.rcParams['font.sans-serif']=['SimHei']
plt.figure()
plt.subplot(2, 2, 1)
plt.axis('off')
plt.gray()
plt.title("原始图像")
plt.imshow(im)

plt.subplot(2, 2, 2)
plt.axis('off')
plt.title("直方图均衡化后的图像")
plt.imshow(im2)

plt.subplot(2, 2, 3)
plt.axis('off')
plt.title("原始直方图")
plt.hist(im.flatten(), 128, density=True)

plt.subplot(2, 2, 4)
plt.axis('off')
plt.title("均衡化后的直方图")
plt.hist(im2.flatten(), 128, density=True)
plt.show()

python灰度图怎么变成彩色 python 灰度图像转彩色_去噪_06

2.3 图像平均

图像平均操作是减少图像噪声的一个简单方式,对于一些具有相同大小的图像,我们可以将其相加,然后除以图像的数目,就可以得到平均图像。

def compute_average(imlist):
    averageim=array(Image.open(imlist[0]),’f’)
    for inname in imlist[1:]:
      try:
        averageim+=array(Image.open(imname))
      except:
        print  imname + ‘....skipped’
    averageim/=len(imlist)
    return array(averageim,’uint8’)

2.4 PCA

PCA是一个非常有用的降维技巧,它可以在使用尽可能少维数的前提下尽量多的保持训练数据的信息。

def  pca(X):
     #获取维数
    num_data,dim=X.shape
    #数据中心化
    mean_X=X.mean(axis=0)
    X=X-mean_X
    if dim>num_data:
        #矩阵相乘
        M=dot(X,X.T)
        #求特征值、特征向量
        e,EV=linalg.eigh(M)
        tmp=dot(X.T,EV).T
        V=tmp[::-1]
        S=sqrt(e)[::-1]
        for i in range(V.shape[1]):
            V[:,i]/=S
    else:
        U,S,V=linalg.svd(X)
        V=V[:num_data]
    return V,S,mean_X

3、Scipy

scipy提供了很多高效的操作,可以实现数值积分、优化、统计、信号处理等,对我们来说是一个非常重要的工具包。

3.1 图像模糊

高斯模糊是非常经典的图像卷积例子,在其他图像处理操作中也经常出现,下面给大家展示一下。

from PIL import Image
from matplotlib import pyplot as plt
from numpy import *
from scipy.ndimage import filters
#灰度图像
img=array(Image.open('d:/imdata/onion.png').convert('L'))
#后一个参数表示标准差
img2=filters.gaussian_filter(img,5)

#彩色图像
im=array(Image.open('d:/imdata/onion.png'))
im2=zeros(im.shape)
for i in range(3):
    im2[:,:,i]=filters.gaussian_filter(im[:,:,i],5)
im2=uint8(im2)
#显示中文
plt.rcParams['font.sans-serif']=['SimHei']
plt.figure()
plt.subplot(2, 2, 1)
plt.title("原始图像")
plt.imshow(img,cmap='gray')

plt.subplot(2, 2, 2)
plt.title("模糊后的图像")
plt.imshow(img2,cmap='gray')

plt.subplot(2, 2, 3)
plt.title("原始图像")
plt.imshow(im)

plt.subplot(2, 2, 4)
plt.title("模糊后的图像")
plt.imshow(im2)
plt.show()

python灰度图怎么变成彩色 python 灰度图像转彩色_Image_07

3.2 图像导数

Scipy模块提供了prewitt、sobel等滤波器,可以比较容易的求出图像的导数。这些算子我们在学习数字图像处理时已经了解过了,在这里就不再一一阐述。

from PIL import Image
from matplotlib import pyplot as plt
from numpy import *
from scipy.ndimage import filters
im=array(Image.open('d:/imdata/onion.png').convert('L'))
#sobel
imx=zeros(im.shape)
#第二个参数表示选择x或y方向导数
filters.sobel(im,1,imx)
imy=zeros(im.shape)
filters.sobel(im,0,imy)
magniyude=sqrt(imx**2+imy**2)

plt.rcParams['font.sans-serif']=['SimHei']
plt.figure()
plt.subplot(2, 2, 1)
plt.title("原始图像")
plt.imshow(im,cmap='gray')

plt.subplot(2, 2, 2)
plt.title("x导数图像")
plt.imshow(imx,cmap='gray')

plt.subplot(2, 2, 3)
plt.title("y导数图像")    
plt.imshow(imy,cmap='gray')

plt.subplot(2, 2, 4)
plt.title("梯度图像")
plt.imshow(magniyude,cmap='gray')
plt.show()

python灰度图怎么变成彩色 python 灰度图像转彩色_ci_08

3.3 形态学:对象计数

形态学通常用于处理二值图像。scipy.ndmage的morphology模块可以实现形态学操作、measurements模块可以实现二值图像的计数和度量功能。

im=array(Image.open('d:/imdata/onion.png').convert('L'))
im=1*(im<128)
labels,nbr_objects=measurements.label(im)
print "Number of objects:",nbr_objects
#开操作
im_open=morphology.binary_opening(im,ones((9,5)),iterations=2)
labels_open,nbr_objects_open=measurements.label(im_open)
print "Number of objects:",nbr_objects_open

4、图像去噪

图像去噪是在去除图像噪声的同时,尽可能地保留图像细节和结构的处理技术。图像去噪对于很多应用来说都非常重要。我们这里使用 ROF(Rudin-Osher-Fatemi)去噪模型,ROF 模型具有很好的性质:使处理后的图像更平滑,可同时保持图像边缘和结构信息。

from matplotlib import pyplot as plt
from numpy import *
from numpy import random
from scipy.ndimage import filters
def denoise(im,U_init,tolerance=0.1,tau=0.125,tv_weight=100):
    m,n=im.shape#噪声图像的大小
    U=U_init
    Px=im
    Py=im
    error=1
    while(error>tolerance):
        Uold=U
        GradUx=roll(U,-1,axis=1)-U
        GradUy = roll(U, -1, axis=0) - U
        Pxnew=Px+(tau/tv_weight)*GradUx
        Pynew = Py + (tau / tv_weight) * GradUy
        NormNew=maximum(1,sqrt(Pxnew**2+Pynew**2))
        Px=Pxnew/NormNew
        Py = Pynew / NormNew
        RxPx=roll(Px,1,axis=1)
        RyPy=roll(Py,1,axis=0)
        DivP=(Px-RxPx)+(Py-RyPy)
        U=im+tv_weight*DivP
        error=linalg.norm(U-Uold)/sqrt(n*m)
    return U,im-U
im=zeros((500,500))
im[100:400,100:400]=128
im[200:300,200:300]=255
im=im+30*random.standard_normal((500,500))     
U,T=denoise(im,im)
G=filters.gaussian_filter(im,10)

plt.rcParams['font.sans-serif']=['SimHei']
plt.figure()
plt.subplot(1, 3, 1)
plt.title("原始图像")
plt.imshow(im,cmap='gray')

plt.subplot(1, 3, 2)
plt.title("rof去噪图像")
plt.imshow(U,cmap='gray')

plt.subplot(1, 3, 3)
plt.title("高斯去噪图像")
plt.imshow(G,cmap='gray')
plt.show()

python灰度图怎么变成彩色 python 灰度图像转彩色_Image_09


可以发现,经过rof去噪的图像的边缘依然很清晰,而经过高斯去噪的图像的边缘就很难分辨了。