Example #1
0
        private void startConvertingNextFile()
        {
            //skip conversion if output file already exists
            if (File.Exists(filesToConvert[conversionFilesConverted].outputFilename) == true && conversionSkipAlreadyConvertedFiles == true)
            {
                string ENVIFileNameOnly = Path.GetFileName(filesToConvert[conversionFilesConverted].outputFilename);
                printNotification(ENVIFileNameOnly + " already exists. Skipping.");
                bw_FileConversionComplete();                //can't work on this file, so mark as finished
                return;
            }

            //skip conversion if IMD file cannot be found
            string NITFFileNameOnly = Path.GetFileName(filesToConvert[conversionFilesConverted].NITFFilename);

            if (File.Exists(filesToConvert[conversionFilesConverted].IMDTarFilename) == false)
            {
                printNotification("No IMD/Tar file for " + NITFFileNameOnly + ". Skipping.", Color.Red);
                bw_FileConversionComplete();                //can't work on this file, so mark as finished
                return;
            }

            //everything ok to start conversion of the next file
            printNotification("Converting " + NITFFileNameOnly);

            //set parameters to pass to converter
            WVConversionSettings conversionSettings = new WVConversionSettings();

            conversionSettings.inputNITFFilename   = filesToConvert[conversionFilesConverted].NITFFilename;
            conversionSettings.inputIMDTarFilename = filesToConvert[conversionFilesConverted].IMDTarFilename;
            conversionSettings.outputFilename      = filesToConvert[conversionFilesConverted].outputFilename;
            conversionSettings.outputType          = conversionOutputDataType;
            conversionSettings.scaleFactor         = conversionOutputScaleFactor;
            conversionSettings.applyFineTuningCal  = conversionApplyFineTuningCal;

            //convert the file
            convertNITFToENVI(conversionSettings);
        }
Example #2
0
        public static void CalibrateImage(WVConversionSettings conversionSettings)
        {
            string   inputFilename        = conversionSettings.inputNITFFilename;
            string   inputIMDFilename     = conversionSettings.inputIMDTarFilename;
            string   outputFilename       = conversionSettings.outputFilename;
            string   outputHeaderFilename = outputFilename + ".hdr";
            DataType outputType           = conversionSettings.outputType;
            double   scaleFactor          = conversionSettings.scaleFactor;

            //open the input file
            Dataset ds = Gdal.Open(inputFilename, Access.GA_ReadOnly);

            if (ds == null)
            {
                throw new Exception("Can't open " + inputFilename);                        //stop if file could not be opened properly
            }
            //get GDAL driver for this file type
            Driver drv = ds.GetDriver();

            if (drv == null)
            {
                throw new Exception("Can't get driver for reading.");                         //stop if driver could not be found for this file
            }
            //get image raster info
            // GDAL reads image in blocks, so get their size & how many
            int width = ds.RasterXSize;
            int height = ds.RasterYSize;
            int nBands = ds.RasterCount;
            int blockXSize, blockYSize;

            ds.GetRasterBand(1).GetBlockSize(out blockXSize, out blockYSize);
            int      nImageXBlocks  = (int)Math.Ceiling((double)width / blockXSize);
            int      nImageYBlocks  = (int)Math.Ceiling((double)height / blockYSize);
            DataType inputDataType  = ds.GetRasterBand(1).DataType;
            int      bytesPerSample = getBytesInSampleType(inputDataType);

            //note on cache size
            // default cache size is ~41MB
            // read buffer must be less than cache size for improved speed
            // appears that gdal can read images using multi-threading with 1 core decoding each block.
            //   This works well as long as all currently needed blocks fit within the cache.
            // all bands for a block appear to be decoded at once
            // reading by block appears better because if we barely overrun the GDAL cache size the time doubles,
            //   whereas if reading by row all blocks intersecting the row must be read every time a row is read (far slower)

            //set GDAL cache to encompass one row of image blocks for all bands (plus a little extra)
            OSGeo.GDAL.Gdal.SetCacheMax(nImageXBlocks * blockXSize * blockYSize * nBands * bytesPerSample + 50000000);

            //parse band info from IMD file
            string IMDTarFilename = inputIMDFilename;

            string[] IMDLines;
            if (IMDTarFilename.Substring(IMDTarFilename.Length - 4, 4).ToLower().Equals(".imd"))
            {
                IMDLines = File.ReadAllLines(IMDTarFilename);
            }
            else
            {
                IMDLines = Regex.Split(TarFileExtraction.getIMDFromTar(IMDTarFilename), "\r\n|\r|\n");
            }
            BandInfo[] bandInfos = parseBandInfoFromIMD(IMDLines);

            //fine-tuning calibration info
            double[] fineTuneGains   = new double[bandInfos.Length];
            double[] fineTuneOffsets = new double[bandInfos.Length];
            //set default values to make no changes
            for (int i = 0; i < bandInfos.Length; i++)
            {
                fineTuneGains[i] = 1;
            }
            //get fine-tune info if specified
            if (conversionSettings.applyFineTuningCal == true)
            {
                getFineTuneFactors(bandInfos, fineTuneGains, fineTuneOffsets);
            }

            //create new envi header file
            createENVIHeader(outputHeaderFilename, inputFilename, ds, bandInfos, outputType, scaleFactor);
            BinaryWriter bw = new BinaryWriter(new FileStream(outputFilename, FileMode.Create));

            //report start of work
            if (conversionSettings.worker != null)
            {
                conversionSettings.worker.ReportProgress(0);
            }

            //convert images one row of blocks at a time
            int bytesPerOutputSample = getBytesInSampleType(outputType);

            for (int ys = 0; ys < nImageYBlocks; ys++)
            {
                //allocate buffer to store one band of data for one block row
                int        rowHeight    = (ys < nImageYBlocks - 1) ? blockYSize : (height - ys * blockYSize);
                byte[]     inputBuffer  = new byte[width * rowHeight * bytesPerSample];
                double[][] dBuffer      = new double[rowHeight][];
                byte[]     outputBuffer = new byte[width * rowHeight * bytesPerOutputSample];

                for (int band = 1; band <= nBands; band++)
                {
                    //read data
                    System.Runtime.InteropServices.GCHandle handle = System.Runtime.InteropServices.GCHandle.Alloc(inputBuffer, System.Runtime.InteropServices.GCHandleType.Pinned);
                    IntPtr pointer = handle.AddrOfPinnedObject();
                    ds.GetRasterBand(band).ReadRaster(0, ys * blockYSize, width, rowHeight, pointer, width, rowHeight, ds.GetRasterBand(1).DataType, 0, 0);
                    handle.Free();

                    //convert raw input data to double precision
                    for (int y = 0; y < rowHeight; y++)
                    {
                        dBuffer[y] = new double[width];
                    }
                    convertByteArrayToDouble2D(dBuffer, inputBuffer, inputDataType);

                    //calibrate
                    for (int y = 0; y < rowHeight; y++)
                    {
                        for (int x = 0; x < width; x++)
                        {
                            dBuffer[y][x] = (fineTuneGains[band - 1] * dBuffer[y][x] * (bandInfos[band - 1].absCalFactor / bandInfos[band - 1].effectiveBandwidth) + fineTuneOffsets[band - 1]) / 10 * scaleFactor;
                        }
                    }

                    //convert calibrated info to output data type
                    convertDouble2DToByteArray(dBuffer, outputBuffer, outputType);

                    //save calibrated data to output file
                    long bToIndex = ((long)(band - 1) * width * height + ys * blockYSize * width + 0) * bytesPerOutputSample;
                    bw.Flush();
                    bw.BaseStream.Seek(bToIndex, SeekOrigin.Begin);
                    bw.Write(outputBuffer);

                    //stop processing if work cancelled
                    if (conversionSettings.worker != null && conversionSettings.worker.CancellationPending == true)
                    {
                        //stop writing to the file
                        bw.Close();
                        //try to delete incomplete output files
                        File.Delete(outputFilename);
                        File.Delete(outputHeaderFilename);

                        //stop processing
                        return;
                    }

                    //report progress
                    if (conversionSettings.worker != null)
                    {
                        conversionSettings.worker.ReportProgress((int)(((double)ys * nBands + band - 1 + 1) / (nImageYBlocks * nBands) * 100));
                    }
                }
            }

            //close output file
            bw.Close();
        }
Example #3
0
        //BACKGROUND THREAD HANDLING

        //starts background thread to work on conversion
        private void convertNITFToENVI(WVConversionSettings conversionSettings)
        {
            conversionSettings.worker = bw;
            bw.RunWorkerAsync(conversionSettings);
        }
Example #4
0
        //parse inputs and attempt conversion of a file
        private static void runConvertCommand(Lookup <string, CommandArgField> lup)
        {
            //parse required input parameters
            string inputFilename  = lup["-input"].ToArray()[0].parameters[0];
            string outputFilename = lup["-output"].ToArray()[0].parameters[0];

            //parse optional input parameters
            int      outputdatatype = (lup.Contains("-outputdatatype") == true) ? int.Parse(lup["-outputdatatype"].ToArray()[0].parameters[0]) : 12;
            DataType outputType;

            if (outputdatatype == 4)
            {
                outputType = DataType.GDT_Float32;
            }
            else if (outputdatatype == 12)
            {
                outputType = DataType.GDT_UInt16;
            }
            else
            {
                throw new Exception("Unhandled output type. Only 4 (Float32) and 12 (UInt16) supported.");
            }

            double scaleFactor = (lup.Contains("-scalefactor") == true) ? double.Parse(lup["-scalefactor"].ToArray()[0].parameters[0]) : 1;

            string imdFilename;

            if (lup.Contains("-imd") == true)
            {
                imdFilename = lup["-imd"].ToArray()[0].parameters[0];
            }
            else
            {
                imdFilename = Path.GetDirectoryName(inputFilename) + "\\" + Path.GetFileNameWithoutExtension(inputFilename) + ".imd";
                if (File.Exists(imdFilename) == false)
                {
                    imdFilename = Path.GetDirectoryName(inputFilename) + "\\" + Path.GetFileNameWithoutExtension(inputFilename) + ".tar";
                }
            }

            bool applyFineTuningCal = (lup.Contains("-applyfinetuningcalibration") == true) ? bool.Parse(lup["-applyfinetuningcalibration"].ToArray()[0].parameters[0]) : true;

            //setup background processing thread handler
            BackgroundWorker bw = new BackgroundWorker();

            bw.WorkerReportsProgress      = true;
            bw.WorkerSupportsCancellation = true;
            bw.DoWork          += new DoWorkEventHandler(bw_DoWork);
            bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

            //set parameters to pass to converter
            WVConversionSettings conversionSettings = new WVConversionSettings();

            conversionSettings.inputNITFFilename   = inputFilename;
            conversionSettings.inputIMDTarFilename = imdFilename;
            conversionSettings.outputFilename      = outputFilename;
            conversionSettings.outputType          = outputType;
            conversionSettings.scaleFactor         = scaleFactor;
            conversionSettings.applyFineTuningCal  = applyFineTuningCal;
            conversionSettings.worker = bw;

            //start calibration in the background thread
            bw.RunWorkerAsync(conversionSettings);

            //wait for background processing to finish
            while (bw.IsBusy == true)
            {
                Thread.Sleep(100);
            }
        }