图像处理与Linux编程基础

图像处理与Linux编程基础 目录一、BMP图像1. 文件整体结构2. 位图头文件数据结构3. 位图信息数据结构4. 调色板5. 位图数据6. 要点二、JPEG图像1. 文件格式2. 标记定义三、YUV图像1. 文件结构2. 转换公式与要点四、图像缩放五、makefile编写六、Linux多线程编程1. 线程的概念2. POSIX线程3. 几个最基本的库函数4. 编译要点七、信号量八、进程间通信1. 命名管道FIFO命名管道的创建命名管道的访问一、BMP图像1. 文件整体结构典型的BMP图像文件由四部分组成位图头文件数据结构包含BMP图像文件的类型、显示内容等信息位图信息数据结构包含BMP图像的宽、高、压缩方法以及定义颜色等信息调色板可选部分有些位图需要调色板有些位图如真彩色图24位的BMP不需要调色板位图数据根据BMP位图使用的位数不同而不同24位图中直接使用RGB其他小于24位的使用调色板中颜色索引值。2. 位图头文件数据结构共14字节含有BMP文件的类型、文件大小和位图起始位置等信息结构体声明如下typedefstructtagBITMAPFILEHEADER{ushort u16bfType;// 位图文件的类型必须为BM1-2字节uint u32bfSize;// 位图文件的大小以字节为单位3-6字节低位在前ushort u16bfReserved1;// 位图文件保留字必须为07-8字节ushort u16bfReserved2;// 位图文件保留字必须为09-10字节uint u32bfOffBits;// 位图数据的起始位置以相对于位图11-14字节低位在前}__attribute__((packed))BITMAPFILEHEADER;3. 位图信息数据结构共40字节用于说明位图的尺寸等信息结构体声明如下typedefstructtagBITMAPINFOHEADER{uint u32biSize;// 本结构所占用字节数15-18字节uint u32biWidth;// 位图的宽度以像素为单位19-22字节uint u32biHeight;// 位图的高度以像素为单位23-26字节ushort u16biPlanes;// 目标设备的级别必须为127-28字节ushort u16biBitCount;// 每个像素所需的位数必须是1双色、416色、8256色、16高彩色或24真彩色之一29-30字节uint u32biCompression;// 位图压缩类型必须是0不压缩、1BI_RLE8压缩类型或2BI_RLE4压缩类型之一31-34字节uint u32biSizeImage;// 位图的大小以字节为单位其中包含了为了补齐行数是4的倍数而添加的空字节35-38字节uint u32biXPelsPerMeter;// 位图水平分辨率每米像素数39-42字节uint u32biYPelsPerMeter;// 位图垂直分辨率每米像素数43-46字节uint u32biClrUsed;// 位图实际使用的颜色表中的颜色数47-50字节uint u32biClrImportant;// 位图显示过程中重要的颜色数51-54字节}__attribute__((packed))BITMAPINFOHEADER;4. 调色板用于说明位图中的颜色有若干个表项每一个表项是一个RGBQUAD类型的结构定义一种颜色。RGBQUAD结构的定义如下typedefstructtagRGBQUAD{uchar u8rgbBlue;// 蓝色的亮度值范围为0-255uchar u8rgbGreen;// 绿色的亮度值范围为0-255uchar u8rgbRed;// 红色的亮度值范围为0-255uchar u8rgbReserved;// 保留必须为0}__attribute__((packed))RGBQUAD;颜色表中RGBQUAD结构数据的个数由biBitCount来确定当biBitCount1时有2个表项当biBitCount4时有16个表项当biBitCount8时有256个表项当biBitCount24时没有颜色表项位图信息头和颜色表组成位图信息BITMAPINFO结构定义如下typedefstructtagBITMAPINFO{BITMAPINFOHEADER bmiHeader;// 位图信息头RGBQUAD bmiColors[1];// 颜色表}__attribute__((packed))BITMAPINFO;5. 位图数据位图数据记录了位图的每一个像素值记录顺序是在扫描行内是从左到右扫描行之间是从下到上。位图的一个像素值所占的字节数当biBitCount1时8个像素占1个字节当biBitCount4时2个像素占1个字节当biBitCount8时1个像素占1个字节当biBitCount24时1个像素占3个字节按顺序分别为B、G、R结构体声明如下typedefstruct{uchar u8b;uchar u8g;uchar u8r;}RGB;6. 要点由于编译器存在着字节自动对齐的问题声明结构体的时候需要添加__attribute__((packed))让编译器取消自动对齐才会获得正确的大小。使用__attribute__((packed))typedefstructtagBITMAPFILEHEADER{ushort u16bfType;// 位图文件的类型必须为BM1-2字节uint u32bfSize;// 位图文件的大小以字节为单位3-6字节低位在前ushort u16bfReserved1;// 位图文件保留字必须为07-8字节ushort u16bfReserved2;// 位图文件保留字必须为09-10字节uint u32bfOffBits;// 位图数据的起始位置以相对于位图11-14字节低位在前}__attribute__((packed))BITMAPFILEHEADER;// sizeof(BITMAPFILEHEADER) 14不使用__attribute__((packed))typedefstructtagBITMAPFILEHEADER{ushort u16bfType;// 位图文件的类型必须为BM1-2字节uint u32bfSize;// 位图文件的大小以字节为单位3-6字节低位在前ushort u16bfReserved1;// 位图文件保留字必须为07-8字节ushort u16bfReserved2;// 位图文件保留字必须为09-10字节uint u32bfOffBits;// 位图数据的起始位置以相对于位图11-14字节低位在前}BITMAPFILEHEADER;// sizeof(BITMAPFILEHEADER) 16二、JPEG图像1. 文件格式JPEG文件由下面的8个部分组成(1) 图像开始 SOI (Start of Image) 标记标记代码2字节固定值0xFFD8(2) APP0 标记 (Marker)标记代码2字节固定值0xFFE0字段说明APP0长度 (length)2字节①~⑨9个字段的总长度标识符 (identifier)5字节固定值0x4A46494600即字符串JFIF0版本号 (version)2字节一般是0x0102表示JFIF的版本号1.2X和Y的密度单位 (units)1字节0无单位1点数/英寸2点数/厘米X方向像素密度 (X density)2字节Y方向像素密度 (Y density)2字节缩略图水平像素数目 (thumbnail horizontal pixels)1字节缩略图垂直像素数目 (thumbnail vertical pixels)1字节缩略图RGB位图 (thumbnail RGB bitmap)标记段⑨可以包含图像的一个微缩版本存为24位的RGB像素。如果没有微缩图像这种情况更常见则字段⑦和字段⑧的值均为0。(3) APPn 标记 (Markers)其中 n1~15 (任选)标记代码2字节固定值0xFFE1~0xFFEF字段说明APPn长度 (length)2字节①~②2个字段的总长度详细信息 (application specific information)数据长度-2字节内容不定例如Adobe Photoshop生成的JPEG图像中就用了APP1和APP13两个标记段分别存储了一幅图像的副本Exif将数码照片的拍摄参数、缩略图及其他属性信息记录在APP1中。值得注意的是同一APPn标记可以同时出现多个例如用Ps处理过的数码相机拍摄的照片可能会存在2个APP1标记。(4) 一个或者多个量化表 DQT (Define Quantization Table)标记代码2字节固定值0xFFDB最多只能出现4次字段说明量化表长度 (quantization table length)2字节①~③三个字段的总长度量化表号 (quantization table number)1字节量化表 (quantization table)另一种说法为精度及量化表ID1字节高4位精度08位116位低4位量化表ID取值范围为0~3表项64×(精度1)字节例如8位精度的量化表其表项长度为64×(01)64字节查不到更多资料无法分辨哪一种是正确的。(5) 帧图像开始 SOF0 (Start of Frame)标记代码2字节固定值0xFFC0字段说明帧开始长度 (start of frame length)2字节①~⑥六个字段的总长度精度 (precision)1字节每个颜色分量每个像素的位数通常是8位图像高度 (image height)2字节图像高度单位像素如果不支持DNL就必须0图像宽度 (image width)2字节图像宽度单位像素如果不支持DNL就必须0颜色分量数 (number of color components)1字节1灰度图3YCrCb或YIQ4CMYK。JFIF中使用YCrCb故这里颜色分量数恒为3对每个颜色分量 (for each component)颜色分量数×3字节通常为9字节ID1字节水平/垂直采样因子1字节高4位水平采样因子低4位垂直采样因子量化表号 (quantization table#)1字节字段⑥应该重复出现有多少个颜色分量字段⑤就出现多少次一般为3次。(6) 一个或者多个霍夫曼表 DHT (Define Huffman Table)标记代码2字节固定值0xFFC4字段说明霍夫曼表的长度 (Huffman table length)类型、AC或者DC (Type, AC or DC)索引 (Index)位表 (bits table)值表 (value table)DC表和AC表分开编码。另一种说法为表ID和表类型占1字节高4位类型0DC直流1AC交流低4位哈夫曼表ID。由于查不到更多资料无法得出详细含义。(7) 扫描开始 SOS (Start of Scan)标记代码2字节固定值0xFFDA字段说明扫描开始长度 (start of scan length)2字节①~④两个字段的总长度颜色分量数 (number of color components)1字节应该和SOF中的字段⑤的值相同1灰度图3YCrCb或YIQ4CMYK每个颜色分量ID1字节直流/交流系数表号1字节高4位直流分量使用的哈夫曼树编号低4位交流分量使用的哈夫曼树编号压缩图像数据 (compressed image data)谱选择开始1字节固定值0x00谱选择结束1字节固定值0x3F谱选择1字节在基本JPEG中总为00字段③应该重复出现有多少个颜色分量字段②就出现多少次一般为3次。本段结束后紧接着就是真正的图像信息了。图像信息直至遇到一个标记代码就自动结束一般就是以EOI标记表示结束。(8) 图像结束 EOI (End of Image)标记代码2字节固定值0xFFD9其他可能出现的标记段DRI (Define Restart Interval)定义差分编码累计复位的间隔标记代码2字节固定值0xFFDD包含2个具体字段数据长度2字节固定值0x0004①~②两个字段的总长度MCU块的单元中的重新开始间隔2字节设其值为n则表示每n个MCU块就有一个RSTn标记。第一个标记是RST0第二个是RST1等RST7后再从RST0重复如果没有本标记段或间隔值为0时就表示不存在重开始间隔和标记RST。2. 标记定义如果在图像数据流中遇到0xFF应该检测其紧接着的字符0x00表示0xFF是图像流的组成部分需要进行译码0xD0~0xD7组成RSTn标记则忽视整个RSTn标记即不对当前0xFF和紧接的0xDn两个字节进行译码并按RST标记的规则调整译码变量0xFF忽视当前0xFF对后一个0xFF再作判断其他数值忽视当前0xFF并保留紧接的此数值用于译码符号标记代码说明英文解释原文起始帧标记非分层霍夫曼编码Start Of Frame markers, non-hierarchical Huffman codingSOF00xFFC0基线DCTBaseline DCTSOF10xFFC1扩展顺序DCTExtended sequential DCTSOF20xFFC2逐行DCTProgressive DCTSOF30xFFC3空间顺序无损Spatial (sequential) lossless起始帧标记分层霍夫曼编码Start Of Frame markers, hierarchical Huffman codingSOF50xFFC5差分顺序DCTDifferential sequential DCTSOF60xFFC6差分渐进DCTDifferential progressive DCTSOF70xFFC7差分空间无损Differential spatial lossless起始帧标记非分层算术编码