Algorithme de correspondance stéréo

Principe SGM (Semi-Global Matching) :

Les principes de SGM sont expliqués plus en détail sur l'encyclopédie wiki et sur le site officiel de matlab :
wiki matlab
Si vous voulez bien comprendre les principes, il est recommandé de lire l' article original (je ne le lirai pas, je suis paresseux.) Une github
interprétation papier et une implémentation de code de haute qualité introduit d'abord deux paramètres importants : Remarque : Cette partie fait référence à l'explication de matlab, et la partie suivante fait référence à l'implémentation d'opencv. peuvent être légèrement différents, mais ils sont généralement cohérents. Niveaux de disparité et nombre de directions



Niveaux de disparité

Niveaux de disparité : les niveaux de disparité sont un paramètre utilisé pour définir l'espace de recherche pour la correspondance. Comme le montre la figure ci-dessous, l'algorithme recherche chaque pixel de l'image de gauche parmi les D pixels de l'image de droite. Les valeurs D générées sont des niveaux de disparité D pour un pixel dans l'image de gauche. Les premières colonnes D de l'image de gauche ne sont pas utilisées car les pixels correspondants de l'image de droite ne sont pas disponibles pour la comparaison. Sur la figure, w représente la largeur de l'image et h la hauteur de l'image. Pour une résolution d'image donnée, l'augmentation du niveau de disparité réduit la distance minimale pour détecter la profondeur. L'augmentation du niveau de disparité augmente également la charge de calcul de l'algorithme. À un niveau de disparité donné, l’augmentation de la résolution de l’image augmente la distance minimale pour détecter la profondeur. L'augmentation de la résolution de l'image augmente également la précision de l'estimation de la profondeur. Le nombre de niveaux de disparité est proportionnel à la résolution de l'image d'entrée pour la détection d'objets à la même profondeur. Cet exemple prend en charge les niveaux de disparité de 8 à 128 (les deux valeurs incluses). L'explication de l'algorithme fait référence à 64 niveaux de disparité. Les modèles fournis dans cet exemple peuvent accepter des images d'entrée de n'importe quelle résolution.——matlab

Il y a trop de mots à comprendre, j'ai donc demandé à gpt de m'expliquer :

# gpt生成,仅供本人理解SSD原理
import numpy as np

def compute_disparity(left_img, right_img, block_size=5, num_disparities=64):
    # 图像尺寸
    height, width = left_img.shape

    # 初始化视差图
    disparity_map = np.zeros_like(left_img)

    # 遍历每个像素
    for y in range(height):
        for x in range(width):
            # 定义搜索范围
            min_x = max(0, x - num_disparities // 2)
            max_x = min(width, x + num_disparities // 2)

            # 提取左图像块
            left_block = left_img[y:y+block_size, x:x+block_size]

            # 初始化最小 SSD 和对应的视差
            min_ssd = float('inf')
            best_disparity = 0

            # 在搜索范围内寻找最佳视差
            for d in range(min_x, max_x):
                # 提取右图像块
                right_block = right_img[y:y+block_size, d:d+block_size]

                # 计算 SSD
                ssd = np.sum((left_block - right_block)**2)

                # 更新最小 SSD 和对应的视差
                if ssd < min_ssd:
                    min_ssd = ssd
                    best_disparity = abs(x - d)

            # 将最佳视差保存到视差图中
            disparity_map[y, x] = best_disparity

    return disparity_map

# 示例用法
left_img = np.random.randint(0, 255, size=(100, 100), dtype=np.uint8)
right_img = np.roll(left_img, shift=5, axis=1)  # 创建右图,右移了5个像素

disparity_map = compute_disparity(left_img, right_img, block_size=5, num_disparities=64)

# 可视化结果(这里简化为将视差图缩放以便可视化)
import matplotlib.pyplot as plt
plt.imshow(disparity_map, cmap='gray')
plt.title('Disparity Map')
plt.show()

Cela montre clairement que les niveaux de disparité constituent la plage de calcul de la disparité (plage de recherche de disparité).

Nombre de directions

Nombre de directions :

Nombre de directions : Dans l'algorithme SGBM, pour optimiser la fonction de coût, l'image d'entrée est considérée depuis plusieurs directions. En général, la précision du résultat de disparité s'améliore avec l'augmentation du nombre de directions. Cet exemple analyse cinq directions : de gauche à droite (A1), de haut gauche à bas droit (A2), de haut en bas (A3), de haut à droite en bas à gauche (A4), et de droite à gauche (A5).
Insérer la description de l'image ici

La correspondance des pixels selon un chemin unique n'est pas assez robuste et la complexité temporelle de la correspondance globale pour un optimal bidimensionnel selon les images est trop élevée (problème NP-complet), c'est pourquoi l'auteur de SGM utilise l'agrégation de chemins unidimensionnels pour approximer l’optimum bidimensionnel.
Insérer la description de l'image ici
référence de la photo

SAD et SSD

Utilisez SAD ou SSD pour calculer la similarité des images afin de les faire correspondre.
Formule :
> Voici la citation
bien que la formule et le code soient générés par gpt, la formule semble correcte. Le code peut aider à la compréhension et est uniquement à titre de référence.
Les num_disparities dans le code sont des niveaux de disparité

SGBM en opencv

J'utilise beaucoup opencv, donc ici je me concentre uniquement sur l'implémentation du code dans opencv .

Exemple opencv StereoSGBM_create :

# gpt生成,仅作为参考,具体请查看opencv官方文档https://docs.opencv.org/4.x/d2/d85/classcv_1_1StereoSGBM.html
import cv2
import numpy as np

# 读取左右视图
left_image = cv2.imread('left_image.png', cv2.IMREAD_GRAYSCALE)
right_image = cv2.imread('right_image.png', cv2.IMREAD_GRAYSCALE)

# 创建SGBM对象
sgbm = cv2.StereoSGBM_create(
    minDisparity=0,
    numDisparities=16,  # 视差范围,一般为16的整数倍
    blockSize=5,        # 匹配块的大小,一般为奇数
    P1=8 * 3 * 5 ** 2,   # SGBM算法参数
    P2=32 * 3 * 5 ** 2,  # SGBM算法参数
    disp12MaxDiff=1,    # 左右视差图的最大差异
    uniquenessRatio=10,  # 匹配唯一性百分比
    speckleWindowSize=100,  # 过滤小连通区域的窗口大小
    speckleRange=32      # 连通区域内的差异阈值
)

# 计算视差图
disparity_map = sgbm.compute(left_image, right_image)

# 将视差图进行归一化处理
disparity_map = cv2.normalize(disparity_map, None, 0, 255, cv2.NORM_MINMAX)

# 显示左图、右图和视差图
cv2.imshow('Left Image', left_image)
cv2.imshow('Right Image', right_image)
cv2.imshow('Disparity Map', disparity_map.astype(np.uint8))

cv2.waitKey(0)
cv2.destroyAllWindows()

Différence entre SGBM et SGM

quelle est la différence entre opencv sgbm et sgm
opencv官方的解释:
La classe implémente l'algorithme modifié de H. Hirschmuller [82] qui diffère de l'original comme suit :

  1. Par défaut, l'algorithme est en un seul passage, ce qui signifie que vous ne considérez que 5 directions au lieu de 8. Définissez mode=StereoSGBM::MODE_HH dans createStereoSGBM pour exécuter la variante complète de l'algorithme, mais attention, il peut consommer beaucoup de mémoire.
  2. L'algorithme fait correspondre les blocs et non les pixels individuels. Cependant, définir blockSize=1 réduit les blocs à des pixels simples.
  3. La fonction de coût de l’information mutuelle n’est pas mise en œuvre. Au lieu de cela, une métrique de sous-pixel Birchfield-Tomasi plus simple de [15] est utilisée. Cependant, les images couleur sont également prises en charge.
    Certaines étapes de pré- et post-traitement de l'algorithme StereoBM de K. Konolige sont incluses, par exemple : pré-filtrage (type StereoBM::PREFILTER_XSOBEL) et post-filtrage (vérification d'unicité, interpolation quadratique et filtrage des taches).

La signification générale est que la différence avec SGM est que la plus petite unité lors de la correspondance avec l'algorithme SGBM est constituée de blocs, pas de pixels, mais lorsque blockSize=1 est défini, elle devient SGM. Les informations mutuelles ne sont pas implémentées, mais la métrique de sous-pixel Birchfield-Tomasi plus simple est utilisée. De plus, il existe certaines opérations de pré- et post-traitement.
Insérer la description de l'image ici
C'est probablement ça, je ne sais pas si c'est vrai.

Algorithme de correspondance stéréo profonde

Faites d'abord un trou

Je suppose que tu aimes

Origine blog.csdn.net/onlyyoujojo/article/details/135244558
conseillé
Classement