【数字图像】C++8位和24位BMP位图的平滑、锐化、二值化处理,以及24位真彩图的灰度化

本文介绍了如何使用C++对8位和24位BMP图像进行平滑、锐化、二值化处理,以及24位真彩图的灰度化操作。通过实例展示了处理前后的效果对比,平滑处理使得图像变得模糊,锐化加强了图像边缘,二值化将图像转换为黑白,而灰度化则将彩色图像转为灰度图像。
摘要由CSDN通过智能技术生成

BMP头文件:

#ifndef BMP_H//预处理器
#define BMP_H

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef long LONG;

//BMP文件头(14字节)
typedef struct tagBITMAPFILEHEADER {
	//WORD bfType;//位图文件的类型,必须为BM(在结构体中读取会发生错误,所以在函数中读取)
	DWORD bfSize;//位图文件的大小,以字节为单位
	WORD bfReserved1;//位图文件保留字,必须为0
	WORD bfReserved2;//位图文件保留字,必须为0
	DWORD bfOffBits;//位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位
}BITMAPFILEHEADER;

//BMP信息头(40字节)
typedef struct tagBITMAPINFOHEADER {
	DWORD biSize;//本结构所占用字节数
	LONG biWidth;//位图的宽度,以像素为单位
	LONG biHeight;//位图的高度,以像素为单位
	WORD biPlanes;//目标设备的级别,必须为1
	WORD biBitCount;//每个像素所需的位数,必须是1(双色),4(16色),8(256色)16(高彩色)或24(真彩色)之一
	DWORD biCompression;//位图压缩类型,必须是0(不压缩),1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
	DWORD biSizeImage;//位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节),以字节为单位
	LONG biXPelsPerMeter;//位图水平分辨率,每米像素数
	LONG biYPelsPerMeter;//位图垂直分辨率,每米像素数
	DWORD biClrUsed;//位图实际使用的颜色表中的颜色数
	DWORD biClrImportant;//位图显示过程中重要的颜色数
}BITMAPINFOHEADER;

//调色板
//只有8位位图才用调色板,用像素值作为索引(0~255),调色板中RGB值都是一样的,范围是0~255
//一个unsigned char的范围刚好是0~255,所以用BYTE类型存储8位位图的像素
typedef struct tagRGBQUAD {
	BYTE rgbBlue;
	BYTE rgbGreen;
	BYTE rgbRed;
	BYTE rgbReserved;//保留,必须为0
}RGBQUAD;

//像素信息
//8位BMP图1个字节代表一个像素,所以可以不用结构存储像素素组,直接用一个指针即可
typedef struct tagIMAGEDATA {
	BYTE blue;
	BYTE green;
	BYTE red;
}IMAGEDATA;

#endif

8位BMP头文件:

#ifndef EIGHTBITMAP_H//预处理器
#define EIGHTBITMAP_H

#include<iostream>
#include"BMP.h"
using namespace std;

class eightBitMap {
private:
	char imageName[30];//图像名
	int width, height;//图像的宽高
	BITMAPFILEHEADER bmpHead;//文件头
	BITMAPINFOHEADER bmpInfo;//信息头
	BYTE *imagedata = NULL, *newimagedata = NULL;//存储图片像素信息的二维数组
	RGBQUAD *pallet = new RGBQUAD[256];//调色板指针
	FILE *fpin, *fpout;//文件指针

					   //平滑算子也是通过模板进行处理的,所以可以把平滑处理和锐化处理通过一个函数实现
	int Template1[3][3]{ 1,1,1,1,1,1,1,1,1 };//平滑模板
	int Template2[3][3]{ 0,-1,0,-1,5,-1,0,-1,0 };//laplace锐化模板,4邻域(原图减去轮廓)
	int Template3[3][3]{ -1,-1,-1,-1,9,-1,-1,-1,-1 };//laplace锐化模板,8邻域
public:
	bool readImage();//读取图片
	bool writeImage();//保存图片
	bool Operation(int x);//图像平滑和锐化处理
	bool Operation(int Template[][3], int coefficient);//图像处理
	bool Binarization();//二值化
	void showBmpHead(BITMAPFILEHEADER BmpHead);//显示文件头
	void showBmpInfo(tagBITMAPINFOHEADER BmpInfo);//显示信息头
};
bool eightBitMap::readImage() {
	cout << "输入要读取的图片名:";
	cin >> imageName;
	if (!fopen_s(&fpin, imageName, "rb")) {
		//读取图片类型
		WORD bfType;
		fread(&bfType, sizeof(WORD), 1, fpin);//fread()的使用
		if (bfType != 0x4d42) {
			cout << "该图片不是BMP!" << endl;
			return false;
		}
		//读取文件头和信息头
		fread(&bmpHead, sizeof(tagBITMAPFILEHEADER), 1, fpin);
		fread(&bmpInfo, sizeof(tagBITMAPINFOHEADER), 1, fpin);
		//检查是否是8位位图
		if (bmpInfo.biBitCount != 8) {
			cout << "该图片不是8位!" << endl;
			return false;
		}
		//读取调色板
		fread(pallet, sizeof(RGBQUAD), 256, fpin);
		//读取图片的像素信息
		width = bmpInfo.biWidth;
		height = bmpInfo.biHeight;
		width = (width*sizeof(BYTE) + 3) / 4 * 4;//图像的每一行必须是4的整数倍
		imagedata = new BYTE[width*height];
		fread(imagedata, sizeof(BYTE)*width, height, fpin);
		//显示文件头和信息头
		showBmpHead(bmpHead);
		showBmpInfo(bmpInfo);
		//关闭图片
		fclose(fpin);
	}
	else {
		cout << "图片不存在!" << endl;
		return false;
	}
	return true;
}
bool eightBitMap::writeImage() {
	char imageName[30];
	cout << "输入处理后的位图名:";
	cin >> imageName;
	//创建位图文件
	if (fopen_s(&fpout, imageName, "wb")) {
		cout << "创建文件失败!" << endl;
		return false;
	}
	//写入位图类型
	WORD bfBYTE = 0x4d42;
	fwrite(&bfBYTE, 1, sizeof(WORD), fpout);
	//写入文件头和信息头
	fwrite(&bmpHead, 1, sizeof(BITMAPFILEHEADER), fpout);
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值