ORB-LSAM2: ComputeKeyPointsOctTree() extrae funciones: maxY = iniY + hCell + 6 ¿Por qué es +6 en lugar de +3?

Como sugiere el título, este blog habla principalmente de

En void ORBextractor::ComputeKeyPointsOctTree(vector<vector<KeyPoint>> &allKeypoints){}, ¿por qué maxY = iniY + hCell + 6 +6 en lugar de +3?

En aras de la continuidad, se presentará la función ComputeKeyPointsOctTree, consulte el blog: enlace de referencia

 (Si está familiarizado con esta función, puede pasar directamente a la segunda parte )

Uno: Introducción a la función ComputeKeyPointsOctTree

 1. ¿Qué hace esta función?

Divida cada capa de la imagen de la pirámide de la imagen en pequeños bloques y use el algoritmo FAST para extraer puntos característicos para cada bloque. Dado que la cantidad de puntos característicos extraídos debe ser mucha, necesitamos extraer la cantidad de puntos característicos que deben extraerse para cada capa de acuerdo con el constructor ORBExtrator Filtre y disperse los puntos característicos (discretice los puntos característicos y haga que los puntos característicos se distribuyan uniformemente), obtenga los puntos clave extraídos por todas las pirámides de imágenes finales y calcule la información de ángulo de estos puntos característicos .

Definimos un contenedor vectorial de dos capas para almacenar todos los puntos característicos. Tenga en cuenta que este es un vector bidimensional. La primera dimensión almacena el número de capas de la pirámide, y la segunda dimensión almacena todas las características extraídas de la imagen de la pirámide de esa capa punto.
    vector < vector<KeyPoint> > allKeypoints; 
    Luego llamamos a la función para calcular los puntos característicos de cada capa de imagen usando quadtree y asignarlos. Recuerde que queremos asignar el número de puntos de características especificados en el archivo de configuración a cada capa de la pirámide. Ya hemos descrito cómo asignar puntos de características nFeatures a nLevels en el último artículo. Sin embargo, el número solo se especifica y la distribución específica no está disponible. Claro, para decirlo claramente, en el paso anterior (enlace a continuación), acabamos de crear una pirámide para especificar cuánto se asigna cada capa de la pirámide, pero sigue siendo una pirámide vacía. pirámide con esta función!

ORB-SLAM2 ---- ORBextractor::ComputePyramid function_Courage2022's Blog-CSDN Blog

 2. Definición de variable de bucle y bucle de tres capas

 2.1 minBorderX, minBorderY, maxBorderX, maxBorderY del ciclo de nivel

         Definimos las variables de bucle de la primera capa (para cada nivel de la pirámide de la imagen) minBorderX, minBorderY, maxBorderX, maxBorderY, como se muestra en la siguiente figura:

 Por lo tanto, el límite de coordenadas de la imagen es que la imagen original se expande en valores de píxel 3. ¿Por qué expandir el valor de píxel? Ya lo dije en el artículo anterior, ¡así que no lo repetiré! 

 [Nota]: Los pequeños cuadrados negros aquí indican la imagen, y los cuadrados rojos indican que los valores de 3 píxeles se han extendido hacia afuera sobre la base de la imagen, de modo que los píxeles en el límite de la imagen también tienen la oportunidad de extraer la clave. puntos.

2.2 vToDistributeKeys, ancho, alto, nCols, nRows, wCell, hCell del bucle de nivel

 

  [Nota]: El ancho y la altura aquí son los cuadrados rojos en la imagen de arriba; nCols y nRows indican la cantidad de celdas de bloque de imagen en filas y columnas respectivamente; wCell y hCell son la cantidad de filas y columnas de píxeles ocupadas por celdas de bloque de imagen .

2.3 iniX, maxX, iniY, maxY en el recorrido de la segunda capa y la tercera capa

        Supongamos que hacemos un bucle por primera vez y las variables son como se muestra en la siguiente figura:

        Entonces, ¿por qué sumar 6? Aun así, debido a los puntos característicos de coincidencia de bordes, agregamos un caparazón de 3 píxeles fuera de la imagen para garantizar que la parte del borde pueda extraer puntos característicos. ( Aquí está la explicación en el blog de referencia. No creo que sea muy claro. La explicación aquí es el propósito de escribir este blog. Hablemos de eso a continuación )

 

3. ¿Qué hacen los tres bucles?

        La primera capa de bucle for: Calcule la variable de bucle de cada capa para el uso de las siguientes dos capas

        La segunda capa del bucle for: atraviesa cada fila, calcula las coordenadas de fila inicial y máxima, el maxY de la capa anterior y el iniY de la siguiente capa se muestran en la figura, porque hay 6.

         Además, si el iniY inicializado es mayor que el límite -3, significa que se ha excedido el límite de la imagen. ¿Por qué es -3, porque cuando usamos FAST para extraer puntos clave, para evitar la situación de que el límite no se puede extraer, necesitamos agregar un radio de 3 al exterior Shell, por eso se agrega 6. Si iniY es mayor que el límite-3, significa que el shell ha alcanzado el límite.

        Además, si la coordenada Y máxima de la cuadrícula excede las coordenadas de límite, deje que la coordenada Y máxima se convierta en las coordenadas de límite.

        Lo mismo ocurre con el recorrido de columnas.

        En el ciclo más interno, usamos un contenedor vector<cv::KeyPoint> vKeysCell para almacenar los puntos característicos extraídos de la cuadrícula actual. Llame a la función integrada de opencv para extraer puntos característicos.
 

Dos: maxY = iniY + hCell + 6 ¿Por qué es +6 en lugar de +3? 

 Mira el código primero:

// 计算进行特征点提取的图像区域尺寸
const float width = (maxBorderX - minBorderX);
const float height = (maxBorderY - minBorderY);

 Las dos líneas de código anteriores representan el cuadrado rojo mencionado anteriormente, es decir, la imagen cuyo límite de la imagen real se extiende a un límite de 3 píxeles (posteriormente se convierte en: imagen extendida). Luego parte la imagen extendida:

// 计算网格在当前层的图像有的行数和列数
const int nCols = width / W;
const int nRows = height / W;
// 计算每个图像网格所占的像素行数和列数
const int wCell = ceil(width / nCols);
const int hCell = ceil(height / nRows);

 Los siguientes dos bucles for recorren el número de bloques de imagen:

// 开始遍历图像网格,还是以行开始遍历的
for (int i = 0; i < nRows; i++)
{
    
    const float iniY = minBorderY + i * hCell;
    
    float maxY = iniY + hCell + 6;

    // 开始列的遍历
    for (int j = 0; j < nCols; j++)
    {
        ...
    }
}

explicar:

De acuerdo con este flujo de código, es fácil malinterpretarlo dividiendo la imagen extendida en pequeños bloques de imagen de 30x30, y extrayendo puntos clave de los pequeños bloques de imagen respectivamente..., pensando así, nunca he entendido el significado de + 6...     

Porque cuando FAST extrae puntos clave, para evitar la situación de que el límite no se puede extraer, se debe agregar un caparazón con un radio de 3 en el exterior, por lo que el tamaño del bloque de imagen enviado a la función FAST() es 36x36. Este es el propósito de +6, para lograr que en la función FAST() sea el bloque de imagen de cada imagen real de 30x30 el que participe en la extracción de puntos clave. 

Si escribe el código de esta manera: divida la imagen real en bloques de imagen de 30x30, expanda el límite de 3 píxeles para cada bloque de imagen y luego envíelo a la función FAST() para extraer puntos clave, no lo malinterpretará, pero será más consumir más recursos informáticos. Para eso está el +6

Ejemplo de imagen:

 

 

 

Supongo que te gusta

Origin blog.csdn.net/weixin_58045467/article/details/130881104
Recomendado
Clasificación