c++实现BMP图像的读取及其形态学处理
来源:互联网 发布:java linux 文件上传 编辑:程序博客网 时间:2024/06/05 04:26
一、BMP文件格式:
BITMAPFILEHEADER 位图文件头
BITMAPINFOHEADER 位图信息头
RGBQUAD 调色板
DATA 图像数据
前三部分结构的定义包含在头文件 Windows.h中
(1)BITMAPFILEHEADER
功能:存储文件类型、文件大小、存放位置等信息
定义:
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
说明:
bfType=0x4D42
bfSize说明文件的大小
bfReserved1=0
bfReserved2=0
bfOffBits为文件头开始到实际图像数据之间的字节偏移量
(2)BITMAPINFOHEADER
功能:存储图像的基本信息,图像的高度、宽度、位面数、比特数、分辨率、索引数等
定义:
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
说明:
biBitCount表示每个像素所占的字节数
(3)RGBQUAD
功能:指定R、G、B不同颜色分量的强度
定义:
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
说明:
rgbReserved=0
(4)DATA
图像中的数据少于或等于256时,数据是颜色在调色板中的索引。
图像为真彩色24位或者更多时,没有调色板,图像数据直接是每个像素的颜色值B、G、R。
因此,当biBitCount<=8时,colorTablesize=2的biBitCount次方*4(字节)
当biBitCount==24时,colorTablesize=0
二、BMP操作
1、读取图像的宽度、高度、字节数
(1)分析
所要读取的信息都在BITMAPINFOHEADER部分,因此可以跳过BITMAPFILEHEDER部分,读取BITMAPINFOHEADER部分内容然后输出即可。
(2)流程图
(3)C++实现代码
#include "Windows.h"#include <iostream>using namespace std;int main(){ FILE *fp=fopen("imagetech.bmp","rb");if(fp==0) return 0; fseek(fp, sizeof(BITMAPFILEHEADER),0); BITMAPINFOHEADER head; fread(&head, sizeof(BITMAPINFOHEADER), 1,fp); int bmpWidth = head.biWidth; int bmpHeight = head.biHeight; int biBitCount = head.biBitCount; cout<<"bmpWidth:"<<bmpWidth<<" bmpHeight:" <<bmpHeight<<" biBitCount:"<<biBitCount<<endl; fclose(fp); return 1;}
(4)实验结果
2、对bmp图像进行腐蚀操作
#include <stdio.h>#include "Windows.h"#define GET(a,b) *(pBmpbuf+bmpWidth*a+b) //获得第(i,j)坐标的像素值#define SET(a,b,t) *(pNewBmpbuf+bmpWidth*a+b)=t //第(i,j)坐标的像素值赋为t#define lineByte ((bmpWidth*biBitCount+31)/32*4) //每行的字节数 unsigned char* pBmpbuf=NULL;unsigned char* pNewBmpbuf=NULL;int bmpWidth;int bmpHeight;int biBitCount;unsigned long bfOffBits;bool readBMPInfo(char * bmpName){ FILE *fp=fopen(bmpName,"rb"); if (fp==0) return false; //判断是否为bmp图像BITMAPFILEHEADER fileHead; fread(&fileHead, sizeof(BITMAPFILEHEADER), 1,fp); if(fileHead.bfType != 0x4D42) //非bmp类型返回 { fclose(fp); printf("输入文件不是bmp类型"); return false; } bfOffBits=fileHead.bfOffBits; //读取偏移位置 //将文件指针跳过位图文件头 fseek(fp, sizeof(BITMAPFILEHEADER),0); BITMAPINFOHEADER head; fread(&head, sizeof(BITMAPINFOHEADER), 1,fp); bmpWidth = head.biWidth; bmpHeight = head.biHeight; biBitCount = head.biBitCount; fseek(fp,bfOffBits,0); //fp指针定位至图像起始位置 pBmpbuf=new unsigned char[bmpHeight*lineByte]; fread(pBmpbuf,1,bmpHeight*lineByte,fp); fclose(fp); return true;}bool grayscaleErosion(){int nWindow=3; //操作结构元素的尺寸 int nAlign=nWindow/2; unsigned char temp_max; if(!pNewBmpbuf){pNewBmpbuf=new unsigned char[bmpHeight*lineByte];memcpy(pNewBmpbuf,pBmpbuf,bmpHeight*lineByte); } //起始位置为(1,1)点,忽略外层边缘 ,仅限3*3尺寸是这样, for (int i=nAlign;i<bmpHeight-nAlign;i++) for (int j=nAlign;j<bmpWidth-nAlign;j++) { temp_max=GET(i,j); for (int m=i-nAlign;m<=i+nAlign;m++) { for (int n=j-nAlign;n<=j+nAlign;n++) { if(GET(m,n)>temp_max) temp_max=GET(m,n); } } SET(i,j,temp_max); } return true;}bool saveBmp(char * bmpName, char *dstName ){FILE *fp1=fopen(bmpName,"rb");FILE *fp2=fopen(dstName,"wb"); if(fp1==0||fp2==0){fclose(fp1);fclose(fp2);return 0;}unsigned char basicInfo[bfOffBits];fread(basicInfo,1,bfOffBits,fp1);fwrite(basicInfo,1,bfOffBits,fp2);fseek(fp1,bfOffBits-1,0); //fp指针定位至图像起始位置 fwrite(pNewBmpbuf,1,bmpHeight*lineByte,fp2); fclose(fp1); fclose(fp2); return 1;}int main(){char srcName[51]="imagetech.bmp";readBMPInfo(srcName);//腐蚀 grayscaleErosion();saveBmp(srcName,"Erosion.bmp");delete[] pNewBmpbuf;pNewBmpbuf=NULL;printf(" 操作成功!\n\n 已在当前文件夹下生成Erosion.bmp图像\n\n");printf("请在当前文件夹下查看处理结果\n\n"); getchar();delete[] pBmpbuf;fflush(stdin); return 1;}
二、问题
1、位图数据宽度为什么必须是4的倍数字节
Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充。
- c++实现BMP图像的读取及其形态学处理
- 【数字图像处理一】BMP图像的读取
- 图像的形态学处理
- 形态学的图像处理
- 图像的形态学处理
- 图像的形态学处理总结
- 图像处理的形态学操作
- 图像处理--形态学的应用
- 灰度图像的形态学处理
- 利用C的BMP图像的读取、保存及旋转的实现
- BMP的图像处理
- C语言处理BMP图像
- bmp格式图像的读取
- C语言读取BMP图像数据(转)
- 使用C函数读取BMP格式图像
- 纯c语言读取BMP图像
- 最全面的图像形态学处理
- 图像操作的形态学处理MATLAB
- Android ContentProvider使用详解
- 在head里的CSS link 居然粗现在body里了?
- zend studio 卡在 loading workbench
- linux 常用命令整理
- android中三种onClick事件的实现,与对比
- c++实现BMP图像的读取及其形态学处理
- 资料——freemarker对空对象处理
- VMware Virtual Ethernet Adapter for VMnet1和8在windows7无法识别的解决方法
- java写入文件
- 调度算法--先来先服务
- 王立平--EditText实现单行显示,左侧图标,提示信息
- android--手势绘制(GestureOverlayView)
- Android开发中遇到的错误及解决方法
- ERR_PTR()和PTR_ERR()