Opencv 图像配准与聚焦叠加

Opencv 图像配准与聚焦叠加,opencv,throughput,Opencv,Throughput,背景: 我正在寻找使用智能手机为焦点堆叠应用程序对齐图像。图像链接: 堆栈中的第一个:,堆栈中的最后一个:,最终堆栈图像: 即,图像名义上相同,但包含: 当焦平面在图像之间移动时焦点的系统性变化 放大率略有变化(焦点变化时智能手机的功能!) 相机由于随机振动而轻微移动 图像需要对齐,焦点堆叠应用程序才能工作 迄今为止的进展情况: 我使用OpenCV的findTransformeC()来获得对齐。经过一些实验后,它工作得很好,例如,看看哪一个对改进扭曲矩阵的初始化有用: 在像素级对齐的图像 处理8

背景: 我正在寻找使用智能手机为焦点堆叠应用程序对齐图像。图像链接:

堆栈中的第一个:,堆栈中的最后一个:,最终堆栈图像:

即,图像名义上相同,但包含:

  • 当焦平面在图像之间移动时焦点的系统性变化
  • 放大率略有变化(焦点变化时智能手机的功能!)
  • 相机由于随机振动而轻微移动
  • 图像需要对齐,焦点堆叠应用程序才能工作

    迄今为止的进展情况: 我使用OpenCV的findTransformeC()来获得对齐。经过一些实验后,它工作得很好,例如,看看哪一个对改进扭曲矩阵的初始化有用:

  • 在像素级对齐的图像
  • 处理8Mpix图像需要60秒(0.5Mpix图像需要1秒)(在使用OpenCV发行库的3年便携式PC上)
  • 请参见上面的堆叠图像链接

    我简要地研究了一个特征检测器(SIFT)。它没有很好地对齐图像,可能是由于图像之间的焦点变化

    代码:

     int scale = 1;
     int scaleSmall = 4;
     float scaleDiff = scaleSmall / scale;
    
         for (i = 0; i< numImages; i++) {
            file = dir + image + to_string(i) + ".jpg";
            col[i] = imread(file);
    
            resize(col[i], z[i], Size(col[i].cols/scale, col[i].rows/scale));       
            cvtColor(z[i], zg[i], CV_BGR2GRAY);
            resize(zg[i], zgSmall[i],  Size(col[i].cols / scaleSmall, col[i].rows / scaleSmall));
         }
    
        // Set a 2x3 or 3x3 warp matrix depending on the motion model.
        // See https://www.learnopencv.com/image-alignment-ecc-in-opencv-c-python/
        // Define the motion model
        const int warp_mode = MOTION_HOMOGRAPHY;
    
        // Initialize the matrix to identity
        if (warp_mode == MOTION_HOMOGRAPHY) {
            warp_init = Mat::eye(3, 3, CV_32F);
            warp_matrix = Mat::eye(3, 3, CV_32F);
            warp_matrix_prev = Mat::eye(3, 3, CV_32F);
            scaleTX = (Mat_<float>(3, 3) << 1, 1, scaleDiff, 1, 1, scaleDiff, 1 / scaleDiff, 1 / scaleDiff, 1);
        }
        else {
            warp_init = Mat::eye(2, 3, CV_32F);
            scaleTX = Mat::eye(2, 3, CV_32F);
            warp_matrix = Mat::eye(2, 3, CV_32F);
            warp_matrix_prev = Mat::eye(2, 3, CV_32F);
            scaleTX = (Mat_<float>(2, 3) << 1, 1, scaleDiff, 1, 1, scaleDiff);
        }
    
        // Specify the number of iterations.
        int number_of_iterations = 5000;
    
        // Specify the threshold of the increment
        // in the correlation coefficient between two iterations
        double termination_eps = 1e-8;
    
        // Define termination criteria
        TermCriteria criteria(TermCriteria::COUNT + TermCriteria::EPS, number_of_iterations, termination_eps);
    
        for (i = 1; i < numImages; i++) {
            // Check images right size
            if (zg[0].rows < 10 || zg[1].rows < 10)
                return;
    
            // Run the ECC algorithm at start to get an initial guess. The results are stored in warp_matrix.
            if (i == 1) {
                findTransformECC(zgSmall[0], zgSmall[i], warp_init, warp_mode, criteria     );
    
                // See https://stackoverflow.com/questions/45997891/cv2-motion-euclidean-for-the-warp-mode-in-ecc-image-alignment-method
                warp_matrix = warp_init * scaleTX;
            }
    
            // Warp Matrix from previous iteration is used as initialisation  
            findTransformECC(zg[0], zg[i], warp_matrix, warp_mode,  criteria);
    
            if (warp_mode != MOTION_HOMOGRAPHY) {
                warpAffine(zg[i], ag[i], warp_matrix, zg[i].size(), INTER_LINEAR + WARP_INVERSE_MAP);
                warpAffine(z[i], acol[i], warp_matrix, zg[i].size(), INTER_LINEAR + WARP_INVERSE_MAP);
            }
            else {
                // Use warpPerspective for Homography
                warpPerspective(z[i], acol[i], warp_matrix, z[i].size(), INTER_LINEAR + WARP_INVERSE_MAP);
                warpPerspective(zg[i], ag[i], warp_matrix, zg[i].size(), INTER_LINEAR + WARP_INVERSE_MAP);
               }
            }
        }
    
    int-scale=1;
    int scaleSmall=4;
    float scaleDiff=缩放缩放缩放/缩放;
    对于(i=0;iscaleTX=(Mat_u3,3)至少可以做3个改进:

  • 5000次迭代可能是不必要的。尝试将其限制为500次。此外,将图像转换到渐变域可能会有所帮助。请参阅此函数中的
    GetGradient
    函数

  • 您可以假设透视效果可以忽略不计,因此可以将
    扭曲_模式
    更改为
    运动_仿射
    ,以将自由度限制在8到6之间

  • 您还可以尝试另一种更快的方法,即基于相位相关(频域)的方法。按照标准方法,它仅估计图像之间的平移,但您可以将图像传输到对数极坐标空间以获得平移、旋转和缩放不变性。这实现了第三种方法


  • 您可以发布示例图像吗?您使用什么设置来对齐图像?也请发布代码。请参阅图像链接和插入的代码相位相关方法非常快,但我正在努力获得足够的精度。有什么想法吗?是否适合将图像与失焦和稍微失准的等效图像进行比较?