数字图像C++8位和24位BMP位图的平滑锐化二值化处理,以及24位真彩图的灰度化
Posted widiot0x
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数字图像C++8位和24位BMP位图的平滑锐化二值化处理,以及24位真彩图的灰度化相关的知识,希望对你有一定的参考价值。
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);
fwrite(&bmpInfo, 1, sizeof(BITMAPINFOHEADER), fpout);
//写入调色板
fwrite(pallet, sizeof(RGBQUAD), 256, fpout);
//写入图像像素数据
fwrite(newimagedata, sizeof(BYTE)*width, height, fpout);
//关闭图片
fclose(fpout);
//释放内存
delete imagedata;
delete newimagedata;
delete pallet;
return true;
}
bool eightBitMap::Operation(int x) {
if (x == 1)
return Operation(Template1, 9);
else if (x == 2)
return Operation(Template2, 1);
else if (x == 3)
return Operation(Template3, 1);
else {
cout << "模板调用错误!" << endl;
return false;
}
}
bool eightBitMap::Operation(int Template[][3], int coefficient) {
//分配新像素素组的空间
newimagedata = new BYTE[width*height];
//进行模板操作
for (int i = 0; i < height; ++i)
for (int j = 0; j < width; ++j) {
if (i == 0 || j == 0 || i == height - 1 || j == width - 1)
*(newimagedata + i*width + j) = *(imagedata + i*width + j);
else {
int sum = 0;
for (int m = i - 1; m < i + 2; ++m)
for (int n = j - 1; n < j + 2; ++n) {
sum += (*(imagedata + m*width + n))*Template[n - j + 1][m - i + 1] / coefficient;
}
//8位BMP中一个像素值,对应调色板中索引号为该像素值的项所存放的RGB色彩
//所以像素值范围为0~255
//像素值小于0就取0,大于255就取255
sum = (sum >= 0) ? sum : 0;
sum = ((sum + *(imagedata + i*width + j))>255) ? 255 : sum;
*(newimagedata + i*width + j) = sum;
}
}
//保存图片
if (writeImage()) {
cout << "\\n处理成功!" << endl;
return true;
}
else {
cout << "\\n处理失败!" << endl;
return false;
}
}
bool eightBitMap::Binarization() {
//分配新像素素组的空间
newimagedata = new BYTE[width*height];
//二值化操作
for (int i = 0; i < width*height; ++i)
if (*(imagedata + i) > 128)
*(newimagedata + i) = 255;
else
*(newimagedata + i) = 0;
//保存图片
if (writeImage()) {
cout << "\\n处理成功!" << endl;
return true;
}
else {
cout << "\\n处理失败!" << endl;
return false;
}
}
void eightBitMap::showBmpHead(BITMAPFILEHEADER BmpHead) {
cout << "\\n图片文件头:" << endl;
cout << " 图片大小:" << BmpHead.bfSize << endl;
cout << " 保留字_1:" << BmpHead.bfReserved1 << endl;
cout << " 保留字_2:" << BmpHead.bfReserved2 << endl;
cout << " 实际位图片数据的偏移字节数:" << BmpHead.bfOffBits << endl;
}
void eightBitMap::showBmpInfo(tagBITMAPINFOHEADER BmpInfo) {
cout << "图片信息头:" << endl;
cout << " 结构体的长度:" << BmpInfo.biSize << endl;
cout << " 位图宽:" << BmpInfo.biWidth << endl;
cout << " 位图高:" << BmpInfo.biHeight << endl;
cout << " 平面数:" << BmpInfo.biPlanes << endl;
cout << " 采用颜色位数:" << BmpInfo.biBitCount << endl;
cout << " 压缩方式:" << BmpInfo.biCompression << endl;
cout << " 实际位图数据占用的字节数:" << BmpInfo.biSizeImage << endl;
cout << " X方向分辨率:" << BmpInfo.biXPelsPerMeter << endl;
cout << " Y方向分辨率:" << BmpInfo.biYPelsPerMeter << endl;
cout << " 使用的颜色数:" << BmpInfo.biClrUsed << endl;
cout << " 重要颜色数:" << BmpInfo.biClrImportant << endl;
}
#endif
以上是关于数字图像C++8位和24位BMP位图的平滑锐化二值化处理,以及24位真彩图的灰度化的主要内容,如果未能解决你的问题,请参考以下文章
用C或C++怎样提取出bmp图像的像素点信息值?用LSB算法做信息隐藏,位图是24位的。