图像处理代码测试程序(基于QT5.9开发)
1.先来看看程序效果:



2.程序设计要求
- 能够读取188*50左右的8位bmp灰度图
- 能够显示图片
- 有相关的错误提示
3.实现方法
QT封装了很多函数,可以参看QT的编程手册(见下图)
大概看来,需要引用文件操作相关的函数,也用到了massagebox以及用QLabel显示图像。

因为只需要读bmp文件,为了方便(不会用QT的函数,仅仅用windows.h
内已经定义好的数据类型,配合stdio.h
内文件操作函数即可。
4.具体代码
bmp_read.h
#ifndef BMP_READ_H
#define BMP_READ_H
#include <windows.h>
#include "stdio.h"
#define CAMERA_H_MAX 200
#define CAMERA_W_MAX 400
extern int camera_raw_data[CAMERA_H_MAX][CAMERA_W_MAX];
extern int camera_real_w;
extern int camera_real_h;
extern int File_Read; //
// 定义一个结构体来读取BMP的信息
typedef struct {
// 定义文件头信息
BITMAPFILEHEADER header;
// 定义位图信息头
BITMAPINFOHEADER info;
// 定义彩色表
RGBQUAD rgb[256];
// 定义位图数据指针
unsigned char* data;
} BMP;
extern BMP bmp;
void bmpRead(const char* bmpPath, BMP& bmp);
void bmpCells( BMP& bmp);
#endif // BMP_READ_H
bmp_read.cpp
#include "bmp_read.h"
int camera_raw_data[CAMERA_H_MAX][CAMERA_W_MAX];
int camera_real_w=0;
int camera_real_h=0;
int File_Read=0; //图像已读入标志位
BMP bmp;
// 读图像函数
void bmpRead(const char* bmpPath, BMP& bmp) {
// 以二进制的方式打开图片
FILE* file = fopen(bmpPath, "rb");
// 读取文件信息头
fread(&bmp.header, sizeof(BITMAPFILEHEADER), 1, file);
// 读取位图信息头
fread(&bmp.info, sizeof(BITMAPINFOHEADER), 1, file);
// 读取彩色表
fread(&bmp.rgb, sizeof(RGBQUAD), 256, file);
// 定义位图数据内存大小
bmp.data = new unsigned char[bmp.info.biWidth * bmp.info.biHeight];
// 读取元素的位图数据
fread(bmp.data, sizeof(unsigned char), bmp.info.biWidth * bmp.info.biHeight, file);
// 关闭图片
fclose(file);
camera_real_w=bmp.info.biWidth;
camera_real_h=bmp.info.biHeight;
}
void bmpCells( BMP& bmp) {
// 循环读取像素值
for (int i = 0; i < bmp.info.biHeight; i++)
{
for (int j = 0; j < bmp.info.biWidth; j++)
{
// 获取循环到像元的像素值
unsigned char pixel = bmp.data[j + i * bmp.info.biWidth];
camera_raw_data[i][j] = pixel; //原始图像二维数组
}
}
}
主窗口类函数 (对应两个按键的槽函数)
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_loadimg_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this,"选取图像文件","C:/", "images(*bmp)");//xx/xx/xx.xx
QFileInfo base(fileName);
QString basename = base.baseName(); //打开的文件文件名,xx。不包含文件后缀
char path[50]; //Qstring 转char数组
QByteArray ba = fileName.toLocal8Bit();
memcpy(path,ba.data(),ba.size()+1);//加1是为了最后的终结符,否则转换回来的时候不知道什么时候截
bmpRead(path,bmp);
bmpCells(bmp);
if(fileName!=0) File_Read=1;
qDebug() << fileName;
}
void MainWindow::on_pushButton_showimg_clicked()
{
if(File_Read)
{
unsigned char picbuf[camera_real_h][camera_real_w]={0};
for(int i=0;i<camera_real_h;i++) //复制数据
{
for(int j=0;j<camera_real_w;j++)
{
picbuf[i][j]=camera_raw_data[camera_real_h-i-1][j];
}
}
//在此处调用图像处理函数,对picbuf数组处理
//在此处调用图像处理函数,对picbuf数组处理
int bytecount = ( camera_real_w * 8 + 31)/32 * 4;
QByteArray imageByteArray = QByteArray( (const char*)picbuf,camera_real_h*bytecount);
uchar* transData = (unsigned char*)imageByteArray.data();
QImage image = QImage(transData, camera_real_w, camera_real_h, QImage::Format_Indexed8);
ui->label_img->setScaledContents(true);
ui->label_img->setPixmap(QPixmap::fromImage(image));
}
else
{
QMessageBox::warning(NULL,"warning","尚未读入图片,请点击载入图片", QMessageBox::Ok);
}
File_Read=0;
}
可视化UI设计

5.打包程序
因为没事想把程序分发给好友试试,所以学习了一下打包方法。
QT默认使用动态链接库(DLL),所以直接生成的.exe是无法单独运行的,会提示丢失dll文件。
首先切换成release生成程序

找到对应的程序

我这个是已经打包好的,一般情况下QT Creator不会删除生成的.o文件以及过程中的.h文件,为了美观,先把这些没用的删掉,仅保留.exe文件
网上好像有很多打包方法,我使用QT自带mingw的打包程序
C:\Qt\Qt5.9.0\5.9\mingw53_32\bin\windeployqt
在QT的安装目录里找找,如果使用频率比较高,也可以添加进系统变量里,省的每次打路径。
命令很简单:
C:\Qt\Qt5.9.0\5.9\mingw53_32\bin\windeployqt IMG_DEBUG.exe
前面是windeployqt.exe 后面是你自己的.exe 不管用绝对路径或者相对路径,能找到就行
运行完可能还会提示缺少某些dll,直接到"qt_path"\mingw53_32\bin\
下找到并复制进去就好了
就完了
6.总结
由于时间比较仓促,在复习近代史的摸鱼时间搞出来的。所以功能比较简陋,提示也不完全。甚至没有对可能的数组越界行为进行错误处理。不过作为一个小练习来说,基本上满足了任务需求,还是比较成功的。

发表评论