图像处理

图像处理

写在博客前面

图像处理的内容没有任何头绪,只能借助材料学习,把链接放在下面,同学们可以共同学习。
https://www.cnblogs.com/zyp4614/p/6917943.html
https://blog.csdn.net/jemenchen/article/details/52658476
https://479001499.iteye.com/blog/2078110

首先了解图像结构

要讲图片格式还先得从图像的基本数据结构说起。在计算机中, 图像是由一个个像素点组成,像素点就是颜色点,而颜色最简单的方式就是用RGB或RGBA表示, 如图所示
图像处理
R,G,B每个分量一般是用一个字节来表示,所以图中每个像素大小就是24位图。
同样有R,G,B,A四个分量,每个像素位为32位图

需要注意的是

一、图像y方向正立或倒立
图像是二维数据,数据在内存中只能一维存储,二维转一维有不同的对应方式。比较常见的只有两种方式: 按像素“行排列”从上往下或者从下往上。
按照我的理解如上图:从上往下为123456789,从下往上读取为789456123
这两种的区别在于取得坐标轴不同,两者可以进行互相转换。
y2 = height-1-y1 y1,y2分别为像素在两个坐标系中的y坐标,height为图像的高度。
二、RGB排列顺序
不同图形库中每个像素点中RGBA的排序顺序可能不一样。上面说过像素一般会有RGB,或RGBA四个分量,那么在内存中RGB的排列就有6种情况
这个排列组合很好理解,

BMP格式

bmp格式没有压缩像素格式,存储在文件中时先有文件头、再图像头、后面就都是像素数据了,上下颠倒存储。
用windows自带的mspaint工具保存bmp格式时,可以发现有四种bmp可供选择:
单色: 一个像素只占一位,要么是0,要么是1,所以只能存储黑白信息
16色位图: 一个像素4位,有16种颜色可选
256色位图: 一个像素8位,有256种颜色可选
24位位图: 颜色可有2^24种可选,对于人眼来说完全足够

代码

# -*- coding: UTF-8 -*-
from struct import unpack

# 读取并存储 bmp 文件
class ReadBMPFile :
    def __init__(self, filePath) :
        file = open(filePath, "rb")
        # 读取 bmp 文件的文件头    14 字节
        self.bfType = unpack("<h", file.read(2))[0]       # 0x4d42 对应BM 表示这是Windows支持的位图格式
        self.bfSize = unpack("<i", file.read(4))[0]       # 位图文件大小
        self.bfReserved1 = unpack("<h", file.read(2))[0]  # 保留字段 必须设为 0 
        self.bfReserved2 = unpack("<h", file.read(2))[0]  # 保留字段 必须设为 0 
        self.bfOffBits = unpack("<i", file.read(4))[0]    # 偏移量 从文件头到位图数据需偏移多少字节(位图信息头、调色板长度等不是固定的,这时就需要这个参数了)
        # 读取 bmp 文件的位图信息头 40 字节
        self.biSize = unpack("<i", file.read(4))[0]       # 所需要的字节数
        self.biWidth = unpack("<i", file.read(4))[0]      # 图像的宽度 单位 像素
        self.biHeight = unpack("<i", file.read(4))[0]     # 图像的高度 单位 像素
        self.biPlanes = unpack("<h", file.read(2))[0]     # 说明颜色平面数 总设为 1
        self.biBitCount = unpack("<h", file.read(2))[0]   # 说明比特数
        
        self.biCompression = unpack("<i", file.read(4))[0]  # 图像压缩的数据类型
        self.biSizeImage = unpack("<i", file.read(4))[0]    # 图像大小
        self.biXPelsPerMeter = unpack("<i", file.read(4))[0]# 水平分辨率
        self.biYPelsPerMeter = unpack("<i", file.read(4))[0]# 垂直分辨率
        self.biClrUsed = unpack("<i", file.read(4))[0]      # 实际使用的彩色表中的颜色索引数
        self.biClrImportant = unpack("<i", file.read(4))[0] # 对图像显示有重要影响的颜色索引的数目
        self.bmp_data = []

        if self.biBitCount != 24 :
            print("输入的图片比特值为 :" + str(self.biBitCount) + "\t 与程序不匹配")

        for height in range(self.biHeight) :
            bmp_data_row = []
            # 四字节填充位检测
            count = 0
            for width in range(self.biWidth) :
                bmp_data_row.append([unpack("<B", file.read(1))[0], unpack("<B", file.read(1))[0], unpack("<B", file.read(1))[0]])
                count = count + 3
            # bmp 四字节对齐原则
            while count % 4 != 0 :
                file.read(1)
                count = count + 1
            self.bmp_data.append(bmp_data_row)
        self.bmp_data.reverse()
        file.close()
        # R, G, B 三个通道
        self.R = []
        self.G = []
        self.B = []

        for row in range(self.biHeight) :
            R_row = []
            G_row = []
            B_row = []
            for col in range(self.biWidth) :
                B_row.append(self.bmp_data[row][col][0])
                G_row.append(self.bmp_data[row][col][1])
                R_row.append(self.bmp_data[row][col][2])
            self.B.append(B_row)
            self.G.append(G_row)
            self.R.append(R_row)
上一篇:learning scala How To Create Implicit Function


下一篇:【C#】图片处理(底片,黑白,锐化,柔化,浮雕,雾化)