编程学习网 > 编程语言 > Python > 利用python进行png图片的读取操作
2021
07-10

利用python进行png图片的读取操作


利用python进行png图像的读写操作,有需要的朋友可以参考一下:

最近遇到了对png灰度图像进行读取,并统计图像中众数的需求,现将代码记录如下。ps:适用于单波段图,形如(X,Y)。

1.导入需要的包
import matplotlib.pyplot as plt # 绘图
import matplotlib.image as mpimg # 显示图像
import numpy as np # 处理数据
from scipy.stats import mode # 统计操作

2.架构框架
主要思路为,先利用matplotlib读取多张图像,并转换为多个2维数组,再通过拼接多个2维数组到3维,实现单波段到多波段图像的转变,最后利用mode函数挑出多波段图片中的众数,返回一个单波段png图片。

class png_mode:
    '''
    png_mode类 用于多张单波段png格式图片组合取众数,最后生成一张由多组众数生成的单波段png图片
    read_picture 可读取图片
    join_picture 可令单波段图片组合成多波段图片
    mode_picture 可取得多波段图片众数
    show_picture 可显示并保存众数结果
    '''
    def __init__(self,picture_path,picture_count):
        pass

    def read_picture(self):
        pass

    def join_picture(self):
        pass

    def mode_picture(self):
        pass

    def show_picture(self):
       pass

写了5个函数进行类的定义,通过上述框架进行需求实现。

3.__init__函数
__init__函数一般定义需要键入的常量,这里选择picture_path和picture_count传入,分别代表图片具体路径和图片张数。picture_path为多个图片路径字符串组成的列表(懒的用os和正则直接读png了),picture_count为整形。

    def __init__(self,picture_path,picture_count):
        self.picture_path = picture_path
        self.picture_count = picture_count

4.read_picture函数
read_picture函数实现原始png图片的读取操作。pictures主要储存读取的图片结果,利用循环和mping.imread函数读取图片。

    def read_picture(self):
        pictures = []
        for i in range(0,self.picture_count):
            pictures.append(mpimg.imread(self.picture_path[i]))
        return pictures

5.join_picture函数
join_picture函数可以把pictures中的图片深度拼接在一起,也就是把单波段图拼接为多波段图,形如(X,Y,Z)其中Z为图片张数。本次实验所用单张图片规格为(1804,2181),这个函数可以通过dstack把多张(1804,2181)规格的图片转换为(1804,2181,n)的图片。

    def join_picture(self):
        new_picture = self.read_picture()[0]
        for j in range(0,self.picture_count-1):
            new_picture = np.dstack((new_picture,self.read_picture()[j+1]))
        self.new_picture = new_picture
        return new_picture

ps:利用dstack可以进行深度拼接。
例:

 a = np.array([[1],[2],[3]])
 b = np.array([[2],[3],[4]])
 np.dstack((a,b))
# 结果
array([[[1, 2]],
       [[2, 3]],
       [[3, 4]]])

6.mode_picture函数
利用mode_picture函数可以求得形如(1804,2181,n)图片的众数,也就是所有n个波段在每个点处的众数,最终会出一张(1804,2181,1)的图片。

    def mode_picture(self):
        new_picture1 = []
        for i in self.join_picture():
            new_picture1.append(mode(i, axis=1)[0])
        new_picture1 =np.array(new_picture1).reshape(np.array(new_picture1).shape[0],np.array(new_picture1).shape[1])
        return new_picture1

ps:关于mode函数

a = np.array([[6, 8, 3, 0],
                  [3, 2, 1, 7],
                  [8, 1, 8, 4],
                  [5, 3, 0, 5],
                  [4, 7, 5, 9]])

print(mode(a))

返回值如下

ModeResult(mode=array([[3, 1, 0, 0]]), count=array([[1, 1, 1, 1]]))


前面数组mode=array([[3, 1, 0, 0]])表示每一列的众数,如果没有则返回最小值,后一列count=array([[1, 1, 1, 1]]表示出现的次数。通过axis可以变换求众数的方向,当axis为None时,可以求得整个数组的众数。

a = np.array([[6, 8, 3, 0],
                  [3, 2, 1, 7],
                  [8, 1, 8, 4],
                  [5, 3, 0, 5],
                  [4, 7, 5, 9]])

print(mode(a,axis=1))

返回值如下

ModeResult(mode=array([[0],
       [1],
       [8],
       [5],
       [4]]), count=array([[1],
       [1],
       [2],
       [2],
       [1]]))

7.show_picture函数
show_picture函数可以打印并保存最后的结果。

    def show_picture(self):
        plt.subplot(221)
        plt.imshow(self.new_picture[:,:,0])
        plt.subplot(222)
        plt.imshow(self.new_picture[:,:,1])
        plt.subplot(223)
        plt.imshow(self.new_picture[:,:,2])
        plt.subplot(224)
        plt.imshow(self.mode_picture())
        plt.axis('off')
        plt.savefig(r'C:\Users\Administrator\Desktop\tiff\jpg\212.png',dpi=300)
        plt.show()

这里我用的是3张图做例,所以出了一张4子图的结果图,可根据要求随时修改。

8.完整代码及结果展示
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
from scipy.stats import mode

class png_mode:
    '''
    png_mode类 用于多张单波段png格式图片组合取众数,最后生成一张由多组众数生成的单波段png图片
    read_picture 可读取图片
    join_picture 可令单波段图片组合成多波段图片
    mode_picture 可取得多波段图片众数
    show_picture 可显示并保存众数结果
    picture_path 为字符串类型,图片路径
    picture_count 为整数类型,图片张数
    '''
    def __init__(self,picture_path,picture_count):
        self.picture_path = picture_path
        self.picture_count = picture_count

    def read_picture(self):
        pictures = []
        for i in range(0,self.picture_count):
            pictures.append(mpimg.imread(self.picture_path[i]))
        return pictures

    def join_picture(self):
        new_picture = self.read_picture()[0]
        for j in range(0,self.picture_count-1):
            new_picture = np.dstack((new_picture,self.read_picture()[j+1]))
        self.new_picture = new_picture
        return new_picture

    def mode_picture(self):
        new_picture1 = []
        for i in self.join_picture():
            new_picture1.append(mode(i, axis=1)[0])
        new_picture1 =np.array(new_picture1).reshape(np.array(new_picture1).shape[0],np.array(new_picture1).shape[1])
        return new_picture1

    def show_picture(self):
        plt.subplot(221)
        plt.imshow(self.new_picture[:,:,0])
        plt.subplot(222)
        plt.imshow(self.new_picture[:,:,1])
        plt.subplot(223)
        plt.imshow(self.new_picture[:,:,2])
        plt.subplot(224)
        plt.imshow(self.mode_picture())
        plt.axis('off')
        plt.savefig(r'C:\Users\Administrator\Desktop\tiff\jpg\212.png',dpi=300)
        plt.show()

a = [r'C:\Users\Administrator\Desktop\tiff\jpg\tif1.png',r'C:\Users\Administrator\Desktop\tiff\jpg\11.png',r'C:\Users\Administrator\Desktop\tiff\png\sanyue2.png']
b = png_mode(a,3)
b.read_picture()
b.join_picture()
b.mode_picture()
b.show_picture()


最后再放张多图成果:

over
以上就是“利用python进行png图片的读取操作”的详细内容,想学习更多Python教程请持续关注编程学习网!

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取