帮我写一代码,用C++实现读取bmp图像并展示出来,然后将该彩色的bmp图像转化为灰度图展示输出前后的对比,并将灰度图保存为新文件
时间: 2024-02-13 11:06:04 浏览: 147
下面是一个用 C++ 实现读取 BMP 图像并展示、转换为灰度图并保存的示例代码:
```c++
#include <iostream>
#include <fstream>
#include <cstdint>
using namespace std;
#pragma pack(push, 2) // 结构体字节对齐方式为 2 字节对齐
typedef struct {
uint16_t bfType; // 位图文件类型,必须为 0x4D42
uint32_t bfSize; // 位图文件大小
uint16_t bfReserved1; // 保留字节1
uint16_t bfReserved2; // 保留字节2
uint32_t bfOffBits; // 从文件头到实际位图数据的偏移字节数
} BMPFILEHEADER;
typedef struct {
uint32_t biSize; // 信息头大小
int32_t biWidth; // 图像宽度
int32_t biHeight; // 图像高度
uint16_t biPlanes; // 位平面数,必须为1
uint16_t biBitCount; // 每像素位数
uint32_t biCompression; // 压缩类型
uint32_t biSizeImage; // 压缩图像大小字节数
int32_t biXPelsPerMeter; // 水平分辨率
int32_t biYPelsPerMeter; // 垂直分辨率
uint32_t biClrUsed; // 颜色表中实际使用的颜色数
uint32_t biClrImportant; // 重要的颜色数
} BMPINFOHEADER;
#pragma pack(pop)
int main() {
const char *inFileName = "color.bmp";
const char *outFileName = "gray.bmp";
BMPFILEHEADER bmpFileHeader;
BMPINFOHEADER bmpInfoHeader;
uint8_t *colorData, *grayData;
int width, height, i, j;
float rWeight = 0.299, gWeight = 0.587, bWeight = 0.114; // 加权平均系数
ifstream inFile(inFileName, ios::binary);
ofstream outFile(outFileName, ios::binary);
inFile.read((char *)&bmpFileHeader, sizeof(BMPFILEHEADER)); // 读取 BMP 文件头
inFile.read((char *)&bmpInfoHeader, sizeof(BMPINFOHEADER)); // 读取 BMP 信息头
width = bmpInfoHeader.biWidth;
height = abs(bmpInfoHeader.biHeight);
colorData = new uint8_t[3 * width * height]; // 分配彩色数组内存
grayData = new uint8_t[width * height]; // 分配灰度数组内存
inFile.seekg(bmpFileHeader.bfOffBits, ios::beg); // 定位到位图数据
// 读取彩色数组
inFile.read((char *)colorData, 3 * width * height);
// 将彩色数组转换为灰度数组
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
int pos = 3 * (i * width + j);
grayData[i * width + j] = (uint8_t)(colorData[pos + 2] * rWeight + colorData[pos + 1] * gWeight + colorData[pos] * bWeight);
}
}
// 写入 BMP 文件头和信息头
outFile.write((char *)&bmpFileHeader, sizeof(BMPFILEHEADER));
outFile.write((char *)&bmpInfoHeader, sizeof(BMPINFOHEADER));
// 写入灰度数组
outFile.write((char *)grayData, width * height);
// 关闭文件
inFile.close();
outFile.close();
// 读取并展示彩色图像
cv::Mat colorImage(height, width, CV_8UC3, colorData);
cv::namedWindow("Color Image", cv::WINDOW_NORMAL);
cv::imshow("Color Image", colorImage);
// 读取并展示灰度图像
cv::Mat grayImage(height, width, CV_8UC1, grayData);
cv::namedWindow("Gray Image", cv::WINDOW_NORMAL);
cv::imshow("Gray Image", grayImage);
// 等待按键
cv::waitKey(0);
// 释放内存
delete[] colorData;
delete[] grayData;
return 0;
}
```
这段代码使用了 OpenCV 库来读取和展示 BMP 图像,利用 C++ 的文件流来读取和写入 BMP 文件。首先读取彩色数组,然后将其转换为灰度数组,最后将灰度数组写入新的 BMP 图像文件中。在展示图像时,使用 OpenCV 的 namedWindow 函数创建窗口并显示图像,waitKey 函数等待按键,imshow 函数展示图像。
阅读全文