GDAL に関する一般的な問題

1 幾何学補正に地上制御点を使用すると、0x00007FFF2CBAEBB4 (gdal302.dll) (SURFMatch.exe 内) で未処理の例外がポップアップ表示されます: 0xC0000005: 位置 0xFFFFFFFFFFFFFFFF の読み取り中にアクセス違反が発生しました。

問題点:修正できない
原因:原因を調べたところ、地上基準点のIDが設定されていないことが原因で、IDを設定したところ正常に動作しました。

gcplist[i].pszId = id;

2 C++ で gdal を実行するとエラー 1 が表示されます: PROJ: proj_create_from_database: proj.db が見つかりません

アイデアは次のとおりです:
このファイルが見つからない場合は、ファイルを見つけさせてください。方法は 3 つあります:
1. 環境変数を追加してコンピュータを再起動する;
2. コード内でパスを指定する;
3. ファイルを exe の下に置く;
場合によってはこれら 3 つのメソッドが必要になる場合があります の両方のメソッドが設定されます。

いくつかのドキュメントを参照した結果、主な解決策が 2 つあることがわかりました:
この問題は 2 番目の方法で正常に解決されました:
1 つは環境変数を追加する方法、
もう 1 つはコード内で proj.db へのパスを直接構成する方法です。

std::string path = "C:\\Program Files\\PROJ\\share\\proj";//proj.db所在文件夹
const char* proj_path[] = {
    
    path.c_str(), nullptr};
OSRSetPROJSearchPaths(proj_path);

C++ バージョン GDAL3.5 で proj.db ファイルが見つかりません_c++ db ファイル_Linlp93 のブログ - CSDN ブログ

GDAL 実行時に proj.db が見つからない問題の解決策_Akuya Motata (Zhang Xuepeng) のブログ - CSDN ブログ

3 C++ の gdal および omp を使用してデータを読み取ると、エラー ERROR 1 が報告されます: GetBlockRef が X ブロック 0 の影響、Y ブロック 12210 で失敗しました。セグメンテーション違反 (コアダンプ)。これらは 2 つの異なるエラーです。

GetBlockRef は、X ブロック オフ 0、Y ブロック オフ 12210 で失敗しました。gdalのデータ読み込みエラーです。
セグメンテーション違反 (コアダンプ)。メモリ不足エラーです

1. 考えられる理由:
コードを Windows で通常どおり実行し、その後 Linux で実行したところ、このエラーが報告されました。
理由は次の 4 つだけです:
(1) omp リソースの競合; Windows 上で通常どおり実行すると、このエラーは基本的に解消されます。
(2)読み込んだデータが間違っているので、確認するためにompアクセラレーションをオフにしてみたところ、正常に動作し、データも正常に読み込めたので、ompが原因であることが分かりました。
(3) ライブラリに依存する理由; 以前は正常に実行できた omp コードが今回は実行できず、このエラーは解消されていません。
(4) メモリリソースが不足している理由; omp では多数のスレッドが同時に実行されていることが判明したため、シェルスクリプトに export OMP_NUM_THREADS=4 を追加しました。ディスカバリーは機能しませんでした。その後、コードに次の単語を追加したところ、プログラムが正常に実行されたことがわかりました。スレッドの数は多くではなく 4 つに制限されているため、プログラムが使用するメモリが少なくなります。

#include <omp.h>

int main() {
    
    
    omp_set_num_threads(4);
    // 并行读取的代码
    // ...
    return 0;
}

2. 理由:
この問題は、メモリ リソースが不足していることが原因で発生します。

3.解決策 1:プログラム内の omp スレッドの数を制限する
. 上記のコードをプログラムに追加すると、プログラムは正常に実行されます。

#include <omp.h>

int main() {
    
    
    omp_set_num_threads(4);
    // 并行读取的代码
    // ...
    return 0;
}

解決策 2:システム メモリをクリアする
: 次のコマンドを使用して、システム内のキャッシュをクリアし、メモリを追加します。

sudo sync && sudo echo 3 > /proc/sys/vm/drop_caches

4 セグメンテーション違反 (コアダンプ) メモリ不足

セグメンテーション違反 (コア ダンプ) は、主に不適切なメモリ操作によって発生します。null ポインタとワイルド ポインタの読み取りおよび書き込み操作、配列の範囲外アクセス、定数の破棄など。この問題を回避するには、宣言後に各ポインタを NULL に初期化するのが良い方法です。

簡単な解決策は、システム メモリをチェックし、free -h して、空きフィールドに何 G メモリが残っているかを確認することです。

メモリが不足している場合は、メモリをクリアする必要があります。

sudo sync && sudo echo 3 > /proc/sys/vm/drop_caches

5 4 つのエラーが同時に報告されました: GetBlockRef は、X ブロックの影響 0、Y ブロックの影響 4373 で失敗しました。

ERROR1: GF2-035009809.tif,band 2: IReadBlock failed at X offset 0, Y offset 4373,
ERROR1:GetBlockRef failed at X block offect 0, Y block offect 4373,
ERROR1:TIFFFillStrip:Read error at scanline 2; get 0 bytes, expected 18438,
ERROR1:RIFFReadEncodedStrip() failed.

1 質問:
GDAL を使用してデータを読み取るとき、omp が有効になっているとこのエラーが発生します。omp が有効なスレッドは 1 で、エラーは報告されません。omp が有効なスレッドは 2 で、エラーが 2 回報告されますが、このエラーが報告されない場合もあります。しかし、omp でスレッドを 8 にできるようにすると、このエラーが 1,000 回以上報告されました。

スレッドの数が増えると、上記のエラーが報告される回数も多くなり、最大で数千回を超える場合があります。つまりデータが取得できません。

2 つの理由:
除外:
(1) 画像サイズを除外する理由: mss.tif と dom.tif はエラーを報告します。mss.tif はサイズが 1000 1000 の場合にエラーを報告し、dom.tif はサイズが 1000 1000 の場合にエラーを報告します。 3000 3000 ですが、dom.tif はエラーを報告します。さらに多くのエラーが報告されます。dom.tif のサイズが 1400*1400 に設定されている場合も、上記のエラーが報告されます。
(2) データの問題を除外する シングルスレッドアクセスは正常であるため、データは正しいです。

判明した理由:

gdal のリソースへのアクセスに競合があります。同じ位置にある画像ブロックを読み取るときに、gdal のマルチスレッドが競合します。つまり、特定のピクセルを読み取るとき、1 つのスレッドだけが読み取ることができます。

这些错误可能是由于并行处理导致的内存访问冲突或资源竞争引起的。当您增加线程数时,多个线程可能会同时访问相同的内存位置或资源,导致读取错误或失败。
为了解决这个问题,您可以尝试以下几点:
确保在并行处理期间,每个线程都在不同的内存位置上进行操作,以避免冲突。可以使用OpenMP的private和shared指令来控制变量的私有和共享访问。
尝试减少并行处理的线程数,以降低资源竞争的可能性。您可以逐步减少线程数,直到不再出现错误。
检查代码中是否存在其他可能导致冲突的部分。例如,如果有其他共享资源或全局变量,可能需要使用互斥锁或其他同步机制来保护它们。
确保您的代码在并行处理期间正确释放和管理内存,以避免内存泄漏或访问已释放内存的错误。
如果可能的话,尝试使用调试工具来跟踪错误发生的位置,并查看是否有任何明显的冲突或错误。
请注意,并行处理可能会增加代码的复杂性和调试难度。因此,在使用并行处理时,确保您的代码正确地处理并发访问和资源管理非常重要。

3 解決策:
gdal を使用してリモート センシング データ ブロックを同時に読み取る複数のスレッドにより、競合が発生し、不正確な結果が発生する可能性があります。これを回避するには、OpenMP の重要なディレクティブを使用して、共有リソースへのアクセスを保護します。
#pragma ompcritical {} を使用して、ピクセルを読み取るコードをラップします。{} は新しい行で開始する必要があり、#pragma ompcritical と同じ行に置くことはできないことに注意してください。

std::vector<cv::Mat> imgMat;     // 每个波段
int size = xpixel * ypixel;      // 这里必须是int
float* pafScan = new float[abs(size)];   // 存储数据,这句读取大影像直接报错了
if (pafScan == NULL) {
    
    
	std::cerr << "pafScan Failed to allocate memory." << std::endl;
	cv::Mat img_null;
	return img_null;
}
#pragma omp critical 
{
    
    
	for (int i = 0; i < band_number; i++) {
    
    
	int band = bands[i];
	GDALRasterBand* pBand = poDataset->GetRasterBand(band);
	// 读取栅格数据,并将其存储在pafScan中
	pBand->RasterIO(GF_Read, left, top, xpixel, ypixel, pafScan,
		xpixel, ypixel, St.iDataType, 0, 0);
	// 这里创建的时候是行数、列数
	cv::Mat tmpMat = cv::Mat(ypixel, xpixel, MdataType, pafScan);
	imgMat.push_back(tmpMat.clone());  // n个波段放到imgMat数组中去
	tmpMat.release();
	}
}

//释放内存
delete[]pafScan;
pafScan = NULL;
cv::Mat img;
img.create(St.Ysize, St.Xsize, MdataTypes);
// 将多通道数组转换为图像数组
cv::merge(imgMat, img);

5 .dll ライブラリが見つかりません

解決策:
実行可能ファイル .exe が存在する場所に .dll ダイナミック リンク ライブラリを配置します。
ここに画像の説明を挿入します

6 プログラム入力ポイントが見つかりません

ダイナミック リンク ライブラリ D: XiaoMaCode\CPlusPlusCode サード パーティ ライブラリ GDAL322\bingdal302dll でプログラム入力ポイント Solid3 列起点名が見つかりません
ここに画像の説明を挿入します

2.2 理由

原因としては、.dll ライブラリが使用できないか、ライブラリの調整がわかりにくいことが考えられます。

2.3 解決策

.dll ライブラリをシステム変数に追加し始めましたが、問題が発生しました。
.dll ファイルを exe と同じディレクトリに配置すると、通常どおり実行できます。

おすすめ

転載: blog.csdn.net/xiaotiig/article/details/129703348