QT+GDAL实现影像的读取和显示

2023-05-16

单纯备份一下源代码,详细流程参考https://blog.csdn.net/deirjie/article/details/37872743

//open_image.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_open_image.h"
#include "gdal_priv.h"
#include <QMessageBox>
#include <QFileDialog>
#include <QTextCodec>
#include<QWheelEvent>
#include<QStandardItemModel>
#include<QFileInfo>
#include<QImage>
#include<QPixmap>
#include<QGraphicsPixmapItem>
#include<QMatrix>
#include<QScrollBar>
#include <QListView>
class open_image : public QMainWindow
{
    Q_OBJECT
		
public slots:
	void readimage();
public:
	QSize sizeHint() const;
	void CloseCurrentImg();
    open_image(QWidget *parent = Q_NULLPTR);
	bool m_showColor;
	float m_scaleFactor;
	QPoint lastEventCursorPos;
protected:
	void wheelEvent(QWheelEvent *event);
	void mousePressEvent(QMouseEvent *event);
	void mouseMoveEvent(QMouseEvent *event);
	void mouseReleaseEvent(QMouseEvent *event);
	void ZoomIn()
	{
		ScaleImg(1.2);
	};
	void ZoomOut()
	{
		ScaleImg(0.8);
	};
private:
	void ShowBand(GDALRasterBand* band);
	void ShowImg(QList<GDALRasterBand*>*imgBand);
	unsigned char* ImgSketch(float* buffer, GDALRasterBand* currentBand, int size, double noValue);
    Ui::open_imageClass ui;
	void ScaleImg(double factor)
	{
		m_scaleFactor *= factor;
		QMatrix matrix;
		matrix.scale(m_scaleFactor, m_scaleFactor);
		ui.image_show->setMatrix(matrix);
	};
	QStandardItemModel *imgMetaModel;
	QStandardItemModel *fileListModel;
	GDALDataset *poDataset;
	void ShowImgInfor(const QString filename);
	void ShowFileList(const QString filename);
};

//open_image.cpp
#include "open_image.h"

open_image::open_image(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	poDataset = NULL;
	m_showColor = true;
	m_scaleFactor = 1.0;
	m_showColor = true;
	imgMetaModel = new QStandardItemModel;
	imgMetaModel->setColumnCount(2);
	fileListModel = new QStandardItemModel;
	connect(ui.actionOpen, SIGNAL(triggered()), this, SLOT(readimage()));
}
void open_image::readimage(){

	QString file = QFileDialog::getOpenFileName(this,
		tr("Open Image"), ".",
		tr("Open tiff files(*.tiff *.tif)"));
	GDALAllRegister();
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
	poDataset = (GDALDataset*)GDALOpen(file.toStdString().c_str(), GA_ReadOnly);
	if (poDataset == NULL)
	{
		QMessageBox::critical(this, tr("Error!"), tr("Can not open file %1").arg(file));
		return;
	}

	ShowFileList(file);
	ShowImgInfor(file);
	if (poDataset->GetRasterCount() != 3)
	{
		int num=poDataset->GetRasterCount();
		m_showColor = false;
		ShowBand(poDataset->GetRasterBand(1));
	}
	// 如果图像正好三个波段,则默认以RGB的顺序显示彩色图
	else
	{
		m_showColor = true;
		QList<GDALRasterBand*> bandList;
		bandList.append(poDataset->GetRasterBand(1));
		bandList.append(poDataset->GetRasterBand(2));
		bandList.append(poDataset->GetRasterBand(3));
		ShowImg(&bandList);
	}
	GDALClose(poDataset);
}
void open_image::ShowBand(GDALRasterBand *band){
	if (band == NULL)
	{
		return;
	}
	QList<GDALRasterBand*> myBand;
	myBand.append(band);
	myBand.append(band);
	myBand.append(band);

	ShowImg(&myBand);
}
void open_image::ShowImg(QList<GDALRasterBand *> *imgBand){
	if (imgBand->size() != 3)
	{
		return;
	}

	int imgWidth = imgBand->at(0)->GetXSize();
	int imgHeight = imgBand->at(0)->GetYSize();

	m_scaleFactor = this->height() * 1.0 / imgHeight;

	int iScaleWidth = (int)(imgWidth *m_scaleFactor - 1);
	int iScaleHeight = (int)(imgHeight *m_scaleFactor - 1);

	GDALDataType dataType = imgBand->at(0)->GetRasterDataType();

	// 首先分别读取RGB三个波段
	float* rBand = new float[iScaleWidth *iScaleHeight];
	float* gBand = new float[iScaleWidth *iScaleHeight];
	float* bBand = new float[iScaleWidth *iScaleHeight];

	unsigned char *rBandUC, *gBandUC, *bBandUC;

	// 根据是否显示彩色图像,判断RGB三个波段的组成方式,并分别读取
	if (m_showColor == true)
	{
		imgBand->at(0)->RasterIO(GF_Read, 0, 0, imgWidth, imgHeight, rBand, iScaleWidth, iScaleHeight, GDT_Float32, 0, 0);
		imgBand->at(1)->RasterIO(GF_Read, 0, 0, imgWidth, imgHeight, gBand, iScaleWidth, iScaleHeight, GDT_Float32, 0, 0);
		imgBand->at(2)->RasterIO(GF_Read, 0, 0, imgWidth, imgHeight, bBand, iScaleWidth, iScaleHeight, GDT_Float32, 0, 0);

		// 分别拉伸每个波段并将Float转换为unsigned char
		rBandUC = ImgSketch(rBand, imgBand->at(0), iScaleWidth * iScaleHeight, imgBand->at(0)->GetNoDataValue());
		gBandUC = ImgSketch(gBand, imgBand->at(1), iScaleWidth * iScaleHeight, imgBand->at(1)->GetNoDataValue());
		bBandUC = ImgSketch(bBand, imgBand->at(2), iScaleWidth * iScaleHeight, imgBand->at(2)->GetNoDataValue());
	}
	else
	{
		imgBand->at(0)->RasterIO(GF_Read, 0, 0, imgWidth, imgHeight, rBand, iScaleWidth, iScaleHeight, GDT_Float32, 0, 0);

		rBandUC = ImgSketch(rBand, imgBand->at(0), iScaleWidth * iScaleHeight, imgBand->at(0)->GetNoDataValue());
		gBandUC = rBandUC;
		bBandUC = rBandUC;
	}

	// 将三个波段组合起来
	int bytePerLine = (iScaleWidth * 24 + 31) / 8;
	unsigned char* allBandUC = new unsigned char[bytePerLine * iScaleHeight];
	for (int h = 0; h < iScaleHeight; h++)
	{
		for (int w = 0; w < iScaleWidth; w++)
		{
			allBandUC[h * bytePerLine + w * 3 + 0] = rBandUC[h * iScaleWidth + w];
			allBandUC[h * bytePerLine + w * 3 + 1] = gBandUC[h * iScaleWidth + w];
			allBandUC[h * bytePerLine + w * 3 + 2] = bBandUC[h * iScaleWidth + w];
		}
	}

	// 构造图像并显示
	QGraphicsPixmapItem *imgItem = new QGraphicsPixmapItem(QPixmap::fromImage(QImage(allBandUC, iScaleWidth, iScaleHeight, bytePerLine, QImage::Format_RGB888)));
	QGraphicsScene *myScene = new QGraphicsScene();
	myScene->addItem(imgItem);
	ui.image_show->setScene(myScene);
}
unsigned char* open_image::ImgSketch(float* buffer, GDALRasterBand* currentBand, int bandSize, double noValue)
{
	unsigned char* resBuffer = new unsigned char[bandSize];
	double max, min;
	double minmax[2];
	currentBand->ComputeRasterMinMax(1, minmax);
	min = minmax[0];
	max = minmax[1];
	if (min <= noValue && noValue <= max)
	{
		min = 0;
	}
	for (int i = 0; i < bandSize; i++)
	{
		if (buffer[i] > max)
		{
			resBuffer[i] = 255;
		}
		else if (buffer[i] <= max&& buffer[i] >= min)
		{
			resBuffer[i] = static_cast<uchar>(255 - 255 * (max - buffer[i]) / (max - min));
		}
		else
		{
			resBuffer[i] = 0;
		}
	}

	return resBuffer;
}

void open_image::wheelEvent(QWheelEvent *event)
{
	// 滚轮向上滑动,放大图像
	if (event->delta() > 0)
	{
		ZoomIn();
	}
	// 滚轮向下滑动,缩小图像
	if (event->delta() < 0)
	{
		ZoomOut();
	}
}

void open_image::CloseCurrentImg()
{
	poDataset = NULL;
	imgMetaModel->clear();
	fileListModel->clear();
}
void open_image::ShowImgInfor(const QString filename){
	if (filename == "" || poDataset == NULL)
	{
		return;
	}
	int row = 0; // 用来记录数据模型的行号
	imgMetaModel->setHorizontalHeaderLabels(QStringList() << QStringLiteral("数据类型")<<QStringLiteral("数值"));
	// 图像的格式
	imgMetaModel->setItem(row, 0, new QStandardItem(tr("Description")));
	imgMetaModel->setItem(row++, 1, new QStandardItem(poDataset->GetDriver()->GetDescription()));
	imgMetaModel->setItem(row, 0, new QStandardItem(tr("Meta Infor")));
	imgMetaModel->setItem(row++, 1, new QStandardItem(poDataset->GetDriver()->GetMetadataItem(GDAL_DMD_LONGNAME)));
	imgMetaModel->setItem(row, 0, new QStandardItem(tr("Data Type")));
	imgMetaModel->setItem(row++, 1, new QStandardItem(GDALGetDataTypeName((poDataset->GetRasterBand(1)->GetRasterDataType()))));

	// 图像的大小和波段个数
	imgMetaModel->setItem(row, 0, new QStandardItem(tr("X Size")));
	imgMetaModel->setItem(row++, 1, new QStandardItem(QString::number(poDataset->GetRasterXSize())));
	imgMetaModel->setItem(row, 0, new QStandardItem(tr("Y Size")));
	imgMetaModel->setItem(row++, 1, new QStandardItem(QString::number(poDataset->GetRasterYSize())));
	imgMetaModel->setItem(row, 0, new QStandardItem(tr("Bands Count")));
	imgMetaModel->setItem(row++, 1, new QStandardItem(QString::number(poDataset->GetRasterCount())));

	// 图像的投影信息
	imgMetaModel->setItem(row, 0, new QStandardItem(tr("Projection")));
	imgMetaModel->setItem(row++, 1, new QStandardItem(poDataset->GetProjectionRef()));

	// 图像的坐标和分辨率信息
	double adfGeoTransform[6];
	QString origin = "";
	QString pixelSize = "";
	if (poDataset->GetGeoTransform(adfGeoTransform) == CE_None)
	{
		origin = QString::number(adfGeoTransform[0]) + ", " + QString::number(adfGeoTransform[3]);
		pixelSize = QString::number(adfGeoTransform[1]) + ", " + QString::number(adfGeoTransform[5]);
	}
	imgMetaModel->setItem(row, 0, new QStandardItem(tr("Origin")));
	imgMetaModel->setItem(row++, 1, new QStandardItem(origin));
	imgMetaModel->setItem(row, 0, new QStandardItem(tr("Pixel Size")));
	imgMetaModel->setItem(row++, 1, new QStandardItem(pixelSize));
	ui.tableView->setModel(imgMetaModel);
}
void open_image::ShowFileList(const QString filename){
	if (filename == "" || poDataset == NULL)
	{
		return;
	}
	fileListModel->setHorizontalHeaderLabels(QStringList() << QStringLiteral("影像名"));
	QStandardItem *rootItem = new QStandardItem(filename);
	for (int i = 0; i < poDataset->GetRasterCount(); i++)
	{
		QStandardItem *childItem = new QStandardItem(tr("Band %1").arg(i + 1));
		rootItem->setChild(i, childItem);
		//childItem->setCheckable(true);//加二态复选框
	}
	fileListModel->setItem(0, rootItem);
	ui.treeView->setModel(fileListModel);
}

QSize open_image::sizeHint() const
{
	return QSize(1024, 768);
}
void open_image::mousePressEvent(QMouseEvent *event)
{
	// 滚轮键按下,平移图像
	if (event->button() == Qt::MidButton)
	{
		ui.image_show->setDragMode(QGraphicsView::ScrollHandDrag);
		ui.image_show->setInteractive(false);
		lastEventCursorPos = event->pos();
	}
}

void open_image::mouseMoveEvent(QMouseEvent *event)
{
	if (ui.image_show->dragMode() == QGraphicsView::ScrollHandDrag)
	{
		QPoint delta = (event->pos() - lastEventCursorPos) / 10;
		ui.image_show->horizontalScrollBar()->setValue(ui.image_show->horizontalScrollBar()->value() + (isRightToLeft() ? delta.x() : -delta.x()));
		ui.image_show->verticalScrollBar()->setValue(ui.image_show->verticalScrollBar()->value() - delta.y());
		ui.image_show->viewport()->setCursor(Qt::ClosedHandCursor);
	}
}
void open_image::mouseReleaseEvent(QMouseEvent *event)
{
	if (event->button() == Qt::MidButton)
	{
		ui.image_show->setDragMode(QGraphicsView::NoDrag);
	}
}

结果展示:
在这里插入图片描述
只打开图片的话,没有投影信息
在这里插入图片描述

*//工程文件,有需要可以下载,主要是为了备份 用了GDAL+QT+OPENCV(包括有:图像打开,元数据查看,VDVI计算,灰度转换、直方图均衡化,拉普拉斯滤波、高斯滤波、线性拉伸、区域生长分割),还有很多bug没修改------

链接:https://pan.baidu.com/s/1hA_0nECmNBI0ipG926JzZA
提取码:ywet 复制这段内容后打开百度网盘手机App,操作更方便哦*
在这里插入图片描述
直方图均衡化截图有问题—不知道为啥
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT+GDAL实现影像的读取和显示 的相关文章

随机推荐

  • Windows下安装wsl

    手动下载ubuntu并安装到其他盘 1 从下面这个网址下载压缩包 链接 link 2 解压压缩包 3 打开解压后的文件夹里面的ubuntu exe 如果提示系统找不到指定的路径可以 打开cmd依次输入 便可打开ubuntu exe进行安装
  • Git常见问题

    1 关于本地库和远程库main和master的问题 刚开始使用github和git时 xff0c 你可能会按以下 xff08 错误 xff09 步骤操作 xff1a 创建一个仓库 xff0c 命名 xff0c 描述 xff0c 然后添加RE
  • visual studio 编译项目生成不了pdb文件,无法调试

    解决方法 xff1a 保证项目属性设置了导出调试信息情况下 xff0c 检查此目录下的这个文件是否有改动 还原即可
  • C++ 继承中的内存布局

    今天在网上看到了一篇写得非常好的文章 xff0c 是有关c 43 43 类继承内存布局的 看了之后获益良多 xff0c 现在转在我自己的博客里面 xff0c 作为以后复习之用 谈VC 43 43 对象模型 xff08 美 xff09 简 格
  • iOS录音、播放、WAV以及caf转成MP3上传后台

    录音 播放 转码 录音播放转成MP3base64转码caf转码MP3调用分享心得 xff1a 录音 span class token macro property span class token directive hash span s
  • 关于各类软件常见问题解决方法

    MySQL安装之后会在每天都启动检查更新 xff0c 比如我的是每天的16 00 xff0c 此时它会弹出命令行窗口 解决方案 xff1a 右键计算机 gt 管理 gt 任务计划程序 gt 左侧找到MYSQL文件夹 gt 点击会有一个ins
  • LINUX设置定时执行脚本

    编写shell脚本 例子 xff1a 设置文件权限755 chmod 755 文件名 root创建文件夹为755 xff0c 创建文件为644 设置定时 cd var spool cron crontab l 查看当前定时任务 新增任务保存
  • Python 求问:怎么将多层级嵌套的Json格式的数据文件,自动解析后存入SQL Server的两个表中

    现有一个Data json文件 xff0c 文件中的数据格式如下 xff1a 34 ID 34 70002 34 NAME 34 34 机器学习 34 34 TYPE 34 7 34 ISM 34 false 34 PARAS 34 34
  • ESP07的启动与下载

    目前大多数人都使用ESP12F来进行ESP8266系列的学习 xff0c 但是ESP07模块大小上更小一些 xff0c 可以有效降低开发板的大小 xff08 一 xff09 ESP07的启动 启动基本上和ESP12F相近 其连接图如下所示
  • openwrt无法读U盘和codepage cp437 not found的问题

    在使用openwrt15 05时 xff0c 发现U盘没有出现在 dev sda1 再开启之后还是报codepage cp437 not found的问题 1 修改文件代码 以mt7620a为例 xff0c 修改target linux r
  • Ubuntu 无法联网 解决办法

    ubuntu经常锁屏后连不上网 xff0c 右上角联网图标也会消失 解决办法 xff1a 1 打开终端 xff0c 依次输入命令 sudo service network manager stop sudo gedit var lib Ne
  • 使用you-get下载不同分辨率的视频

    分辨率太高 xff0c 文件太大下载速度太慢 分辨率太低 xff0c 效果太差 怎么办 xff1f 自己决定呗 xff01 方法 you get i URL 出来的提示会告诉你如何下载不同比例不同格式文件拉 61 61 61 61 61 6
  • Rust std library not found(标准库找不到)

    Rust std library not found 标准库找不到 问题描述 xff1a 解决办法 xff1a 问题描述 xff1a 在clion开发环境下 xff0c 找不到标准库资源等于没有代码提示 xff0c 表现就是下面找不到路径
  • linux-新建文件分区作为swap交换空间

    1 sudo fallocate l 1G swapfile 普通创建 sudo dd if 61 dev zero of 61 swapfile bs 61 1024 count 61 1024000 dd创建 xff0c 建议用这种方式
  • adb获取ANDROID_ID、系统属性、查看机型、系统版本、系统api版本、分辨率、设备名称

    获取手机Settings Secure ANDROID ID xff1a adb shell settings get secure android id 系统属性 xff1a adb shell getprop grep product
  • NOIP2017普及组★棋盘

    题目 棋盘 chess cpp c pas 1S20 5 传统256MB 问题描述 有一个m m的棋盘 xff0c 棋盘上每一个格子可能是红色 黄色或没有任何颜色的 你现在 要从棋盘的最左上角走到棋盘的最右下角 任何一个时刻 xff0c 你
  • Ubuntu 20.04 Xrdp 远程桌面黑屏

    1 问题现象 xff1a 通过远程桌面输入账户和密码后 xff0c 进入ubuntu20 04后 xff0c 出现的是黑屏 2 解决办法 xff1a xff08 1 xff09 xff1a 打开startwm sh文件 sudo vim e
  • 【论文阅读】Feedback Network for Image Super-Resolution(SRFBN)

    0问题重述 基于深度学习的超分辨图像的生成问题 之前都没有人引入反馈机制 1摘要 最近图像超分辨SR用深度学习技术获得了很好的表现 但是存在于人类视觉系统的反馈机制 xff0c 没有被用到这些方法中 本文提出了SRFBN xff08 sup
  • ajax发送put/delete请求时出现错误的原因和解决方案

    https www cnblogs com roobtyan p 9576685 html ajax使用restful服务发送put 和 delete 请求时直接传参会出现问题 一 xff0c 采用POST 43 method delete
  • QT+GDAL实现影像的读取和显示

    单纯备份一下源代码 xff0c 详细流程参考https blog csdn net deirjie article details 37872743 open image h pragma once include lt QtWidgets