Opened 12 years ago

Closed 12 years ago

Last modified 12 years ago

#3142 closed defect (fixed)

Erroneous values in destination image with gdalwarp's interpolations

Reported by: andrieu Owned by: warmerdam
Priority: normal Milestone: 1.7.0
Component: Utilities Version: unspecified
Severity: normal Keywords: gdalwarp interpolation
Cc:

Description

Hello,

I have been trying to use gdalwarp to make some image merging and reprojection.

Unfortunately, with gdalwarp, the use of interpolations others than bilinear will produce images with wrong values.

My source pictures are Byte, 1 band, nodata = 0.

I have trying to use various destination datatype but they all lead to the same results : values in the destination image are below 0 (I even found a value around -80...) and so are considered as nodata.

My conversion script is :

gdal_translate -projwin 713676 4783608 713692 4783597 PIC_SS_P_821_8bit.tif little.tif

gdalwarp -t_srs EPSG:4326 -r bilinear -ot Int32 -dstnodata -100 little.tif little_bilinear_1.tif
gdalwarp -t_srs EPSG:4326 -r cubic -ot Int32 -dstnodata -100 little.tif little_cubic_1.tif
gdalwarp -t_srs EPSG:4326 -r cubicspline -ot Int32 -dstnodata -100 little.tif little_cubicspline_1.tif
gdalwarp -t_srs EPSG:4326 -r lanczos -ot Int32 -dstnodata -100 little.tif little_lanczos_1.tif

I then use a gdal_translate to add compression, tiling and correct nodata :

gdal_translate -ot Byte -a_nodata 0 -scale 0 255 1 255 -co TILED=YES -co COMPRESS=DEFLATE -co PREDICTOR=1 source dest

And finally a gdaladdo pass.

The reason I make a gdalwarp in a signed datatype is that the interpolation does not take the nodata value in consideration so my destination image will be filled with wrong nodata. So to avoid that, use of gdalwarp in signed datatype followed by a gdal_translate in unsigned datatype with scaling will produce correct nodata.

By the way, I am using FWTools 2.2.9 and 2.4.3 (same results).

This is very sad because image quality is better with lanczos than with bilinear...

Regards,

Benoit Andrieu

Attachments (5)

little.tif (17.6 KB) - added by andrieu 12 years ago.
Source image
little_bilinear_1.tif (65.2 KB) - added by andrieu 12 years ago.
Bilinear result with Int32
little_cubic_1.tif (65.2 KB) - added by andrieu 12 years ago.
Cubic result with Int32
little_cubicspline_1.tif (65.2 KB) - added by andrieu 12 years ago.
Cubicspline result with Int32
little_lanczos_1.tif (65.2 KB) - added by andrieu 12 years ago.
Lanczos result with Int32

Download all attachments as: .zip

Change History (9)

Changed 12 years ago by andrieu

Attachment: little.tif added

Source image

Changed 12 years ago by andrieu

Attachment: little_bilinear_1.tif added

Bilinear result with Int32

Changed 12 years ago by andrieu

Attachment: little_cubic_1.tif added

Cubic result with Int32

Changed 12 years ago by andrieu

Attachment: little_cubicspline_1.tif added

Cubicspline result with Int32

Changed 12 years ago by andrieu

Attachment: little_lanczos_1.tif added

Lanczos result with Int32

comment:1 Changed 12 years ago by andrieu

Component: defaultUtilities
Keywords: gdalwarp interpolation added

comment:2 Changed 12 years ago by Even Rouault

Milestone: 1.7.0
Resolution: fixed
Status: newclosed

Several things :

  • if you use a negative nodata value, yes, you must use a signed datatype. I've added in r17658 a check to clamp nodata values if they go outside the valid range of the datatype.
  • the negative values you get for cubic, cubicspline and lanczos are not surprising, considering the non-linear underlying maths. For example, on your example with cubic, at a moment we compute CubicConvolution?(d, d*d, d*d*d, f0, f1, f2, f3) where d = 0.136, f0 = 37, f1 = f2 = f3 = 1. The result is -2.66. bilinear interpolation of course doesn't allow for those undershoot or overshoot effects.
  • in those cases, using an unsigned datatype leads to truncation to positive range, hence those negative interpolated values are clamped to 0. If 0 is the chosen nodata value, then it might be a problem. So in r17659, I've added a check so that if a computed pixel value is equal to a destination nodata value, we use the integer above or under instead.

comment:3 Changed 12 years ago by andrieu

Thanks for the changes ! That should do the trick !!! I'll test those as soon as possible (I'm on holidays...)

comment:4 Changed 12 years ago by andrieu

Ok, as you said, computed values equal to nodata are set to the above value.

Thanks !

Note: See TracTickets for help on using tickets.