6.4 Image Orthorectification

Orthorectification is a rectification transformation process where information about the elevation, the terrain, and the shape of the Earth is used to improve the quality of the output rectified image. Oracle GeoRaster supports single image orthorectification with average height value or DEM.

The orthorectification is done by the SDO_GEOR.rectify procedure and requires that the source GeoRaster have a 3D SRS. The SDO_GEOR.rectify procedure can execute orthorectification with just the average height of the area or with a detailed Digital Elevation Model (DEM).

6.4.1 Orthorectification with Average Height

A GeoRaster object with a Digital Elevation Model (DEM) is optional for orthorectification. For relatively flat terrains, the 3D SRS together with the average height value might be sufficient to correct the distortion of the source image.

Example 6-5 Orthorectification with Average Height

Example 6-5 shows orthorectification with average height. For this example, the source image was acquired from DigitalGlobe with RPC. The DEM was not available, but the average elevation of the area is known to be 1748.0 meters.

DECLARE
  gr_src  sdo_georaster;
  gr_out  sdo_georaster;
BEGIN
  select georaster into gr_src from georaster_table where georid = 1;
  delete from georaster_table where georid = 3;
  insert into georaster_table values(3, 'orthorectified without DEM',
         sdo_geor.init('rdt_4',3)) 
         returning georaster into gr_out;
  sdo_geor.rectify(inGeoRaster      => gr_src,
                   pyramidLevel     => null,
                   elevationParam   => 'average=1748.8',
                   dem              => null,
                   outSRID          => 32613,
                   outModelCoordLoc => null,
                   cropArea         => null,
                   polygonClip      => null,
                   layerNumbers     => null,
                   outResolutions   => null,
                   resolutionUnit   => null,
                   referencePoint   => null,
                   resampleParam    => 'resampling=AVERAGE4',
                   storageParam     => null,
                   outGeoraster     => gr_out);
  update georaster_table set georaster = gr_out where georid = 3;
  commit;
END;

In Example 6-5, the dem parameter is null, and the elevationParam average elevation must be in the same unit as the SRS. Also, in elevationParam the offset and scale keywords are not specified because they are relevant only if DEM is specified.

6.4.2 Orthorectification with DEM

The use of a DEM (Digital Elevation Model) layer improves the accuracy of the rectification process and therefore produces a higher quality output GeoRaster object.

Orthorectification with DEM requires that the source GeoRaster have a 3D SRS. The DEM must cover all the target output area, and it should be in the same SRID as the output. The resolution of the DEM should be similar to the expected resolution of the output GeoRaster object.

For orthorectification with DEM, the elevationParam average keyword is optional; and if it is not specified, the procedure estimates elevation values based on sample values extracted from the DEM on the target area.

The elevationParam offset and scale values can be used to modify the values from the DEM. For example, scale can be used for unit conversion if the DEM values are in a unit other than that of the source GeoRaster SRS, and offset can be used to perform geoidal correction or other offsetting. However, these specifications do not apply the changes to DEM values in the GeoRaster object. An alternative is to pre-process the DEM values by applying the scaling and offsetting to the DEM data before the orthorectification, as explained in Raster Data Scaling and Offsetting.

Example 6-6 Orthorectification with DEM

Example 6-6 example performs orthorectification with DEM. The DEM covers all the output area in a resolution approximated to the resolution of the output GeoRaster. The DEM values are in meters but the source image SRS is in feet. There is also a geoid correction on that area of about -15.3 meters:

DECLARE
  gr_src  sdo_georaster;
  gr_dem  sdo_georaster;
  gr_out  sdo_georaster;
BEGIN
  select georaster into gr_src from georaster_table where georid = 1;
  select georaster into gr_dem from georaster_table where georid = 5;
  delete from georaster_table where georid = 6;
  insert into georaster_table values(5, 'orthorectified with DEM',
         sdo_geor.init('rdt_4',6)) 
         returning georaster into gr_out;
  sdo_geor.rectify(inGeoRaster      => gr_src,
                   pyramidLevel     => null,
                   elevationParam   => 'average=1748.8 offset=-15.3',
                   dem              => gr_dem,
                   outSRID          => 32613,
                   outModelCoordLoc => null,
                   cropArea         => null,
                   polygonClip      => null,
                   layerNumbers     => null,
                   outResolutions   => null,
                   resolutionUnit   => null,
                   referencePoint   => null,
                   resampleParam    => 'resampling=BILINEAR',
                   storageParam     => null,
                   outGeoraster     => gr_out);
  update georaster_table set georaster = gr_out where georid = 6;
  commit;
END;

Example 6-7 Orthorectification with Cropped DEM

Typically, the DEM covers an area much larger than the target area, and the resolution is coarser than the target resolution of the output GeoRaster object. Using this DEM "as is" would result in poor quality orthorectification. The solution to that common problem is to crop the DEM to the target area and rescale it to the desired resolution, as shown in Example 6-7. This example uses the SDO_GEOR.rectify procedure to transform the low-resolution DEM GeoRaster object into a second DEM GeoRaster object that has the same resolution as the orthorectified GeoRaster object generated by the second call to the SDO_GEOR.rectify procedure.

DECLARE
  height   number := 1748.8;
  gr_src   sdo_georaster;
  gr_out   sdo_georaster;
  gr_dem   sdo_georaster;
  gr_dem2  sdo_georaster;
  gm_area  sdo_geometry;
begin
  select georaster into gr_src from georaster_table where georid = 1;
  select georaster into gr_dem from georaster_table where georid = 2;
  -- Calculate crop area
  gm_area := sdo_cs.make_2d(
             sdo_geor.generateSpatialExtent(gr_src,height),
             sdo_geor.getModelSRID(gr_dem));
  -- Rectify dem ( re-project, crop area, re-escale and resample )
  delete from georaster_table where georid = 4;
  insert into georaster_table values(4, 
              'rectified DEM',
              sdo_geor.init('rdt_4',4)) 
              returning georaster into gr_dem2;
  sdo_geor.rectify(inGeoRaster      => gr_dem,
                   pyramidLevel     => null,
                   elevationParam   => null,
                   dem              => null,
                   outSRID          => 32613,
                   outModelCoordLoc => null,
                   cropArea         => gm_area,
                   polygonClip      => null,
                   layerNumbers     => null,
                   outResolutions   => sdo_number_array(0.6,0.6),
                   resolutionUnit   => null,
                   referencePoint   => null,
                   resampleParam    => 'resampling=CUBIC',
                   storageParam     => null,
                   outGeoraster     => gr_dem2);
  update georaster_table set georaster = gr_dem2 where georid = 4;
  commit;
  -- Orthorectification with DEM
  select georaster into gr_dem2 from georaster_table where georid = 4;
  delete from georaster_table where georid = 5;
  insert into georaster_table 
         values(5, 'orthorectified', sdo_geor.init('rdt_4',5)) 
         returning georaster into gr_out;
  sdo_geor.rectify(inGeoRaster      => gr_src,
                   pyramidLevel     => null,
                   elevationParam   => 
                          'average=' || height || ' offset=-15.588',
                   dem              => gr_dem2,
                   outSRID          => 32613,
                   outModelCoordLoc => null,
                   cropArea         => gm_area,
                   polygonClip      => null,
                   layerNumbers     => null,
                   outResolutions   => sdo_number_array(0.6,0.6),
                   resolutionUnit   => null,
                   referencePoint   => null,
                   resampleParam    => 'resampling=average16',
                   storageParam     => null,
                   outGeoraster     => gr_out);
  update georaster_table set georaster = gr_out where georid = 5;
  commit;
end;
/