導航:首頁 > 地理科目 > C用GDAL怎麼更改圖像的地理坐標

C用GDAL怎麼更改圖像的地理坐標

發布時間:2022-05-15 00:03:59

❶ c++,gdal,GCPS為獲取地理坐標,報錯求解答!

影像投影轉換就是將一個地理坐標系統轉換到另一個坐標系統,如果在同一個橢球基準面下的轉換就是嚴密的轉換,如果在同一個橢球體不同基準面的轉換是不嚴密的,不同橢球體之間的轉換是不嚴密的,這就需要用到七參數、三參數等方法。需要兩個不同坐標系統下公共點坐標求得系數。例如北京54和WG4-84坐標下的同一點的經緯度或者是經過投影後的平面坐標也是不同的。那麼影像投影主要分為哪些步驟呢?說白了,就三個步驟,第一,坐標轉換;第二,影像的重采樣,最後就是寫入到新文件中。
首先來說第一步,坐標轉換需要轉換四個坐標,也就是四個角點。也許有人說兩個點就夠了,左下點和右上點。在此,我告訴你,這是錯誤的。投影轉換後這個四個角點組成的矩形那麼很有可能就不是矩形了,如果你取兩個點做轉換那麼後面的影像投影轉換後的范圍就不正確了。
或者再有人問,我怎麼知道影像的四個角點的坐標啊?這個很簡單,通過仿射變換系數,它就是影像的像素坐標(行列號)和地理坐標之間進行關聯的系數。一般是六個參數。在GDAL中可以通過以下這個函數來獲得,如果影像有仿射變換系數的話。如果沒有仿射變換系數但是有控制點的話也能解算出系數;如果都沒有,說明這幅影像是沒有地理參考的,那麼狠遺憾的告訴你,這個影像就不能做投影轉換。還有就是,如果你這幅影像沒有投影的話也就不能做投影轉換了,因為你根本不知道這幅影像的投影是啥。

CPLErr GDALDataset::GetGeoTransform

(

double *

padfTransform

)

其中padfTransform就存儲了這六個參數。這是個六個double型的數的數組。
在向北向的圖像中,padfTransform[1]代表像素寬度,padfTransform[5]代表像素高度。圖像左上角的坐標是(padfTransform[0],padfTransform[3]),adfGeoTransform[1] X方向也就是橫向的解析度大小,padfTransform [2] 旋轉系數,如果為0,就是標準的正北向圖像,padfTransform [4] 旋轉系數,如果為0,就是標準的正北向圖像,知道了這兩個參數的意義,那麼我們就可以得到四個角點的地理坐標了。
在正北向的圖像中,四個角點的坐標計算如下:
//計算源圖像的MBR
double dbX[4];
double dbY[4];
double dbZ[4] = {0,0,0,0};
dbX[0] = adfDstGeoTransform[0]; //左上角點坐標
dbY[0] = adfDstGeoTransform[3];

//右上角坐標
dbX[1] = adfDstGeoTransform[0] + nXsize*adfDstGeoTransform[1];
dbY[1] = adfDstGeoTransform[3];

//右下角點坐標
dbX[2] = adfDstGeoTransform[0] + nXsize*adfDstGeoTransform[1] + nYsize*adfDstGeoTransform[2];
dbY[2] = adfDstGeoTransform[3] + nXsize*adfDstGeoTransform[4] + nYsize*adfDstGeoTransform[5];

//左下角坐標
dbX[3] = adfDstGeoTransform[0];
dbY[3] = adfDstGeoTransform[3] + nYsize*adfDstGeoTransform[5];

這樣我們就找到了需要參與投影轉換的坐標點了,下一步就是坐標轉換,坐標轉換的過程通過GDAL的介面實現,其底層依賴了PROJ4地圖投影開源類庫。對於不同的橢球體之間變換需要用到三參數布爾莎或者七參數布爾莎模型,具體過程就是首先將經緯度大地坐標轉換為地心坐標系下的空間直角坐標,然後用布爾莎模型計算,最後將計算後的結果重新轉換到目標地理坐標系統下的經緯度大地坐標。有了需要轉換的坐標後,我們將對上述四個點的坐標進行變換,其函數如下:

[cpp] view plain
bool TranformCoordsOGR(char* pszSrcWkt,char* pszDestWkt, int nCount,double* x,double* y,double* z
,double *dfParaSrc,double* dfParaDst,int nParaCount)
{
//創建OGR的空間參考系
OGRSpatialReference oSrcSrs; //源坐標系統
OGRSpatialReference oDestSrs; //目的坐標系統
oSrcSrs.importFromWkt(&pszSrcWkt);
oDestSrs.importFromWkt(&pszDestWkt);

int nSameGeoCS = oSrcSrs.IsSameGeogCS(&oDestSrs);

//相同的橢球基準面,則進行轉換
if (nSameGeoCS)
{
OGRCoordinateTransformation *poCT = NULL;
poCT = ( &oSrcSrs,&oDestSrs );
if (NULL == poCT)
{
return false;
}
int nFlag = poCT->Transform(nCount,x,y,z);
if (nFlag)
{
OGRCoordinateTransformation::DestroyCT(poCT);
return true;
}

return false;
}

else //不同的橢球體基準面,要設置七參數或者三參數
{
int nFlag = 0;

//如果是地理坐標系,直接轉換為空間直角坐標
OGRErr err = 0;
double dbAsrc = 0;
double dbBsrc = 0;
double dbEsrc = 0;
dbAsrc = oSrcSrs.GetSemiMajor(&err);
dbBsrc = oSrcSrs.GetSemiMinor(&err);
dbEsrc = 1-pow((dbBsrc/dbAsrc),2.0);

if (oSrcSrs.IsProjected())
{
OGRSpatialReference* poTmpSRS = oSrcSrs.CloneGeogCS();
OGRCoordinateTransformation *poCTTmp = NULL;
poCTTmp = ( &oSrcSrs,poTmpSRS );
nFlag = poCTTmp->Transform(nCount,x,y,z);
if (!nFlag)
{
OGRCoordinateTransformation::DestroyCT(poCTTmp);
return false;
}
OGRCoordinateTransformation::DestroyCT(poCTTmp);
//pj_geodetic_to_geocentric(dbAsrc,dbEsrc,nCount,0,x,y,z);
}

//將經緯度坐標轉換為空間直角坐標
CGeoEllipse geoEllipse(dbAsrc,dbBsrc);
double dbX = 0;
double dbY = 0;
double dbZ = 0;
for (int i = 0; i < nCount; i ++)
{
geoEllipse.BLH_XYZ(x[i],y[i],z[i],dbX,dbY,dbZ);
x[i] = dbX;
y[i] = dbY;
z[i] = dbZ;
}

//七參數模型
vector<double> vecX;
vector<double> vecY;
vector<double> vecZ;
for (int i = 0; i < nCount; i ++)
{
double dbX = dfParaSrc[0] + (1+dfParaSrc[6])*(x[i]+dfParaSrc[5]*y[i]-dfParaSrc[4]*z[i]);
vecX.push_back(dbX);
double dbY = dfParaSrc[1] + (1+dfParaSrc[6])*(-dfParaSrc[5]*x[i]+y[i]+dfParaSrc[3]*z[i]);
vecY.push_back(dbY);
double dbZ = dfParaSrc[2] + (1+dfParaSrc[6])*(dfParaSrc[4]*x[i]-dfParaSrc[3]*y[i]+z[i]);
vecZ.push_back(dbZ);
}

memcpy(x,&vecX[0],sizeof(double)*nCount);
memcpy(y,&vecY[0],sizeof(double)*nCount);
memcpy(z,&vecZ[0],sizeof(double)*nCount);

double dbAdst = 0;
double dbBdst = 0;
double dbEdst = 0;
dbAdst = oDestSrs.GetSemiMajor(&err);
dbBdst = oDestSrs.GetSemiMinor(&err);

//再將空間直角坐標轉換為地理坐標,即經緯度坐標
CGeoEllipse geoEllipse1(dbAdst,dbBdst);
for (int i = 0; i < nCount; i ++)
{
geoEllipse1.XYZ_BLH(x[i],y[i],z[i],dbX,dbY,dbZ);
x[i] = dbX;
y[i] = dbY;
z[i] = dbZ;
}

if (oDestSrs.IsProjected())
{
const char* pszProjName = oDestSrs.GetAttrValue("PROJECTION");

OGRSpatialReference* poTmpSRS = oDestSrs.CloneGeogCS();
int nZone = oDestSrs.GetUTMZone();
char* pszTmp;
poTmpSRS->exportToWkt(&pszTmp);
OGRCoordinateTransformation *poCTTmp = NULL;
poCTTmp = ( poTmpSRS,&oDestSrs );
if (NULL == poCTTmp)
{
//MessageBox(NULL,_T("失敗"),_T("提示"),MB_OK);
return false;
}
nFlag = poCTTmp->Transform(nCount,x,y,z);
if (!nFlag)
{
OGRCoordinateTransformation::DestroyCT(poCTTmp);
return false;
}
OGRCoordinateTransformation::DestroyCT(poCTTmp);

return true;
}

return true;
}

return false;
}
上述代碼中有空間直角坐標和大地坐標之間的變換,這個是我自己寫的,讀者也可以使用PROJ中的介面進行變換。

第二步就是影像重采樣了,重采樣就是通過原始影像的像素值內插得到新到采樣點上的像素值。這個可以直接用GDAL中重采樣介面來完成。
第三步就不用詳細說了,一般投影轉換後需要將投影後的影像寫入的新文件中,直接用GDAL的讀寫介面來完成。

二、GDAL影像投影轉換的過程中解析度和仿射變換系數的估算
上一節已經完成了點的投影轉換,那麼我們現在就要估算投影後的像素解析度大小和仿射變換系數了。
如果投影變換前是投影坐標系統,投影轉換後也是投影坐標系統,或者說另外一種情況:投影變換前是地理坐標系統,投影變換後也是地理坐標系統,並且坐標的單位都一致的,那麼解析度大小基本上沒變換,可以用變換前的解析度大小。如果變換前是地理坐標系統,投影變換後是投影坐標系統,假設地理坐標系統以度為單位,投影坐標系統以米為單位,那麼投影後的像素大小可以這樣估計,因為經線上一個緯度的距離大約是111km,那麼變換後的解析度可以由原始解析度乘以111000;相反的話,如果變換前是投影坐標系統,投影變換後是地理坐標系統,假設地理坐標系統以度為單位,投影坐標系統以米為單位,同理投影後的像素大小可以這樣估計,變換後的解析度可以由原始解析度除以111000。
仿射變換系數這樣也就可以確定了,左上角的坐標就是最小x值,最大y值,在變換後的四個角點坐標中比較獲得,解析度上一段也講了如何獲得。對於正北向的圖像這就夠了。 然後行列數就用變換後的四個角點組成的區域的MBR的寬度除以橫向解析度得到列數,高度除以縱向解析度得到行數。

附上出處鏈接:http://blog.csdn.net/zhouxuguang236/article/details/17468171

❷ 用GDAL 讀取圖像到Dataset,然後取出一個Band ,如何把它轉換成Bitmap,便於pictureBox載入

數據 轉為 byte[] ,然後用 bitmap 的 重載方法 ,有直接讀取 byte[] 位元組 構成 bitmap

❸ GDAL怎麼用函數讀取12位的圖像信息

首先,採用GDAL讀取圖像:

GDALAllRegister();
GDALDataset*poDataset;
QStringfilename;
filename=QFileDialog::getOpenFileName(this,tr("ChooseImages"),tr("AllFles(*.*)"));
//Opentheimage
QByteArrayba=filename.toLatin1();
poDataset=(GDALDataset*)GDALOpen(ba.data(),GA_ReadOnly);

其次,成功後,可以獲取圖像的一些基本信息,如下:

  1. 描述信息:

    const char* GDALDataset::GetDriver()->GetDescription(),通常是圖像的格式;

  2. 圖像大小:

    圖像寬度:int GDALDataset::GetRasterXSize();

    圖像高度:int GDALDataset::GetRasterYSize();

  3. 波段數:int GDALDataset::GetRasterCount();

  4. 投影信息:GDALDataset::GetProjectionRef(),有的圖像沒有投影信息;

    地理坐標信息:double adfGeoTransform[6] GDALDataset::GetGeoTransform(adfGeoTransform);

  5. 波段信息:數據集中重要的信息,有波段尺寸、數據類型、顏色信息等;

  6. 獲取波段的方法:poBand為指向第i個波段的指針

    GDALRasterBand *poBand;

    poBand = poDataset->GetRasterBand(i);

  7. 波段尺寸:

    int poBand->GetXSize();

    int poBand->GetYSize();

  8. 數據類型:const char* GDALGetDataTypeName(poBand->GetRasterDataType());

  9. 顏色信息:const char* (poBand->GetColorInterpretation());

❹ c語言怎麼用gdal讀取geotiff文件

load是導入文件,一般從mat文件中imread是圖像處理工具箱的庫函數,處理圖像比較方便Load命令功能loadFilename將名為Filename的MAT文件中的所有變數載入到工作空間中loadFilenamexyz將名為Filename的MAT文件中的x、y、z等指定變數載入到工作空間中loadFilename-regexppat1pat2將名為Filename的MAT文件中符合表達式要求的變數載入到工作空間中loadFilenamexyz-ASCII將名為Filename的8位ASCII文件中的x、y、z等指定變數載入到工作空間中load是讀取matalab本身附帶的索引圖(具體路徑是C:\MATLAB2009\toolbox\wavelet\wavedemo);而imread是讀取你自己的圖片(也就是你電腦上的圖)imread該函數用於讀取圖片文件中的數據。在matlab的命令窗口中輸入docimread或者helpimread即可獲得該函數的幫助信息。matlab的imread很強大,一個命令可以讀取各種類型的圖像。但是imread並不是一個實際功能函數。不同的圖像格式有不同的編碼方式,因此有不同的讀取方式。實際上,為每種不同格式的圖像編寫各自的讀取函數是適當的,實際中也是這么做的。matlab就是這樣的,imread只是一個入口函數。它僅僅是做了一些文件名的處理,從你的文件名中,找到絕對路徑,找到圖像後綴名,然後調用合適的讀取函數。比如你打開\toolbox\matlab\imagesci\private文件夾會看到很多諸如readjpg.m,readtif.m的文件。這些才是不同格式圖片讀取的真正函數,但是!這些函數也不是實際功能函數!你打開這些m函數就可以看到裡面其實很簡單。它們所做的事情和imread差不多。也是調用了一些別的函數。比如readjpg.m里的實際讀取函數是rjpg8crjpg16c這些。你會發現這些文件也存在於上面所說的這個文件夾中,但是它們的後綴名不是.m,而是.mexw32(.mexw64for64bit),這些實際功能函數並不是用matlab編寫的,而是用C編寫的,它們是經過編譯的文件,不是文本文件。matlab只是調用他們而已。也就是說實際上matlab讀取圖像也是調用了C語言編寫的代碼。而且不同格式的圖像有不同的代碼。imread只不過是個入口函數而已。這種結構在matlab里非常非常非常常見。管中窺豹,可見一斑,看來matlab高級語言得以應用也是建立在C語言的架構之上的

❺ VS2005平台下用GDAL做圖像處理

delete poDataset; //釋放資源

cout<<"RasterXSize:"<<poDataset->GetRasterXSize()<<endl;//x方向長度
cout<<"RasterYSize:"<<poDataset->GetRasterYSize()<<endl;//y方向長度
cout<<"RasterCount:"<<poDataset->GetRasterCount()<<endl;//波段數量

指針使用問題,delete語句已經把poDataset釋放了,後面語句就是訪問野指針了

❻ GDAL/OGR的應用

利用GDAL/OGR庫,可以使基於Linux的地理空間數據管理系統提供對矢量和柵格文件數據的支持。
1 . GDAL
GDAL提供對多種柵格數據的支持,包括Arc/Info ASCII Grid(asc),GeoTiff (tiff),Erdas Imagine Images(img),ASCII DEM(dem) 等格式。1)GDAL抽象數據模型
GDAL使用抽象數據模型(abstract datamodel)來解析它所支持的數據格式,抽象數據模型包括數據集(dataset),坐標系統,仿射地理坐標轉換(Affine GeoTransform), 大地控制點(GCPs), 元數據(Metadata),柵格波段(Raster Band),顏色表(ColorTable),子數據集域(Subdatasets Domain),圖像結構域(Image_StructureDomain),XML域(XML:Domains)。

❼ 如何在CSharp中使用GDAL

問題解決方案,可以不考慮測試結果 將四個*_CSharp.dll在項目中「添加引用」添加進來,其餘gdal16.dll和另外四個編譯C#時生成的dll文件拷貝到項目的debug下。即可。 如果不把dll文件拷貝到debug下,將出現下面錯誤: 「OSGeo.OGR.Ogr」的類型初始值設定項引發異常這樣的問題。 這個問題是dll不全造成的,除了要引用的4個dll外,還有5個dll也要放到Debug目錄下。 在編譯C#下的gdal時,總共生成了9個dll,在編譯的本機上,程序是通過環境變數path找到另外的幾個dll的。 在沒有編譯過gdal的電腦上,反正就把這9個編譯後的dll放到debug下面就一切Ok了

❽ 使用gdal庫讀取圖像

谷歌了一下,就找到這個還好點,希望能幫到你。

http://wenku..com/view/f419727d27284b73f2425035.html

❾ 關於C++中使用頭文件gdal_priv.h

你沒有導入lib庫,所有造成函數有定義而連接不上,將你的lib庫文件加入到工程文件中,或者在原代碼中加入 #pragma comment(lib,"你的lib庫路徑和文件名"). 然後進行編譯連接。

❿ 關於UTM投影坐標與地理經緯度轉換的問題

UTM是平面坐標, 轉成經緯度是地理坐標

閱讀全文

與C用GDAL怎麼更改圖像的地理坐標相關的資料

熱點內容
word中化學式的數字怎麼打出來 瀏覽:747
乙酸乙酯化學式怎麼算 瀏覽:1411
沈陽初中的數學是什麼版本的 瀏覽:1364
華為手機家人共享如何查看地理位置 瀏覽:1054
一氧化碳還原氧化鋁化學方程式怎麼配平 瀏覽:894
數學c什麼意思是什麼意思是什麼 瀏覽:1423
中考初中地理如何補 瀏覽:1312
360瀏覽器歷史在哪裡下載迅雷下載 瀏覽:712
數學奧數卡怎麼辦 瀏覽:1402
如何回答地理是什麼 瀏覽:1037
win7如何刪除電腦文件瀏覽歷史 瀏覽:1063
大學物理實驗干什麼用的到 瀏覽:1494
二年級上冊數學框框怎麼填 瀏覽:1713
西安瑞禧生物科技有限公司怎麼樣 瀏覽:1008
武大的分析化學怎麼樣 瀏覽:1256
ige電化學發光偏高怎麼辦 瀏覽:1345
學而思初中英語和語文怎麼樣 瀏覽:1669
下列哪個水飛薊素化學結構 瀏覽:1431
化學理學哪些專業好 瀏覽:1493
數學中的棱的意思是什麼 瀏覽:1072