มี email มาถามถึงการใช้งานไลบารีในการประมวลผลภาพ (Digital image processing) รวมไปถึงการทำงานด้าน Remote sensing โดยต้องการสร้าง Application จากภาษา .Net จริงๆแล้วถ้าเป็นไลบารี่ opensource คงหนีไม่พ้น GDAL โปรเจคชื่อดังคุณภาพดี วันนี้เลยจะขอมาสาธิตวิธีการใช้งาน GDAL ไลบารีเบื้องต้นนะครับ

         1 วิธีการ Build GDAL

             – เปิด DOS

             – Run VCVARS32.bat อยู่ใน Microsoft Visual Studio 8/VC/bin

             – ดาวน์โหลด sourcecode ของ GDAL จาก http://www.gdal.org/ 

             – เข้าไปที่ Root directory แล้ว Run คำสั่ง nmake /f makefile.vc

             – install ด้วยคำสั่ง nmake /f makefile.vc install

              กรณีติดปัญหาลองเข้าไปอ่านเพิ่มเติมได้ที่ http://www.gdal.org/gdal_building.html หรือ http://www.vterrain.org/Distrib/gdal.html

           *** หรือไม่ก็ใช้ FWtools ก็ได้นะครับ

        2 . เตรียมตัวเขียนโปรแกรมกัน โดยผมใช้ภาษา C#.net ในการเขียน

            – copy ไลบารี่ต่างๆที่เกี่ยวข้อง ซึ่ง build ไว้มาเก็บไว้ในที่ต้องการ จากนั้นก็ add เข้ามาใน .net นะครับ

            – ลองเริ่ม basic step กับ gdal โดยจะเขียนโปรแกรม gdal เพื่อเรียกดู infomation และ header ของภาพถ่ายดาวเทียมหรือภาพถ่ายทางอากาศ โดยจะใช้ฟังกชั่น Gdal.Open() เพื่อเข้าถึงภาพ Raster แล้วจึงเข้าถึงรายละเอียดของคุณสมบัติต่างๆของภาพ Raster เช่น Map Projection, pixel value , Meatadata header เป็นต้น

public static void Main(string[] args)
    {

        if (args.Length != 1) usage();

        Console.WriteLine(“”);

        try
        {
            /* ——————————————————————– */
            /*      Register driver ทั้งหมด                                            */
            /* ——————————————————————– */
            Gdal.AllRegister();

            /* ——————————————————————– */
            /*      เปิดไฟล์ Raster                                                   */
            /* ——————————————————————– */
            Dataset ds = Gdal.Open( args[0], Access.GA_ReadOnly );
  
            if (ds == null)
            {
                Console.WriteLine(“Can’t open ” + args[0]);
                System.Environment.Exit(-1);
            }

            Console.WriteLine(“Raster dataset parameters:”);
            Console.WriteLine(”  Projection: ” + ds.GetProjectionRef());
            Console.WriteLine(”  RasterCount: ” + ds.RasterCount);
            Console.WriteLine(”  RasterSize (” + ds.RasterXSize + “,” + ds.RasterYSize + “)”);
           
            /* ——————————————————————– */
            /*      Get driver สำหรับ Raster                                                      */
            /* ——————————————————————– */ 
            Driver drv = ds.GetDriver();

            if (drv == null)
            {
                Console.WriteLine(“Can’t get driver.”);
                System.Environment.Exit(-1);
            }
           
            Console.WriteLine(“Using driver ” + drv.LongName);

            /* ——————————————————————– */
            /*      Get metadata หรือ Header ของภาพ Raster                                                   */
            /* ——————————————————————– */
            string[] metadata = ds.GetMetadata(“”);
            if (metadata.Length > 0)
            {
                Console.WriteLine(”  Metadata:”);
                for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
                {
                    Console.WriteLine(”    ” + iMeta + “:  ” + metadata[iMeta]);
                }
                Console.WriteLine(“”);
            }

            /* ——————————————————————– */
            /*      แสดง “IMAGE_STRUCTURE”                           */
            /* ——————————————————————– */
            metadata = ds.GetMetadata(“IMAGE_STRUCTURE”);
            if (metadata.Length > 0)
            {
                Console.WriteLine(”  Image Structure Metadata:”);
                for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
                {
                    Console.WriteLine(”    ” + iMeta + “:  ” + metadata[iMeta]);
                }
                Console.WriteLine(“”);
            }

            /* ——————————————————————– */
            /*     แสดงส่วนของ subdatasets.                                             */
            /* ——————————————————————– */
            metadata = ds.GetMetadata(“SUBDATASETS”);
            if (metadata.Length > 0)
            {
                Console.WriteLine(”  Subdatasets:”);
                for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
                {
                    Console.WriteLine(”    ” + iMeta + “:  ” + metadata[iMeta]);
                }
                Console.WriteLine(“”);
            }

            /* ——————————————————————– */
            /*      แสดงรายละเอียด geolocation.                                             */
            /* ——————————————————————– */
            metadata = ds.GetMetadata(“GEOLOCATION”);
            if (metadata.Length > 0)
            {
                Console.WriteLine(”  Geolocation:”);
                for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
                {
                    Console.WriteLine(”    ” + iMeta + “:  ” + metadata[iMeta]);
                }
                Console.WriteLine(“”);
            }

            /* ——————————————————————– */
            /*      แสดง image boundary                                                 */
            /* ——————————————————————– */
            Console.WriteLine( “Corner Coordinates:” );
            Console.WriteLine(”  Upper Left (” + GDALInfoGetPosition( ds, 0.0, 0.0) + “)”);
            Console.WriteLine(”  Lower Left (” + GDALInfoGetPosition( ds, 0.0, ds.RasterYSize) + “)”);
            Console.WriteLine(”  Upper Right (” + GDALInfoGetPosition( ds, ds.RasterXSize, 0.0) + “)”);
            Console.WriteLine(”  Lower Right (” + GDALInfoGetPosition( ds, ds.RasterXSize, ds.RasterYSize) + “)”);
            Console.WriteLine(”  Center (” + GDALInfoGetPosition( ds, ds.RasterXSize / 2, ds.RasterYSize / 2) + “)”);
            Console.WriteLine(“”);

            /* ——————————————————————– */
            /*      Get raster band                                                 */
            /* ——————————————————————– */
            for (int iBand = 1; iBand <= ds.RasterCount; iBand++)
            {
                Band band = ds.GetRasterBand(iBand);
                Console.WriteLine(“Band ” + iBand + ” :”);
                Console.WriteLine(”   DataType: ” + Gdal.GetDataTypeName(band.DataType));
                Console.WriteLine(”   ColorInterpretation: ” + Gdal.GetColorInterpretationName(band.GetRasterColorInterpretation()));
                ColorTable ct = band.GetRasterColorTable();
    if (ct != null)
     Console.WriteLine(”   Band has a color table with ” + ct.GetCount() + ” entries.”);
               
    Console.WriteLine(”   Description: ” + band.GetDescription());
                Console.WriteLine(”   Size (” + band.XSize + “,” + band.YSize + “)”);
                int BlockXSize, BlockYSize;
                band.GetBlockSize(out BlockXSize, out BlockYSize);
                Console.WriteLine(”   BlockSize (” + BlockXSize + “,” + BlockYSize + “)”);
                double val;
                int hasval;
                band.GetMinimum(out val, out hasval);
                if (hasval != 0) Console.WriteLine(”   Minimum: ” + val.ToString());
                band.GetMaximum(out val, out hasval);
                if (hasval != 0) Console.WriteLine(”   Maximum: ” + val.ToString());
                band.GetNoDataValue(out val, out hasval);
                if (hasval != 0) Console.WriteLine(”   NoDataValue: ” + val.ToString());
                band.GetOffset(out val, out hasval);
                if (hasval != 0) Console.WriteLine(”   Offset: ” + val.ToString());
                band.GetScale(out val, out hasval);
                if (hasval != 0) Console.WriteLine(”   Scale: ” + val.ToString());
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(“Application error: ” + e.Message);
        }
    }

 private static string GDALInfoGetPosition(Dataset ds, double x, double y)
    {
        double[] adfGeoTransform = new double[6];
        double dfGeoX, dfGeoY;
        ds.GetGeoTransform(adfGeoTransform);

        dfGeoX = adfGeoTransform[0] + adfGeoTransform[1] * x + adfGeoTransform[2] * y;
        dfGeoY = adfGeoTransform[3] + adfGeoTransform[4] * x + adfGeoTransform[5] * y;

        return dfGeoX.ToString() + “, ” + dfGeoY.ToString();
    }
}

———————————————————————————

code ตัวอย่างจาก GDAL developer group โดย Tamas Szekeres

         สรุปอีกที GDAL &OGR เป็นไลบารีที่มีประสิทธิภาพ และใช้งานได้สารพัดประโยชน์จริงๆครับ ท่านที่เริ่มศึกษาการเขียนโปรแกรมทาง GIS หรือ Remote Sensing ก็สามารถนไปประยุกต์ใช้ได้ ซึ่งจะช่วยลดภาระเรื่องการจัดการไฟล์ไปได้มากเลยทีเดียว อ่านรายละเอียดเพิ่มเติมและดูตัวอย่างอื่นๆที่ http://trac.osgeo.org/gdal/wiki/GdalOgrInCsharp