当前位置:网站首页>Mosaïque d'images basée sur la matrice de transformation

Mosaïque d'images basée sur la matrice de transformation

2022-06-12 03:23:00 Le blog de Joon Joon Joon

Mosaïque d'images selon la matrice de transformation

Description:Lors d'une combinaison de plusieurs caméras,La position de la caméra est relativement fixe.En général, lors de la mosaïque d'images,Besoin de trouver des points caractéristiques entre deux paires d'images,Calculer la matrice de transformation,Encore une fois, la mosaïque d'images.Dans la recherche de points caractéristiques et la génération de matrices de transformation,Plus de calculs seront consommés,Cause slow Speed.Pour les combinaisons fixes de caméras,Sa matrice de transformation peut être calculée une fois,Lisez ensuite directement le contenu de la matrice.

Un.、Obtenir la matrice de transformation

Coller le Code directementmain.py

from stitcher import stitcher
import cv2
import time
# Lire l'image de l'épissage

t0 = time.time()
imageA = cv2.imread("left_01.png")
imageB = cv2.imread("right_01.png")

# Assembler les images en Panorama
stitcher = stitcher()
(result, vis) = stitcher.stitch([imageA, imageB], showMatches=True)
print('Use time is : ',time.time()-t0)

# Afficher toutes les images
cv2.imshow("Image A", imageA)
cv2.imshow("Image B", imageB)
cv2.imwrite('vis.jpg',vis)
cv2.imshow("Keypoint Matches", vis)
cv2.imwrite('result.jpg',result)
cv2.imshow("Result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

stitcher.pyCode

import numpy as np
import cv2


class stitcher:

    def stitch(self, images, ratio=0.75, reprojThresh=4.0, showMatches=False):
        (imageA, imageB) = images

        #  Trouver des points caractéristiques 
        (kpsA, npkpsA, feasA) = self.find_kps_feas(imageA)
        (kpsB, npkpsB, feasB) = self.find_kps_feas(imageB)

        M = self.matchKeypoints(npkpsA, npkpsB, feasA, feasB, ratio, reprojThresh)
        (good, H, status) = M
        np.savetxt("data.txt", H)
        result = cv2.warpPerspective(imageB, H, (imageA.shape[1] + imageB.shape[1], imageB.shape[0]))
        #self.cv_show('result1', result)
        result[0:imageA.shape[0], 0:imageA.shape[1]] = imageA
        #self.cv_show('result2', result)

        img = cv2.drawMatchesKnn(imageB, kpsB, imageA, kpsA, good, None, flags=2)
        #self.cv_show('result', img)

        return result, img

    def find_kps_feas(self, image):
        # ÉtablissementSIFTGénérateur
        descriptor = cv2.xfeatures2d.SIFT_create()
        # DétectionSIFTPoints caractéristiques
        (kps, features) = descriptor.detectAndCompute(image, None)

        # Convertir les résultats enNumPyTableau
        npkps = np.float32([kp.pt for kp in kps])

        # Renvoie l'ensemble de points caractéristiques,Et les caractéristiques descriptives correspondantes
        return (kps, npkps, features)

    def matchKeypoints(self, kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh):
        bf = cv2.BFMatcher()
        allMatches = bf.knnMatch(featuresB, featuresA, k=2)
        matches = []
        good = []
        for m, n in allMatches:
            if m.distance < ratio * n.distance:
                matches.append((m.trainIdx, m.queryIdx))
                good.append([m])

        if len(matches) > 4:
            ptsA = np.float32([kpsA[i] for (i, _) in matches])
            ptsB = np.float32([kpsB[i] for (_, i) in matches])

            (H, status) = cv2.findHomography(ptsB, ptsA, cv2.RANSAC, reprojThresh)

        return (good, H, status)

    def cv_show(self, name, img):
        cv2.imshow(name, img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

Dans le code ci - dessus, Enregistrer principalement la matrice des caractéristiques sous data.txt. Faciliter la lecture ultérieure des données .Testé, Le code ci - dessus prend environ 70ms.

2.、 Lecture directe de la matrice de conversion pour la mosaïque d'images

1.pythonVersion
Les codes sont les suivants::

import cv2
import time
import numpy as np
# Lire l'image de l'épissage

t0 = time.time()
imageA = cv2.imread("left_01.png")
imageB = cv2.imread("right_01.png")


A = np.zeros((3, 3), dtype=float)

f = open('/home/cj/work/python/proc_image/concatimg/2/data.txt')  #  Ouvrir le fichier de données 
lines = f.readlines()  #  Lire tous les fichiers de données dans une liste linesMoyenne
A_row = 0  # Ligne représentant la matrice,De0Ça commence
for line in lines:  # Prends ça.lines Les données sont lues ligne par ligne 
    list = line.strip('\n').split(' ')  #  Traitement des données ligne par ligne :strip Ça veut dire mettre la tête et la queue '\n'Enlevez,split Indique que les données de ligne sont divisées en espaces , Les données de ligne traitées sont ensuite retournées à listDans la Liste
    A[A_row:] = list[0:3]  #  Mettre les données traitées dans une matrice carrée AMoyenne.list[0:4] Représentant la liste 0,1,2,3 Les données de colonne sont placées dans la matrice ADansA_rowD'accord
    A_row += 1  #  Et la matrice A La ligne suivante de 

result = cv2.warpPerspective(imageB, A, (imageA.shape[1] + imageB.shape[1], imageB.shape[0]))
result[0:imageA.shape[0], 0:imageA.shape[1]] = imageA
print("Use calculated matrix operation me is : ",time.time()-t0)
cv2.imwrite('myresult.jpg',result)

Lecture directe de la matrice pour la mosaïque d'images ,Ça va prendre du temps11ms, C'est beaucoup plus rapide !
2.C++Version
Les codes sont les suivants:

#include <iostream>
#include <opencv2/opencv.hpp>

#include <stdio.h>
#include<time.h>

using namespace cv;

using namespace std;

int main()
{
    
    clock_t start_time,stop_time;// Début de l'augmentation du temps 
    start_time = clock();
    // Lire la matrice de transformation 
    float A[3][3];
    //Mat A;
    FILE* fpread;
        fpread = fopen("/home/cj/work/code/C++/concatimg/2/untitled/data.txt", "r");
        if (fpread == NULL)
        {
    
            printf("file is error.");
            return -1;
        }
        for (int i = 0; i < 3; i++)
        {
    
            for (int j = 0; j < 3; j++)
            {
    
                fscanf(fpread, "%e", &A[i][j]);
            }
        }
        fclose(fpread);
        for (int i = 0; i < 3; i++)
            {
    
                for (int j = 0; j < 3; j++)
                {
    
                    printf("%e\t",A[i][j]);
                }
                printf("\n");
             }


    Mat imageA=imread("/home/cj/work/code/C++/concatimg/2/untitled/left_01.png");
    Mat imageB=imread("/home/cj/work/code/C++/concatimg/2/untitled/right_01.png");
    int W_imageA = imageA.cols;
    int H_imageA = imageA.rows;
    int W_imageB = imageB.cols;
    int H_imageB = imageB.rows;
    int new_w = W_imageA+W_imageB;

    imshow("img",imageA);
    Mat H(3,3,CV_32FC1,A);//Convertir enMatMatrice
    cout<<"H is :"<<H;


    //dst = cv::warpPerspective(imageB, A, dsize[, dst[, flags[, borderMode[, borderValue]]]])
    Mat dst;
    //cv::warpPerspective(imageB,dst,H,imageB.size());
    cv::warpPerspective(imageB,dst,H,cv::Size(new_w,H_imageB));//Transformation en perspective
    cout<<"Size of imageB is :\n"<<imageB.size();
    cv::imwrite("dst.jpg",dst);

    cv::Rect roi_rect = cv::Rect(0, 0, imageA.cols, imageA.rows);

    imageA.copyTo(dst(roi_rect));
    stop_time = clock();
    printf("Use Time : %f s\n",(double)(stop_time-start_time)/CLOCKS_PER_SEC);
    cv::imwrite("dst_result.jpg",dst);


    waitKey(2000);

    destroyAllWindows();
}

C++ L'affichage du terminal d'exécution est :
Insérer la description de l'image ici
Effets
Insérer la description de l'image ici

原网站

版权声明
本文为[Le blog de Joon Joon Joon]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/163/202206120322114784.html