[Gdal-dev] RE: GCPs and Thin Plate Splines - C++
chris pozsgai
poz at rocketmail.com
Fri Mar 9 06:52:54 EST 2007
Hello again..
I would like to repost my query to the mailing list regarding the thin plate
splines... (I now have access to my code and the internet at the same time.)
I was able to get reasonable results using the
GDALGCPsToGeoTransform function to generate a geo transform, but I would
like to have an exact fit at the GCPs. That drove me to delve further into the
GDAL functionality where I ran across the warping functions.
I tried to first use the gdal warper to be able to reproduce the results I got
using the GDALGCPstoGeoTransform function with the warper. I was
not able to do that, but here is the code that I wrote. My intention was to
look at the TPS transform's ability to preserve the GCP values, but I could not
get that to work, or even to reproduce the results from GDALGCPsToGeoTransform
using regular GCP warping.
I apologize for putting this much code on the mailing but I guess it's the best way....
NOTE: m_pRasterDataset is the dataset that will be used for rendering and is initially
loaded as a JPEG dataset with a set of GCPs. (The gcpCount and gcp list
are passed in the parameter list for clarity.)
// This method transforms gcps and saves in the raster dataset.
// 0 = use GDALGCPsToGeoTrans, 1 = use GCP warp, 2 = use TPS GCP warp
bool CGDALGCPImageFile::transformGCPs(int gcpCount, const GDAL_GCP *pGCPList, int iMethod)
{
// Ensure we have a good dataset and it hasn't already been loaded.
bool bOK = m_pRasterDataset != NULL && !hasBeenLoaded();
if(bOK)
{
// Get the regular transform.
double adfGeoTransform[6];
bOK = GDALGCPsToGeoTransform(gcpCount, pGCPList, adfGeoTransform, TRUE);
if(iMethod == 0)
{
// Set it and return.
m_pRasterDataset->SetGeoTransform(adfGeoTransform);
}
else
{
// Set up the warping.
char *pszSrcWKT = NULL, *pszDstWKT = NULL;
OGRSpatialReference oSRS;
oSRS.SetWellKnownGeogCS("WGS84");
oSRS.exportToWkt(&pszSrcWKT);
oSRS.exportToWkt(&pszDstWKT);
double defGeoTrans[6] = {0., 1., 0., 0., 0., 1.};
// Ensure we have set the geo transform as the default.
CPLErr err = m_pRasterDataset->SetGeoTransform(defGeoTrans);
int i = 0;
GDALWarpOptions *psWO = GDALCreateWarpOptions();
psWO->eResampleAlg = GRA_NearestNeighbour;
psWO->pfnProgress = GDALTProgressGCP;
// Create the dest dataset.
double adfDstGeoTransform[6] = {0., 1., 0., 0., 0., 1.};
// Copy off the raster metadata into a new dataset.
GDALDatasetH hSrcDS = CopyRasterWindow(m_pRasterDataset, 0, 0,
m_pRasterDataset->GetRasterXSize(), m_pRasterDataset->GetRasterYSize());
int nBands = GDALGetRasterCount(hSrcDS);
vector<GDALColorInterp> srcColors;
for(int i = 1; i <= nBands; i++)
{
GDALRasterBand *poSrcBand = m_pRasterDataset->GetRasterBand(i);
srcColors.push_back(poSrcBand->GetColorInterpretation());
}
if(bOK)
{
psWO->hSrcDS = m_pRasterDataset;
psWO->hDstDS = NULL;
psWO->nBandCount = GDALGetRasterCount(m_pRasterDataset);
psWO->panSrcBands = (int *) CPLMalloc(sizeof(int) * psWO->nBandCount);
psWO->panDstBands = (int *) CPLMalloc(sizeof(int) * psWO->nBandCount);
for(int i = 0; i < psWO->nBandCount; i++)
{
psWO->panSrcBands[i] = i+1;
psWO->panDstBands[i] = i+1;
}
// Use 0 for GCP regular warp and -1 for TPS warp.
int iGCPWarp = (iMethod == 1) ? 0 : -1;
psWO->pfnTransformer = GDALGenImgProjTransform;
// Use NULLs as parameters to get from pixel/line to geocoordinates
psWO->pTransformerArg = GDALCreateGenImgProjTransformer(psWO->hSrcDS,
NULL, NULL, NULL, TRUE, -1.0, iMethod);
// Figure out the desired output bounds and the geo transform.
int nPixels = 0, nLines = 0;
CPLErr eErr = GDALSuggestedWarpOutput(m_pRasterDataset, psWO-
>pfnTransformer, psWO->pTransformerArg, adfDstGeoTransform, &nPixels,
&nLines);
// Update the transformer to include the output geotransform.
GDALSetGenImgProjTransformerDstGeoTransform(psWO->pTransformerArg,
adfDstGeoTransform);
if(bOK)
{
int nBands = GDALGetRasterCount(m_pRasterDataset);
psWO->dfWarpMemoryLimit = nPixels*nLines*4*8*nBands;
psWO->nBandCount = nBands;
psWO->panSrcBands = (int *) CPLMalloc(psWO->nBandCount*sizeof(int));
psWO->panDstBands = (int *) CPLMalloc(psWO->nBandCount*sizeof(int));
for(int i = 0; i < psWO->nBandCount; i++)
{
psWO->panSrcBands[i] = i+1;
psWO->panDstBands[i] = i+1;
}
psWO->nDstAlphaBand = 0;
// Create a warped VRT dataset.
GDALDatasetH hDstDS = GDALCreateWarpedVRT(m_pRasterDataset, nPixels,
nLines, adfDstGeoTransform, psWO);
bOK = (hDstDS != NULL);
if(bOK)
{
// Write out the projection definition.
GDALSetProjection(hDstDS, pszDstWKT);
// Copy the color table, if required.
GDALColorTableH hCT = GDALGetRasterColorTable(GDALGetRasterBand
(m_pRasterDataset, 1));
if(hCT != NULL)
{
GDALSetRasterColorTable(GDALGetRasterBand(hDstDS,1), hCT);
}
// Initialize and execute the warp operation.
GDALWarpOperation *oOperation = new GDALWarpOperation;
psWO->hSrcDS = m_pRasterDataset;
psWO->hDstDS = hDstDS;
for(int i = 0; i < nBands; i++)
{
((GDALRasterBand *) GDALGetRasterBand(hDstDS,i+1))->SetAccess
(GA_Update);
}
eErr = oOperation->Initialize(psWO);
if (eErr == CE_None)
{
eErr = oOperation->ChunkAndWarpMulti(0, 0, GDALGetRasterXSize(hDstDS),
GDALGetRasterYSize(hDstDS));
}
if(eErr == CE_None)
{
// Set the colors in the dest.
GDALRasterBand *pBand = NULL;
GDALDataset *pDstDS = (GDALDataset *)hDstDS;
for(int i = 1; i <= nBands; i++)
{
pBand = pDstDS->GetRasterBand(i);
GDALColorInterp gColor = srcColors[i - 1];
pBand->SetColorInterpretation(gColor);
}
// We can overwrite the destination as the source dataset.
delete m_pRasterDataset;
m_pRasterDataset = (GDALDataset *)hDstDS;
m_pRasterDataset->SetGeoTransform(adfDstGeoTransform);
}
}
}
}
// Clean up.
GDALDestroyGenImgProjTransformer(psWO->pTransformerArg);
GDALDestroyWarpOptions(psWO);
}
}
return bOK;
}
I appreciate any guidance that can be provided!!
Thanks,
Chris Pozsgai
---------------------------------
We won't tell. Get more on shows you hate to love
(and love to hate): Yahoo! TV's Guilty Pleasures list.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osgeo.org/pipermail/gdal-dev/attachments/20070309/9281aa54/attachment.html
More information about the Gdal-dev
mailing list