Algunos problemas comunes con GDAL

1 Cuando se utilizan puntos de control terrestre para la corrección geométrica, aparece una excepción no controlada en 0x00007FFF2CBAEBB4 (gdal302.dll) (en SURFMatch.exe): 0xC0000005: se produjo una infracción de acceso al leer la posición 0xFFFFFFFFFFFFFFFF.

Problema: No se puede corregir
Motivo: Busqué la causa y descubrí que se debía a que no se configuró la ID del punto de control terrestre. Después de configurar la ID, se ejecutó normalmente.

gcplist[i].pszId = id;

2 Aparece el ERROR 1 al ejecutar gdal en c++: PROJ: proj_create_from_database: no se puede encontrar proj.db

La idea es:
si no puede encontrar este archivo, deje que lo encuentre. Hay 3 formas:
1. Agregar variables de entorno y luego reiniciar la computadora ;
2. Especificar la ruta en el código;
3. Ponerlo debajo del exe. ;
a veces se necesitan estos 3 métodos. Ambos métodos están configurados.

Después de consultar algunos documentos, descubrí que hay dos soluciones principales:
este problema se resolvió exitosamente con el segundo método:
uno es agregar variables de entorno ;
el otro es configurar la ruta a proj.db directamente en el código.

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

La versión C++ GDAL3.5 no puede encontrar el blog-CSDN de proj.db file_c++ db file_Linlp93

Solución al problema de No se puede encontrar proj.db cuando se ejecuta GDAL_Blog-CSDN de Akuya Motata (Zhang Xuepeng)

3 Cuando se usa gdal y omp de c++ para leer datos, se informa un error ERROR 1: GetBlockRef falló en el efecto del bloque X 0, efecto del bloque Y 12210. Fallo de segmentación (núcleo volcado). Estos son dos errores diferentes.

GetBlockRef falló en el bloque X de 0, el bloque Y de 12210. Es un error al leer datos de gdal.
Fallo de segmentación (núcleo volcado). Es un error de falta de memoria.

1. Posibles razones:
ejecuté el código normalmente en Windows y luego lo ejecuté en Linux y se informó este error.
No hay más que las siguientes 4 razones:
(1) conflicto de recursos omp; lo ejecuto normalmente en Windows y básicamente elimino este error.
(2) Los datos leídos son incorrectos; para verificar, desactivé la aceleración de omp y descubrí que se estaba ejecutando normalmente y que los datos se podían leer normalmente, lo que indica que debe ser la causa de omp.
(3) Razones para confiar en las bibliotecas; antes tenía un código omp que podía ejecutarse normalmente, pero esta vez no se puede ejecutar y este error no se ha eliminado.
(4) El motivo de los recursos de memoria insuficientes; mi omp descubrió que se estaban ejecutando muchos subprocesos al mismo tiempo, por lo que agregué export OMP_NUM_THREADS=4 en el script de shell. El descubrimiento no funcionó. Luego agregué las siguientes palabras al código y descubrí que el programa se ejecutó normalmente, el número de subprocesos está limitado a 4 en lugar de muchos, por lo que el programa ocupa menos memoria:

#include <omp.h>

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

2. Motivo:
los recursos de memoria insuficientes causan este problema.

3. Solución 1: limite la cantidad de subprocesos omp en el programa
. Agregue el código anterior al programa y el programa se ejecutará normalmente.

#include <omp.h>

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

Solución 2: borrar la memoria del sistema
Utilice el siguiente comando para borrar el caché del sistema y proporcionar más memoria:

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

4 Fallo de segmentación (núcleo volcado) Memoria insuficiente

La falla de segmentación (núcleo volcado) se debe principalmente a un funcionamiento incorrecto de la memoria. Operaciones de lectura y escritura de punteros nulos y punteros salvajes, acceso fuera de límites a matrices, destrucción de constantes, etc. Inicializar cada puntero a NULL después de la declaración es una buena forma de evitar este problema.

Una solución rápida es verificar la memoria del sistema, free -h, y ver cuánta memoria G queda en el campo libre.

Si no hay memoria suficiente, debe borrarla:

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

5 4 errores reportados al mismo tiempo: GetBlockRef falló en el efecto del bloque X 0, efecto del bloque 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 Pregunta:
Cuando se usa GDAL para leer datos, este error ocurre cuando omp está habilitado. El hilo habilitado para omp es 1 y no se informa ningún error. El hilo habilitado para omp es 2 y se informa un error dos veces, a veces este error no se informa. Pero cuando omp habilitó que los subprocesos fueran 8, este error se informó más de 1000 veces.

Cuanto mayor sea el número de subprocesos, más veces se informará el error anterior, que puede exceder varios miles de veces como máximo. Es decir, no se pueden obtener los datos.

2 razones:
Exclusión:
(1) Razones para excluir el tamaño de la imagen: mss.tif y dom.tif informarán errores. mss.tif informará un error si el tamaño es 1000 1000 y dom.tif informará un error si es 3000 3000, pero dom.tif informará un error. Se informan más errores. Si el tamaño de dom.tif se establece en 1400*1400, también se informará el error anterior.
(2) Excluir problemas de datos. Los datos son correctos porque el acceso de un solo subproceso es normal.

La razón encontrada:

hay un conflicto en el acceso de gdal a los recursos. Los subprocesos múltiples de gdal entrarán en conflicto al leer bloques de imágenes en la misma ubicación, es decir, al leer un determinado píxel, solo un subproceso puede leer.

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

3 Solución:
varios subprocesos que utilizan gdal para leer bloques de datos de detección remota al mismo tiempo pueden causar conflictos y resultados incorrectos. Para evitar esto, podemos utilizar la directiva crítica de OpenMP para proteger el acceso a recursos compartidos.
Utilice #pragma omp critic {} para ajustar el código para leer píxeles. Tenga en cuenta que {} debe comenzar en una nueva línea y no puede estar en la misma línea que #pragma omp critic.

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 No se puede encontrar la biblioteca .dll

Solución:
coloque la biblioteca de vínculos dinámicos .dll donde se puede encontrar el archivo ejecutable .exe
Insertar descripción de la imagen aquí

6 No se puede localizar el punto de entrada del programa

No se puede ubicar el nombre de origen de la columna solid3 del punto de entrada del programa en la biblioteca de vínculos dinámicos D: XiaoMaCode\CPlusPlusCode Biblioteca de terceros GDAL322\bingdal302dll
Insertar descripción de la imagen aquí

2.2 Razones

Lo más probable es que se deba a que no se puede utilizar la biblioteca .dll o que el ajuste de la biblioteca sea confuso.

2.3 Solución

Empecé a poner la biblioteca .dll en las variables del sistema, pero algo salió mal.
Coloque el archivo .dll en el mismo directorio que el exe y podrá ejecutarse normalmente.

Supongo que te gusta

Origin blog.csdn.net/xiaotiig/article/details/129703348
Recomendado
Clasificación