基于C#和DGAL包实现栅格影像的读取和显示

  GDAL包提供了诸多处理栅格影像的方法,本文就将详细介绍基于GDAL包和C#语言如何实现栅格影像的读取和显示,这种实现是在VS2015的开发环境中完成。

  要想实现栅格影像数据的读取和显示,首先得弄清楚栅格影像的数据结构,栅格影像主要分为两类,一类是灰度影像,一类是彩色影像。但是这两类影像有一个共同的特点,他们都是由像元构成,每一个像元由像元值表示该像元的属性,不过灰度影像的像元属性有一个值(0-255)确定,而彩色影像一般是由三个值确定,分别对听R,G,B三类原色的值(0-255),就是说只要我们知道了每一个像元对应的属性值,那么就可以实现该影像的显示或者其他操作。

  由于GDAL是一个包,因此在正式开始之前需要配置环境,具体配置方法我已经发布过相应的博客,大家如果在这里有问题的话可以参考下面的连接
GDAL配置

  到这里就假装认为大家配置环境都木有问题了啊,咱们就开始码代码了,首先就是引用包的基本操作,得获取包的相应许可,也就是下面这句话啦,这句话是很简单,但是这是添加的引用的情况下,大家配置好环境后一定要添加相应的引用,接下来本文会附上本文代码所用到的所有引用,供大家参考。

Gdal.AllRegister();
//引用
using System;
using System.Drawing;
using System.Windows.Forms;
using OSGeo.GDAL;

  好了不说废话了,一句句解释太累了,直接上代码吧,下面是第一部分,环境的初始化,包括栅格文件的选择和初始环境的配置,这种配置主要是针对pictrueBox控件,该控件将用来显示栅格影像。代码中有两个函数,分别是initial()和ReadImage(),initial()大家不用在意,这个没么之用,只是我个人觉得窗体打开后pictrueBox对应的区域一片空白有点不爽,所以写了一个函数把pictrueBox对应的image也初始化,代码我后面也会粘上去;而ReadImage()就重要了,包括了读取栅格影像的具体代码,主要包括三个部分,分别是读取影像的相关信息、对图像进行缩放(为了防止图像变形,需要按照影像的宽高比对缓冲区的宽高比进行调整)、读取影像数据,其中读取影像数据包括两个部分,即灰度影像的像元值读取和彩色影像的像元值读取。

            initial();
            //文件路径
            string fileName = "";
            OpenFileDialog openFile = new OpenFileDialog();
            openFile.Filter = "所有文件|*.*|Tiff文件|*.tif|Erdas img文件|*.img|Bmp文件|*.bmp|jpeg文件|*.jpg";
            if (openFile.ShowDialog() == DialogResult.OK)
            {
                fileName = openFile.FileName;
            }
            else
            {
                MessageBox.Show("影像路径不能为空","注意",
                    MessageBoxButtons.OKCancel,MessageBoxIcon.Information);
                return;
            }
            textBox1.Text = fileName;
            //创建Dataset
            Gdal.AllRegister();
            Dataset ds = null;
            try
            {
                ds = Gdal.Open(fileName, Access.GA_ReadOnly);
            }
            catch (Exception ex)
            {
                MessageBox.Show("打开影像失败"+ex.Message);
            }
            if (ds == null)
            {
                MessageBox.Show("影像无效");
                return;
            }
           
            //创建包络矩形
            Rectangle rec = new Rectangle();
            rec.Width = this.pictureBox1.Width;
            rec.Height = this.pictureBox1.Height;
            //调用ReadImage方法获取图像并显示
            Bitmap map = ReadImage(ds, rec);
            pictureBox1.Image = map;
下面是 ReadImage()函数对应的代码。
            #region 获取图像信息
            int imageWidth = ds.RasterXSize;
            int imageHeight = ds.RasterYSize;
            float imgRatio = imageWidth / (float)imageHeight;
            //图像颜色模式
            int model;
            model = ds.RasterCount;
            double[] dd = new double[4];
            ds.GetGeoTransform(dd);
            string prj = ds.GetProjection();
            string str = string.Format("波段数目:{0}\n行数:{1};列数:{2}\n坐标参考:{3},{4},{5},{6}\n", ds.RasterCount, ds.RasterXSize, ds.RasterYSize, dd[0], dd[1], dd[2], dd[3]);
            str += prj + "\n";
            for (int i = 1; i <= ds.RasterCount; ++i)
            {
                OSGeo.GDAL.Band band = ds.GetRasterBand(i);
                str += "波段" + i + ":" + band.DataType.ToString();
            }
            infoText.Text = str;
            #endregion
            #region 对图像进行缩放
            //依据矩形尺寸设置buffer的尺寸
            int boxWidth = rec.Width;
            int boxHeight = rec.Height;
            float boxRatio = boxWidth / (float)boxHeight;
            int bufferHeight, bufferWidth;
            if (imgRatio >= boxRatio)
            {
                bufferWidth = boxWidth;
                bufferHeight = (int)(boxWidth / imgRatio);

            }
            else
            {
                bufferHeight = boxHeight;
                bufferWidth = (int)(boxHeight * imgRatio);
            }
            #endregion
            Bitmap map = new Bitmap(bufferWidth, bufferHeight,
                    System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            #region 读取图像波段数据
            //如果图像颜色模式为灰度
            if (model == 1)
            {
                Band band1 = ds.GetRasterBand(1);
                double[] maxmin1 = { 0, 0 };
                band1.ComputeRasterMinMax(maxmin1, 0);
                int[] info = new int[bufferHeight * bufferWidth];
                band1.ReadRaster(0, 0, imageWidth,
                    imageHeight, info, bufferWidth, bufferHeight, 0, 0);
                int i, j;
                for (i = 0; i < bufferHeight; i++)
                    for (j = 0; j < bufferWidth; j++)
                    {
                        int val = info[i * bufferWidth + j];
                        val = (int)(((val - maxmin1[0]) / (maxmin1[1] - maxmin1[0])) * 255);
                        Color newColor = Color.FromArgb(val, val, val);
                        map.SetPixel(j, i, newColor);
                    }
            }
             //如果图像颜色模式为彩色
            if (model != 1)
            {
                Band band1 = ds.GetRasterBand(1);
                double[] maxmin1 = { 0, 0 };
                band1.ComputeRasterMinMax(maxmin1, 0);
                int[] r = new int[bufferHeight * bufferWidth];
                band1.ReadRaster(0, 0, imageWidth,
                    imageHeight, r, bufferWidth, bufferHeight, 0, 0);

                Band band2 = ds.GetRasterBand(2);
                double[] maxmin2 = { 0, 0 };
                band2.ComputeRasterMinMax(maxmin2, 0);
                int[] g = new int[bufferHeight * bufferWidth];
                band2.ReadRaster(0, 0, imageWidth,
                    imageHeight, g, bufferWidth, bufferHeight, 0, 0);

                Band band3 = ds.GetRasterBand(3);
                double[] maxmin3 = { 0, 0 };
                band3.ComputeRasterMinMax(maxmin3, 0);
                int[] b = new int[bufferHeight * bufferWidth];
                band3.ReadRaster(0, 0, imageWidth,
                    imageHeight, b, bufferWidth, bufferHeight, 0, 0);

                int i, j;
                for (i = 0; i < bufferHeight; i++)
                    for (j = 0; j < bufferWidth; j++)
                    {
                        int rval = r[i * bufferWidth + j];
                        rval = (int)(((rval - maxmin1[0]) / (maxmin1[1] - maxmin1[0])) * 255);

                        int gval = g[i * bufferWidth + j];
                        gval = (int)(((gval - maxmin2[0]) / (maxmin2[1] - maxmin2[0])) * 255);

                        int bval = b[i * bufferWidth + j];
                        bval = (int)(((bval - maxmin3[0]) / (maxmin3[1] - maxmin3[0])) * 255);

                        Color newColor = Color.FromArgb(rval, gval, bval);
                        map.SetPixel(j, i, newColor);
                    }
            }
            return map;
             #endregion

  以上就是所有的关键代码了,哦,对了,还有一个initial()方法对应的代码块,代码如下。

            int xSize = this.pictureBox1.Width;
            int ySize = this.pictureBox1.Height;
            Bitmap map = new Bitmap(xSize, ySize, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            for (int i = 0; i < xSize; i++)
                for (int j = 0; j < ySize; j++)
                {
                    Random rd = new Random((int)DateTime.Now.Ticks);
                    Color newColor = Color.FromArgb(rd.Next(0,255), rd.Next(0, 255), rd.Next(0, 255));
                    map.SetPixel(i, j, newColor);
                }
            pictureBox1.Image = map;

  下面附几张程序的运行效果图吧。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  本文对应程序的所有文档已经全部上传到csdn网站上,如果大家有需求的话请自行下载(程序亲测有用),不过还是希望大家自己完成,个人觉得我这个小程序不值5个积分,但是我也么的办法,链接见下。
基于GDAL和C#语言读取栅格影像

  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 在Qt和OpenCV中,可以使用dgal库来读取和处理.tif格式的图像文件。首先,需要在代码中使用dgal库来加载.tif文件。然后,利用OpenCV的Mat类来存储和处理图像数据,并使用Qt中的QImage类将Mat对象转换为QPixmap对象,在图形界面中显示.tif图像。具体代码和步骤如下所示: 1.加载图像文件:使用dgal库来加载图像文件。 ```C++ #include <dgal/dgal.h> dgal::Image<uint16_t> img; img.read("filename.tif"); ``` 2.将图像数据转换为Mat对象:使用OpenCV的Mat类来存储和处理图像数据。 ```C++ cv::Mat rawData(img.height(), img.width(), CV_16U, img.data()); ``` 3.将Mat对象转换为QPixmap对象:使用Qt中的QImage类将Mat对象转换为QPixmap对象。 ```C++ QImage image(rawData.data, img.width(), img.height(), QImage::Format_Grayscale16); QPixmap pixmap = QPixmap::fromImage(image); ``` 4.在图形界面中显示.tif图像:使用Qt中的QLabel控件来显示QPixmap对象。 ```C++ QLabel *label = new QLabel(); label->setPixmap(pixmap); label->show(); ``` 通过上述步骤,我们就可以在Qt和OpenCV中显示.tif格式的图像文件了。 ### 回答2: qt, dgal和opencv都是涉及图像处理和显示的开源库。其中,QT是一个跨平台的开源图形界面应用程序开发框架,主要用于快速开发GUI程序;dgal是一种开源的空间数据分析库,用于空间数据分析和处理;opencv则是一个开源的计算机视觉库,主要用于图像和视频处理。 .tif是一种图像文件格式,它通常用于存储高质量的图片,括照片、图像和艺术品等。 要在Qt, dgal和opencv中显示.tif格式的图像,首先需要将图像加载到相应的库中。这可以通过Qt的QImage类、dgalGDAL库和opencv的cv::imread函数实现。加载图像后,可以使用相应库中提供的函数和工具对图像进行处理和显示。 在Qt中,可以使用QPixmap或QImage进行图像显示。对于dgal,可以使用GDAL库提供的函数进行图像处理和显示。opencv则提供了cv::imshow函数来显示图像。 总之,Qt,dgal和opencv都提供了丰富的功能和工具,可以方便地处理和显示.tif格式的图像。无论是用于开发GUI程序还是进行空间数据分析和计算机视觉处理,这些库都是非常有用的工具。 ### 回答3: Qt是一个跨平台的GUI开发框架,可以与DGAL和OpenCV结合使用来显示.tif文件。其中,DGAL是一个面向计算几何和数字几何算法的C++库,OpenCV则是一个开源计算机视觉库。 首先,可以使用DGAL库中的CGAL::ImageIO类来读取.tif文件,并将其转换为DGAL中的Image对象。接着,通过使用OpenCV库中的cv::Mat类将DGAL中的Image对象转换为OpenCV中的Mat对象。最后,可以使用Qt中的QLabel或者QGraphicsView来显示存储.tif文件的OpenCV中的Mat对象。 例如,可以通过以下代码实现: #include <CGAL/ImageIO.h> #include <opencv2/core/mat.hpp> #include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <QImage> #include <QLabel> int main(int argc, char *argv[]) { CGAL::Image_3 image; QImage qimage; cv::Mat mat; // 读取.tif文件到DGAL的Image对象中 CGAL::ImageIO::read_TIFF_image(argv[1], image); // 将DGAL的Image对象转换为OpenCV的Mat对象 mat = cv::Mat(image.height(), image.width(), CV_8UC4, image.pixel_ptr()); // 将OpenCV的Mat对象转换为QImage对象 qimage = QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32); // 通过Qt中的QLabel显示QImage对象 QLabel label; label.setPixmap(QPixmap::fromImage(qimage)); label.show(); return 0; }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lemon_tttea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值