Large-Scale Image Mosaicking

A large geospatial area typically consists of many smaller aerial photographs or satellite images. Large-scale image mosaicking can stitch these small geospatial images into one large image to get a better view of the whole spatial area.

GeoRaster provides large-scale mosaicking functions that allow gaps, overlaps, and missing source GeoRaster objects. It supports both rectified and unrectified images. It supports internal reprojection and rectification, common point rules, and simple color balancing. You can also mosaic at a certain pyramid level. This mosaicking process results in a single GeoRaster object, which is also called a physical mosaic as opposed to virtual mosaic (For information about virtual mosaic, see Virtual Mosaic).

The SDO_GEOR.mosaic and SDO_GEOR_AGGR.mosaicSubset procedures provide support for image mosaicking; however, you are strongly encouraged to use SDO_GEOR_AGGR.mosaicSubset because it provides much more advanced features and options, and it is also implemented with parallelism. SDO_GEOR_AGGR.mosaicSubset can take a virtual mosaic, such as a list of GeoRaster tables, a database view with a GeoRaster column, or a REF CURSOR, as the source images.

The SDO_GEOR.mosaic procedure mosaics a set of source GeoRaster images that are rectified, are geospatially aligned under the same SRID, and have the same resolution. The result of the mosaic is another GeoRaster object. If there are overlaps between the source images, the mosaic result will have the last source image’s content at the overlapping area. This procedure works well for preprocessed and perfectly aligned source images.

In the examples in this section, the source images are stored in source GeoRaster tables GRTAB, GRTAB1, and GRTAB2, which are defined with the following columns:

(id          NUMBER PRIMARY KEY,
cloud_cover  NUMBER     -- percentage of cloud coverage
last_update  TIMESTAMP  -- GeoRaster object's last update time
grobj        SDO_GEORASTER )

Oracle Spatial spatial indexes have been created on the spatialExtent attribute of the GeoRaster object in these tables.

In these examples, the mosaicked image is stored in GEORASTER_TABLE, which is defined in Storage Parameters.

Example: SDO_GEOR.mosaic (Table and Column Name)

Example: SDO_GEOR.mosaic (Table and Column Name) shows the SDO_GEOR.mosaic procedure.

DECLARE
  gr sdo_georaster;
BEGIN
  INSERT INTO georaster_table (georid, georaster)
      VALUES (12, sdo_geor.init('rdt_1'))
      RETURNING georaster INTO gr;
  sdo_geor.mosaic('grtab', 'grobj', gr, 'blocking=optimalpadding blocksize=(512,512,1)');
  UPDATE georaster_table SET georaster=gr WHERE id=12;
END;
/

In the real world, however, the source images are often collected under different circumstances so as to have different resolutions or large areas of overlap, or using a different georeference system. In such cases, you can use the SDO_GEOR_AGGR.mosaicSubset procedure to mosaic these source images into one uniform mosaicked image. Compared to SDO_GEOR.mosaic, the SDO_GEOR_AGGR.mosaicSubset procedure provides more features and options:

Example: SDO_GEOR_AGGR.mosaicSubset

Example: SDO_GEOR_AGGR.mosaicSubset uses SDO_GEOR_AGGR.mosaicSubset to mosaic all the source images from two GeoRaster tables (GRTAB1 and GRTAB2) into a large mosaicked image in SRID 4326 with a resolution of 30 meters on the x and y dimensions.

DECLARE
  resolutions sdo_number_array;
  gr sdo_georaster;
BEGIN
    insert into georaster_table (georid, georaster)
        values (10, sdo_geor.init('RDT_1',10))
         returning georaster into gr;

    resolutions := sdo_number_array(30, 30);
    sdo_geor_aggr.mosaicSubset('grtab1, grtab2', 'grobj, grobj',
                               0, 4326, null, null, null,
                               null, null, null, resolutions, 'unit=meter',
                               'commonPointRule = end, nodata=true, resampleTolerance=0.2, resampling=bilinear, fillGap=true',
                               'blocking=optimalpadding blocksize=(512, 512, 3)', gr, null, 'parallel=4');

      update georaster_table set georaster = gr where georid=10;
      commit;
END;
/

In Example: SDO_GEOR_AGGR.mosaicSubset:

You can call SDO_GEOR_AGGR.validateForMosaicSubset before calling SDO_GEOR_AGGR.getMosaicSubset to make sure that the source images can be mosaicked.

Color Balancing During Mosaicking

The source images of the mosaicking operation can have different luminance or colors due to the differences in the lighting conditions, time of day, or other factors when the images were captured. Color balancing minimizes the color differences between the neighboring images and makes the resulting mosaic look more seamless. SDO_GEOR_AGGR.mosaicSubset and SDO_GEOR_AGGR.getMosaicSubset provide some basic color balancing methods during the mosaicking process. Several color balancing methods are provided. They are identified by the keyword colorbalance in the mosaicParam parameter:

There are several ways to specify the reference values for the color balancing methods. They are identified by the keyword cbreference in the mosaicParam parameter:

Example: LINEARSTRETCHING Color Balancing

This example shows how to use the LINEARSTRETCHING color balancing method on the source images in the SDO_GEOR_AGGR.mosaicSubset procedure. The reference minimum and maximum values are specified in the referenceValue1 and referenceValue2 parameters. In the example, each band has different reference value.

DECLARE
gr sdo_georaster;
resolutions  sdo_number_array;
ref_min    sdo_number_arrray;
ref_max   sdo_number_array;
BEGIN
    -- create the new GeoRaster object for mosaic
    insert into georaster_table (georid, georaster)
        values (10, sdo_geor.init('RDT_1',10))
         returning georaster into gr;

    -- set the output resolution
     resolutions := sdo_number_array(30, 30);


    -- Set the reference values, there are 3 values, one for each band
    ref_min := sdo_number_array(10, 10, 10);
    ref_max := sdo_number_array(200, 255, 230);

    -- Mosaic
    sdo_geor_aggr.MosaicSubset('georaster_table_1',
                   'georaster', null, 32610, null, null, null, null,
                    null, null, null, resolutions, null,
                   'colorBalance=linearstretching, cbreference=value',
                   'blocking=optimalpadding, blocksize=(512,512,3)',
                    gr, null, 'parallel=4', referenceValue1=>ref_min,
                    referenceValue2=>ref_max);

     update georaster_table set georaster = gr where georid=10;
     commit;
END;
/

Example: HISTOGRAMMATCHING Color Balancing

This example shows how to use the HISTOGRAMMATCHING color balancing method on the source images in the SDO_GEOR_AGGR.mosaicSubset procedure. The reference histograms are derived from the reference image. The reference image must have the same number of bands as the source images.

DECLARE
gr sdo_georaster;
resolutions  sdo_number_array;
ref_gr    sdo_georaster;
BEGIN
    -- create the new GeoRaster object for mosaic
    insert into georaster_table (georid, georaster)
        values (10, sdo_geor.init('RDT_1',10))
         returning georaster into gr;

    -- set the output resolution
    resolutions := sdo_number_array(30, 30);

-- retrieve the reference image
Select georaster into ref_gr from georaster_table where georid = 1;

    -- Mosaic
    sdo_geor_aggr.MosaicSubset('georaster_table_1',
                   'georaster', null, 32610, null, null, null, null,
                    null, null, null, resolutions, null,
                   'colorBalance=histogramMatching, cbreference=image',
                   'blocking=optimalpadding, blocksize=(512,512,3)',
                    gr, null, 'parallel=4', refereneImage=>ref_gr);

     update georaster_table set georaster = gr where georid=10;
     commit;
END;
/

Example: STATISTICSMATCHING Color Balancing

This example shows how to use the STATISTICSMATCHING color balancing method on the source images in the SDO_GEOR_AGGR.mosaicSubset procedure. The reference statistics values are calculated from the overlapped area of the neighboring images. This requires that the source images have significant overlaps so that the statistics of the overlapped area can reflect the color difference between neighboring images.

DECLARE
gr sdo_georaster;
resolutions  sdo_number_array;
BEGIN
    -- create the new GeoRaster object for mosaic
    insert into georaster_table (georid, georaster)
        values (10, sdo_geor.init('RDT_1',10))
         returning georaster into gr;

    -- set the output resolution
    resolutions := sdo_number_array(30, 30);

    -- Mosaic
    sdo_geor_aggr.MosaicSubset('georaster_table_1',
                   'georaster', null, 32610, null, null, null, null,
                    null, null, null, resolutions, null,
                   'colorBalance=statisticsMatching, cbreference=overlap',
                   'blocking=optimalpadding, blocksize=(512,512,3)',
                    gr, null, 'parallel=4');

     update georaster_table set georaster = gr where georid=10;
     commit;
END;
/

Parallel Compression, Copying, and Subsetting

To parallelize rectification, orthorectification and reprojecting, use SDO_GEOR.rectify. To parallelize warping, call SDO_GEOR.warp. All raster algebra operations are parallelized too.

You can use the SDO_GEOR_AGGR.mosaicSubset procedure to conduct several types of parallel operations, including parallel compression and decompression, parallel copying or change format copying, parallel subsetting, parallel reprojection, and parallel rectification. The copying and subsetting operations are not parallelized directly. For JPEG and DEFLATE, the SDO_GEOR.changeFormatCopy procedure can be called to do parallel compression and decompression if reformatting is not required. This topic gives some examples for parallelized compressing, copying, and subsetting operations. In all these cases, the SDO_GEOR_AGGR.mosaicSubset procedure works on single GeoRaster objects.

To illustrate the parallelized operations, the examples in this section use a null value for most parameters. In your applications, you can apply all other parameters of the SDO_GEOR_AGGR.mosaicSubset procedure; however, the mosaicParam parameter has no effect when the input is a single GeoRaster object.

Example: Parallel Compression

Example: Parallel Compression shows parallel compression using the SDO_GEOR_AGGR.mosaicSubset procedure. This applies to both DEFLATE and JPEG compression and decompression.

DECLARE
  gr sdo_georaster;
  cur sys_refcursor;
  crop_area sdo_geometry := null;
BEGIN
  -- create a new georaster object with georid = 2
  -- to hold the compressed image
  delete from georaster_table where georid = 2;
  insert into georaster_table(georid, georaster) values (2,
     sdo_geor.init('RDT2', 2)) returning georaster into gr;


  -- reblock and compress the image with georid = 1 into JPEG using parallel degree of 8
  open cur for 'select georaster from georaster_table where georid = 1';
  sdo_geor_aggr.mosaicSubset(cur, 0, null, null, null, crop_area,
                             null, null, null, null, null, null,
                             'compression=JPEG-F, blocking=optimalpadding, blocksize=(512,512,3)',
                             gr, null, 'parallel=8');

  update georaster_table set georaster = gr where georid = 2;
  commit;
END;
/

In the preceding example, if you adjust the storageParam parameter, it works as a parallelized SDO_GEOR.changeFormatCopy operation, including compression and decompression.

Example: Parallel Subsetting and Copying

Example: Parallel Subsetting and Copying shows parallel subsetting and copying using theSDO_GEOR_AGGR.mosaicSubset procedure.

DECLARE
  gr sdo_georaster;
  cur sys_refcursor;
  crop_area sdo_geometry := null;
BEGIN
  -- create a new georaster object with georid = 2 to hold the copy
  delete from georaster_table where georid = 2;
  insert into georaster_table(georid, georaster) values (2,
     sdo_geor.init('RDT2', 2)) returning georaster into gr;


  -- set the crop_area for subsetting.
  crop_area := sdo_geometry(2003, 26986, null, sdo_elem_info_array(1,1003,1),
                sdo_ordinate_array(237040,   897924,
                                   237013.3, 897831.6,
                                   237129,   897840,
                                   237182.5, 897785.5,
                                   237239.9, 897902.7,
                                   237223,   897954,
                                   237133,   897899,
                                   237040,   897924));

  -- subset from the image with georid = 1 using parallel degree of 8
  -- and do polygon clipping
  -- If the crop_area is set to null, the same call will do a simple parallelized copying without subsetting.
  open cur for 'select georaster from georaster_table where georid = 1';
  sdo_geor_aggr.mosaicSubset(cur, 0, null, null, null, crop_area,
                             'true', null, null, null, null, null,
                             'pyramid=true', gr, null, 'parallel=8');
  update georaster_table set georaster = gr where georid = 2;
  commit;
END;
/

In Example: Parallel Subsetting and Copying, if you adjust the storageParam parameter, it works as a parallelized copy or SDO_GEOR.changeFormatCopy operation, including compression and decompression.