Re: [gdal-dev] GDALWarp API and paletted images
I have those nodata-values there since the same code path is used for elevation data and such, but it had no effect to remove it. I have narrowed it down to the case where I use an overview as input. I have some very large images with overviews, so I find the overview closest matching to the output resolution of my image and make a VRT of the overview level like this: vrtDS = vrtDriver-Create(, ovrW, ovrH, _numBands, _dataType, NULL); GDALSetProjection(vrtDS, _srcProjectionWKT.c_str()); geoTransform[XFM_PIXEL_SIZE_EW] = scaleX*basePixelSizeX; geoTransform[XFM_PIXEL_SIZE_NS] = scaleY*basePixelSizeY; vrtDS-SetGeoTransform(geoTransform); for(int i = 1; i = _numBands; i++) { GDALRasterBand* srcRootBand = _ds-GetRasterBand(i); GDALRasterBand* srcBand = srcRootBand-GetOverview(overviewId); VRTSourcedRasterBand* vrtBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(i); vrtBand-AddSimpleSource(srcBand); } srcDS = vrtDS; The strange thing is that this used to work when I had the same mistake as you pointed out, where I added the bands twice, i.e the overview had 6 bands, but only three or four of them were used in the warp operation. When fixing the code, I got this problem. Is this the best way to do it btw, or is it a better way to make use of overviews when cutting out and reprojecting parts of a big image? Thanks again for all your help :-) - Thomas On Fri, Jun 12, 2015 at 1:35 PM, Even Rouault even.roua...@spatialys.com wrote: Selon Thomas Sevaldrud tho...@silentwings.no: Thanks again! The problem was in the warper setup, it used only the first band of the image. This also revealed a bug in another part of my code related to VRT's and Warp, since I had added double sets of bands there as well. However, when fixing this, some old code stopped working :-) Basically, my problem is that I want to reproject an RGB image which may be the VRT I made above, or another RGB(A) image, into an output RGBA. If I don't have an input alpha channel, I still want the output to have alpha, and I want any borders that result from the reprojection to have alpha = 0. What is the correct way of setting up this? Currently I set up the bands like this: warpOptions-nBandCount = srcNumBands; warpOptions-panSrcBands = (int*)CPLMalloc(warpOptions-nBandCount*sizeof(int)); warpOptions-panDstBands = (int*)CPLMalloc(warpOptions-nBandCount*sizeof(int)); warpOptions-padfSrcNoDataReal = (double*)CPLMalloc(warpOptions-nBandCount*sizeof(double)); warpOptions-padfSrcNoDataImag = (double*)CPLMalloc(warpOptions-nBandCount*sizeof(double)); warpOptions-padfDstNoDataReal = (double*)CPLMalloc(warpOptions-nBandCount*sizeof(double)); warpOptions-padfDstNoDataImag = (double*)CPLMalloc(warpOptions-nBandCount*sizeof(double)); for (int j = 0; j warpOptions-nBandCount; j++) { warpOptions-panSrcBands[j] = j+1; warpOptions-panDstBands[j] = j+1; warpOptions-padfSrcNoDataReal[j] = _srcNodata; warpOptions-padfSrcNoDataImag[j] = 0.0; warpOptions-padfDstNoDataReal[j] = _nodata; warpOptions-padfDstNoDataImag[j] = 0.0; } if (srcNumBands == 4) warpOptions-nSrcAlphaBand = 4; if (dstNumBands == 4) warpOptions-nDstAlphaBand = 4; char **papszWarpOptions = NULL; papszWarpOptions = CSLSetNameValue(papszWarpOptions, INIT_DEST, NO_DATA ); In some cases this works, but in others I get only a black image after the warp. So my question is basically if the above code should have worked. My assumption here is that the GDAL Warper will regard all input pixels as having full opacity when no alpha channel is specified, and that output alpha is initialized to 0. Are these valid assumptions, or do I need to create an alpha channel in the input image as well? I don't see anything fundamentally wrong in the above. If your source image is fully opaque, you don't need to set padfSrcNoDataReal and padfSrcNoDataImag. And if you have an output alpha channel, you don't need to set padfDstNoDataReal and padfDstNoDataImag too. In that cas you would just do papszWarpOptions = CSLSetNameValue(papszWarpOptions, INIT_DEST, 0 ); I'm not sure this will change the end result however. - Thomas On Thu, Jun 11, 2015 at 5:25 PM, Even Rouault even.roua...@spatialys.com wrote: Selon Thomas Sevaldrud tho...@silentwings.no: Great, thanks! I tried this, but got only a red image as result, so I guess only the first channel was used. This is the relevant code, where _ds is the input paletted data set vrtDS = vrtDriver-Create(, origW, origH, 3, GDT_Byte, NULL); double geoTransform[6]; _ds-GetGeoTransform(geoTransform); vrtDS-SetGeoTransform(geoTransform); GDALSetProjection(vrtDS, _srcProjectionWKT.c_str()); GDALRasterBand* srcBand = _ds-GetRasterBand(1); vrtDS-AddBand(GDT_Byte, NULL); vrtDS-AddBand(GDT_Byte, NULL); vrtDS-AddBand(GDT_Byte, NULL); You don't need the above
Re: [gdal-dev] GDALWarp API and paletted images
Thanks again! The problem was in the warper setup, it used only the first band of the image. This also revealed a bug in another part of my code related to VRT's and Warp, since I had added double sets of bands there as well. However, when fixing this, some old code stopped working :-) Basically, my problem is that I want to reproject an RGB image which may be the VRT I made above, or another RGB(A) image, into an output RGBA. If I don't have an input alpha channel, I still want the output to have alpha, and I want any borders that result from the reprojection to have alpha = 0. What is the correct way of setting up this? Currently I set up the bands like this: warpOptions-nBandCount = srcNumBands; warpOptions-panSrcBands = (int*)CPLMalloc(warpOptions-nBandCount*sizeof(int)); warpOptions-panDstBands = (int*)CPLMalloc(warpOptions-nBandCount*sizeof(int)); warpOptions-padfSrcNoDataReal = (double*)CPLMalloc(warpOptions-nBandCount*sizeof(double)); warpOptions-padfSrcNoDataImag = (double*)CPLMalloc(warpOptions-nBandCount*sizeof(double)); warpOptions-padfDstNoDataReal = (double*)CPLMalloc(warpOptions-nBandCount*sizeof(double)); warpOptions-padfDstNoDataImag = (double*)CPLMalloc(warpOptions-nBandCount*sizeof(double)); for (int j = 0; j warpOptions-nBandCount; j++) { warpOptions-panSrcBands[j] = j+1; warpOptions-panDstBands[j] = j+1; warpOptions-padfSrcNoDataReal[j] = _srcNodata; warpOptions-padfSrcNoDataImag[j] = 0.0; warpOptions-padfDstNoDataReal[j] = _nodata; warpOptions-padfDstNoDataImag[j] = 0.0; } if (srcNumBands == 4) warpOptions-nSrcAlphaBand = 4; if (dstNumBands == 4) warpOptions-nDstAlphaBand = 4; char **papszWarpOptions = NULL; papszWarpOptions = CSLSetNameValue(papszWarpOptions, INIT_DEST, NO_DATA ); In some cases this works, but in others I get only a black image after the warp. So my question is basically if the above code should have worked. My assumption here is that the GDAL Warper will regard all input pixels as having full opacity when no alpha channel is specified, and that output alpha is initialized to 0. Are these valid assumptions, or do I need to create an alpha channel in the input image as well? - Thomas On Thu, Jun 11, 2015 at 5:25 PM, Even Rouault even.roua...@spatialys.com wrote: Selon Thomas Sevaldrud tho...@silentwings.no: Great, thanks! I tried this, but got only a red image as result, so I guess only the first channel was used. This is the relevant code, where _ds is the input paletted data set vrtDS = vrtDriver-Create(, origW, origH, 3, GDT_Byte, NULL); double geoTransform[6]; _ds-GetGeoTransform(geoTransform); vrtDS-SetGeoTransform(geoTransform); GDALSetProjection(vrtDS, _srcProjectionWKT.c_str()); GDALRasterBand* srcBand = _ds-GetRasterBand(1); vrtDS-AddBand(GDT_Byte, NULL); vrtDS-AddBand(GDT_Byte, NULL); vrtDS-AddBand(GDT_Byte, NULL); You don't need the above 3 AddBand() since you called Create() with 3 already VRTSourcedRasterBand* vrtRBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(1); VRTSourcedRasterBand* vrtGBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(2); VRTSourcedRasterBand* vrtBBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(3); vrtRBand-AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0, 1.0, VRT_NODATA_UNSET, 1); vrtGBand-AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0, 1.0, VRT_NODATA_UNSET, 2); vrtBBand-AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0, 1.0, VRT_NODATA_UNSET, 3); Is there anything I have missed in the setup here? Looks good otherwise. Did you check that you configured properly the warper to use the 3 bands of the VRT ? - Thomas On Tue, Jun 9, 2015 at 1:44 PM, Even Rouault even.roua...@spatialys.com wrote: Thomas, I'm using the GDALWarp api from C++ to reproject and cut various input images. In general this works very well for my purposes, except that for paletted images I have to use NearestNeighbour resampling, I would like to use Bilinear or higher order resampling, and wonder if there is any way to expand a paletted image to true RGB during the warp process, so I can use these resampling methods. No, you must use an intermediate step before. Alternatively, is there a way to do this conversion (from code) before the warp without having to run through the entire image in memory? You can use a in-memory VRT dataset to do on-the-fly expansion to RGB. With the AddComplexSource() method of VRTSourcedRasterBand class: CPLErr AddComplexSource( GDALRasterBand *poSrcBand, int nSrcXOff=-1, int nSrcYOff=-1, int nSrcXSize=-1, int nSrcYSize=-1, int nDstXOff=-1, int nDstYOff=-1, int nDstXSize=-1, int nDstYSize=-1,
Re: [gdal-dev] GDALWarp API and paletted images
Selon Thomas Sevaldrud tho...@silentwings.no: Thanks again! The problem was in the warper setup, it used only the first band of the image. This also revealed a bug in another part of my code related to VRT's and Warp, since I had added double sets of bands there as well. However, when fixing this, some old code stopped working :-) Basically, my problem is that I want to reproject an RGB image which may be the VRT I made above, or another RGB(A) image, into an output RGBA. If I don't have an input alpha channel, I still want the output to have alpha, and I want any borders that result from the reprojection to have alpha = 0. What is the correct way of setting up this? Currently I set up the bands like this: warpOptions-nBandCount = srcNumBands; warpOptions-panSrcBands = (int*)CPLMalloc(warpOptions-nBandCount*sizeof(int)); warpOptions-panDstBands = (int*)CPLMalloc(warpOptions-nBandCount*sizeof(int)); warpOptions-padfSrcNoDataReal = (double*)CPLMalloc(warpOptions-nBandCount*sizeof(double)); warpOptions-padfSrcNoDataImag = (double*)CPLMalloc(warpOptions-nBandCount*sizeof(double)); warpOptions-padfDstNoDataReal = (double*)CPLMalloc(warpOptions-nBandCount*sizeof(double)); warpOptions-padfDstNoDataImag = (double*)CPLMalloc(warpOptions-nBandCount*sizeof(double)); for (int j = 0; j warpOptions-nBandCount; j++) { warpOptions-panSrcBands[j] = j+1; warpOptions-panDstBands[j] = j+1; warpOptions-padfSrcNoDataReal[j] = _srcNodata; warpOptions-padfSrcNoDataImag[j] = 0.0; warpOptions-padfDstNoDataReal[j] = _nodata; warpOptions-padfDstNoDataImag[j] = 0.0; } if (srcNumBands == 4) warpOptions-nSrcAlphaBand = 4; if (dstNumBands == 4) warpOptions-nDstAlphaBand = 4; char **papszWarpOptions = NULL; papszWarpOptions = CSLSetNameValue(papszWarpOptions, INIT_DEST, NO_DATA ); In some cases this works, but in others I get only a black image after the warp. So my question is basically if the above code should have worked. My assumption here is that the GDAL Warper will regard all input pixels as having full opacity when no alpha channel is specified, and that output alpha is initialized to 0. Are these valid assumptions, or do I need to create an alpha channel in the input image as well? I don't see anything fundamentally wrong in the above. If your source image is fully opaque, you don't need to set padfSrcNoDataReal and padfSrcNoDataImag. And if you have an output alpha channel, you don't need to set padfDstNoDataReal and padfDstNoDataImag too. In that cas you would just do papszWarpOptions = CSLSetNameValue(papszWarpOptions, INIT_DEST, 0 ); I'm not sure this will change the end result however. - Thomas On Thu, Jun 11, 2015 at 5:25 PM, Even Rouault even.roua...@spatialys.com wrote: Selon Thomas Sevaldrud tho...@silentwings.no: Great, thanks! I tried this, but got only a red image as result, so I guess only the first channel was used. This is the relevant code, where _ds is the input paletted data set vrtDS = vrtDriver-Create(, origW, origH, 3, GDT_Byte, NULL); double geoTransform[6]; _ds-GetGeoTransform(geoTransform); vrtDS-SetGeoTransform(geoTransform); GDALSetProjection(vrtDS, _srcProjectionWKT.c_str()); GDALRasterBand* srcBand = _ds-GetRasterBand(1); vrtDS-AddBand(GDT_Byte, NULL); vrtDS-AddBand(GDT_Byte, NULL); vrtDS-AddBand(GDT_Byte, NULL); You don't need the above 3 AddBand() since you called Create() with 3 already VRTSourcedRasterBand* vrtRBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(1); VRTSourcedRasterBand* vrtGBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(2); VRTSourcedRasterBand* vrtBBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(3); vrtRBand-AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0, 1.0, VRT_NODATA_UNSET, 1); vrtGBand-AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0, 1.0, VRT_NODATA_UNSET, 2); vrtBBand-AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0, 1.0, VRT_NODATA_UNSET, 3); Is there anything I have missed in the setup here? Looks good otherwise. Did you check that you configured properly the warper to use the 3 bands of the VRT ? - Thomas On Tue, Jun 9, 2015 at 1:44 PM, Even Rouault even.roua...@spatialys.com wrote: Thomas, I'm using the GDALWarp api from C++ to reproject and cut various input images. In general this works very well for my purposes, except that for paletted images I have to use NearestNeighbour resampling, I would like to use Bilinear or higher order resampling, and wonder if there is any way to expand a paletted image to true RGB during the warp process, so I can use these resampling methods. No, you must use an intermediate step before. Alternatively, is there a way to do this conversion (from code) before the warp without having to run through the
Re: [gdal-dev] GDALWarp API and paletted images
Great, thanks! I tried this, but got only a red image as result, so I guess only the first channel was used. This is the relevant code, where _ds is the input paletted data set vrtDS = vrtDriver-Create(, origW, origH, 3, GDT_Byte, NULL); double geoTransform[6]; _ds-GetGeoTransform(geoTransform); vrtDS-SetGeoTransform(geoTransform); GDALSetProjection(vrtDS, _srcProjectionWKT.c_str()); GDALRasterBand* srcBand = _ds-GetRasterBand(1); vrtDS-AddBand(GDT_Byte, NULL); vrtDS-AddBand(GDT_Byte, NULL); vrtDS-AddBand(GDT_Byte, NULL); VRTSourcedRasterBand* vrtRBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(1); VRTSourcedRasterBand* vrtGBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(2); VRTSourcedRasterBand* vrtBBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(3); vrtRBand-AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0, 1.0, VRT_NODATA_UNSET, 1); vrtGBand-AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0, 1.0, VRT_NODATA_UNSET, 2); vrtBBand-AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0, 1.0, VRT_NODATA_UNSET, 3); Is there anything I have missed in the setup here? - Thomas On Tue, Jun 9, 2015 at 1:44 PM, Even Rouault even.roua...@spatialys.com wrote: Thomas, I'm using the GDALWarp api from C++ to reproject and cut various input images. In general this works very well for my purposes, except that for paletted images I have to use NearestNeighbour resampling, I would like to use Bilinear or higher order resampling, and wonder if there is any way to expand a paletted image to true RGB during the warp process, so I can use these resampling methods. No, you must use an intermediate step before. Alternatively, is there a way to do this conversion (from code) before the warp without having to run through the entire image in memory? You can use a in-memory VRT dataset to do on-the-fly expansion to RGB. With the AddComplexSource() method of VRTSourcedRasterBand class: CPLErr AddComplexSource( GDALRasterBand *poSrcBand, int nSrcXOff=-1, int nSrcYOff=-1, int nSrcXSize=-1, int nSrcYSize=-1, int nDstXOff=-1, int nDstYOff=-1, int nDstXSize=-1, int nDstYSize=-1, double dfScaleOff=0.0, double dfScaleRatio=1.0, double dfNoDataValue = VRT_NODATA_UNSET, int nColorTableComponent = 0); Set nColorTableComponent to 1,2,3 for respectively R,G,B. This is what gdal_translate will do if you use gdal_translate -of VRT -expand rgb pct.tif out.vrt Even -- Spatialys - Geospatial professional services http://www.spatialys.com ___ gdal-dev mailing list gdal-dev@lists.osgeo.org http://lists.osgeo.org/mailman/listinfo/gdal-dev
Re: [gdal-dev] GDALWarp API and paletted images
Selon Thomas Sevaldrud tho...@silentwings.no: Great, thanks! I tried this, but got only a red image as result, so I guess only the first channel was used. This is the relevant code, where _ds is the input paletted data set vrtDS = vrtDriver-Create(, origW, origH, 3, GDT_Byte, NULL); double geoTransform[6]; _ds-GetGeoTransform(geoTransform); vrtDS-SetGeoTransform(geoTransform); GDALSetProjection(vrtDS, _srcProjectionWKT.c_str()); GDALRasterBand* srcBand = _ds-GetRasterBand(1); vrtDS-AddBand(GDT_Byte, NULL); vrtDS-AddBand(GDT_Byte, NULL); vrtDS-AddBand(GDT_Byte, NULL); You don't need the above 3 AddBand() since you called Create() with 3 already VRTSourcedRasterBand* vrtRBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(1); VRTSourcedRasterBand* vrtGBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(2); VRTSourcedRasterBand* vrtBBand = (VRTSourcedRasterBand*)vrtDS-GetRasterBand(3); vrtRBand-AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0, 1.0, VRT_NODATA_UNSET, 1); vrtGBand-AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0, 1.0, VRT_NODATA_UNSET, 2); vrtBBand-AddComplexSource(srcBand, -1, -1, -1, -1, -1, -1, -1, -1, 0.0, 1.0, VRT_NODATA_UNSET, 3); Is there anything I have missed in the setup here? Looks good otherwise. Did you check that you configured properly the warper to use the 3 bands of the VRT ? - Thomas On Tue, Jun 9, 2015 at 1:44 PM, Even Rouault even.roua...@spatialys.com wrote: Thomas, I'm using the GDALWarp api from C++ to reproject and cut various input images. In general this works very well for my purposes, except that for paletted images I have to use NearestNeighbour resampling, I would like to use Bilinear or higher order resampling, and wonder if there is any way to expand a paletted image to true RGB during the warp process, so I can use these resampling methods. No, you must use an intermediate step before. Alternatively, is there a way to do this conversion (from code) before the warp without having to run through the entire image in memory? You can use a in-memory VRT dataset to do on-the-fly expansion to RGB. With the AddComplexSource() method of VRTSourcedRasterBand class: CPLErr AddComplexSource( GDALRasterBand *poSrcBand, int nSrcXOff=-1, int nSrcYOff=-1, int nSrcXSize=-1, int nSrcYSize=-1, int nDstXOff=-1, int nDstYOff=-1, int nDstXSize=-1, int nDstYSize=-1, double dfScaleOff=0.0, double dfScaleRatio=1.0, double dfNoDataValue = VRT_NODATA_UNSET, int nColorTableComponent = 0); Set nColorTableComponent to 1,2,3 for respectively R,G,B. This is what gdal_translate will do if you use gdal_translate -of VRT -expand rgb pct.tif out.vrt Even -- Spatialys - Geospatial professional services http://www.spatialys.com -- Spatialys - Geospatial professional services http://www.spatialys.com ___ gdal-dev mailing list gdal-dev@lists.osgeo.org http://lists.osgeo.org/mailman/listinfo/gdal-dev
[gdal-dev] GDALWarp API and paletted images
Hi, I'm using the GDALWarp api from C++ to reproject and cut various input images. In general this works very well for my purposes, except that for paletted images I have to use NearestNeighbour resampling, I would like to use Bilinear or higher order resampling, and wonder if there is any way to expand a paletted image to true RGB during the warp process, so I can use these resampling methods. Alternatively, is there a way to do this conversion (from code) before the warp without having to run through the entire image in memory? - Thomas ___ gdal-dev mailing list gdal-dev@lists.osgeo.org http://lists.osgeo.org/mailman/listinfo/gdal-dev
Re: [gdal-dev] GDALWarp API and paletted images
Thomas, I'm using the GDALWarp api from C++ to reproject and cut various input images. In general this works very well for my purposes, except that for paletted images I have to use NearestNeighbour resampling, I would like to use Bilinear or higher order resampling, and wonder if there is any way to expand a paletted image to true RGB during the warp process, so I can use these resampling methods. No, you must use an intermediate step before. Alternatively, is there a way to do this conversion (from code) before the warp without having to run through the entire image in memory? You can use a in-memory VRT dataset to do on-the-fly expansion to RGB. With the AddComplexSource() method of VRTSourcedRasterBand class: CPLErr AddComplexSource( GDALRasterBand *poSrcBand, int nSrcXOff=-1, int nSrcYOff=-1, int nSrcXSize=-1, int nSrcYSize=-1, int nDstXOff=-1, int nDstYOff=-1, int nDstXSize=-1, int nDstYSize=-1, double dfScaleOff=0.0, double dfScaleRatio=1.0, double dfNoDataValue = VRT_NODATA_UNSET, int nColorTableComponent = 0); Set nColorTableComponent to 1,2,3 for respectively R,G,B. This is what gdal_translate will do if you use gdal_translate -of VRT -expand rgb pct.tif out.vrt Even -- Spatialys - Geospatial professional services http://www.spatialys.com ___ gdal-dev mailing list gdal-dev@lists.osgeo.org http://lists.osgeo.org/mailman/listinfo/gdal-dev