在 OpenCV 中创建二维矩阵数组?

Posted

技术标签:

【中文标题】在 OpenCV 中创建二维矩阵数组?【英文标题】:Creating a 2D array of matrices in OpenCV? 【发布时间】:2018-04-12 21:20:37 【问题描述】:

我正在尝试从头开始实施 SIFT 算法。现在,我正在尝试生成比例空间,其中包含多个比例减小的模糊图像。我的直觉是使用数组,因为我知道我需要的维度并且它们不会改变。在 2D 数组中,每个元素都是表示模糊图像的矩阵。每列将代表一个八度。但是,无论是 OpenCV(2.4 版)还是 g++ 似乎都不明白我想要什么。我正在使用头文件和实现文件,但是,SIFT 算法不适合对象(IMO),所以我避免使用它们。 这是我的头文件代码:

#include <opencv2/opencv.hpp>

void generateOctaves(cv::Mat img); // Function to generate octaves.
void approxLoG(cv::Mat passOctave[4][5]);    // Function to approximate Laplacian of Gaussian

下面是对应实现文件的代码:

#include <iostream>
#include <cmath>
#include <opencv2/opencv.hpp>
#include "scaleSpace.h"

// Generate four octaves with five images each.
using namespace std;
using namespace cv;
void generateOcatves(Mat img)       // Determine Octaves

    Mat octaves[4][5];  // Creates 4x5 array/grid to hold 4 octaves, each comprised of 5 images.
    Mat resizedImg; // Holds resized image.
    resize(img, resizedImg, Size(), 2, 2, CV_INTER_CUBIC);      // Double image size to allow for more keypoints
    Mat originalResize = resizedImg;     // Temp matrix to hold the original resized image prior to blurring.
    double sigma = 1.6;     // General value for sigma
    double k = sqrt(2);     // Gneral value for k
    for(int i=0; i < 4; i++)
    
        if(i > 0)       // Shrink image on all iterations other than the first.
        
            resize(originalResize, resizedImg, Size(), 0.5, 0.5, CV_INTER_AREA);
            // Reset altered values.
            originalResize = resizedImg;
            sigma = 1.6;
        
        for(int j=0; j < 5; j++)
        
            octaves[i][j] = resizedImg;
            GaussianBlur(resizedImg, resizedImg, Size(0,0), sigma, sigma, 0);   // Perform Gaussian Blur on the image.
            sigma = sigma * k;
            imshow("Octave", resizedImg);
        
        cout << "Press Enter to continue." << endl;
        while (true)
        
            char cont=(char)waitKey(25);
            if(cont == 27)
            
                destroyAllWindows();
                break;
            
        
        approxLoG(octaves[4][5]);
    


void approxLoG(Mat passOctave[4][5])

    // Compute the DoG of consecutive scales. Computing the DoG gives an approximation of the LoG in less time. 
    // Since the LoG would have to be computed for multiple images, the DoG is used.
    Mat array_DoG[4][4];    // 4x4 array to hold four octaves and 4 DoG images. There is one less DoG created than images in each octave for each octave.
    for(int i=0; i < 4; i++)
    
        for(int j=0; j < 4; j++)
        
            Mat DoG = passOctave[i][j] - passOctave[i][j+1];        // Compute DoG
            imshow("Difference of Gaussian", DoG);
            array_DoG[i][j] = DoG;
        
        char cont=(char)waitKey(25);
        if(cont == 27)
        
            destroyAllWindows();
        
    

我得到的编译错误是:

g++ -g -c scaleSpace.cpp `pkg-config --cflags --libs opencv2`
scaleSpace.cpp: In function ‘void generateOcatves(cv::Mat)’:
scaleSpace.cpp:50:26: error: cannot convert ‘cv::Mat’ to ‘cv::Mat (*)[5]’ for argument ‘1’ to ‘void approxLoG(cv::Mat (*)[5])’
approxLoG(octaves[4][5]);

让我特别困惑的是,可以使用 OpenCV 创建一维矩阵数组,如 here 所示。 我可能可以使用二维向量而不是数组。但是,即便如此,为什么二维数组不起作用,而一维数组却可以呢?

【问题讨论】:

【参考方案1】:

您的线路:

approxLoG(octaves[4][5]);

octaves[4][5] 就像其他每个 octaves[i][j] 正在访问单个元素一样。这个越界了。

要传递数组,只需编写:

approxLoG(octaves);

【讨论】:

我仍然对八度音阶越界感到困惑。八度音阶的每个元素不是矩阵吗?我查看了我的 for 循环逻辑,它似乎在我的适当范围内。你能详细说明一下吗? @SaulKapruac 记住索引在 0 到 size-1 之间,大小是禁止的。 0, 1, 2, 3 用于i,0, 1, 2, 3, 4 用于joctaves[i=4][j=5] 等更高的值超出范围。 是的,但我的条件是 i 和 j 分别小于 4 和 5。因此,当达到这些数字并且不再满足小于条件时,for 循环将停止迭代。 @SaulKapruac 我说的是你的电话:approxLoG(octaves[4][5]);。你的 for 循环很好。

以上是关于在 OpenCV 中创建二维矩阵数组?的主要内容,如果未能解决你的问题,请参考以下文章

从巨大的二维结构数组中创建结构的子数组

C代码和python代码:用二维数组实现矩阵的转置

在opencv中创建4x4 mat矩阵时出错

R中的多维稀疏数组(3路张量)

OpenCV 简单的二维矩阵乘法失败

使用 4 循环的二维矩阵上的数组下标的无效类型“int [int]”