c++ - std::cv::Mat 的 vector

标签 c++ opencv vector

继续我的计算机视觉方面的工作,我要为 N 个相机中的一个补丁计算描述符。 问题是当我计算描述符时,OpenCV 中的函数是

descriptor.compute(image, vecKeypoints, matDescriptors);

其中 vecKeypointscv::KeyPoints 的 vector ,ma​​tDescriptors 是一个 cv::Mat ,根据 OpenCV 的文档,它会填充计算的描述符。

因为我有 N 个摄像头,我为每个摄像头计算了几个描述符,所以我为每个 N 个摄像头存储了 K 个描述符。因此我创建了一个描述符 vector (即矩阵)

std::vector<cv::Mat> descriptors;

在每次迭代中,我计算一个新的 ma​​tDescriptors 并将其推送到 vector descriptors。我看到的问题是,每个 ma​​tDescriptors 的数据存储地址对于 vector descriptors

中的每个元素都是相同的

据我所知,当我执行 vector.push_back(arg) 时,生成了 arg 的拷贝并将其存储在 vector 中,那么,为什么我有相同的地址? &(descriptors[0].data) 不应该与 &(descriptors[1].data) 不同吗?

这是代码的一般 View

std::vector<Pixel> patchPos;
std::vector<Pixel> disparityPatches;

//cv::Ptr<cv::DescriptorExtractor> descriptor = cv::DescriptorExtractor::create("ORB");
cv::ORB descriptor(0, 1.2f, 8, 0);
std::vector<cv::Mat> camsDescriptors;
std::vector<cv::Mat> refsDescriptors;

uint iPatchV = 0;
uint iPatchH = 0;

// FOR EACH BLOCK OF PATCHES (there are 'blockSize' patches in one block)
for (uint iBlock = 0; iBlock < nBlocks; iBlock++)
{
    // FOR EACH PATCH IN THE BLOCK
    for(uint iPatch = iBlock*blockSize; iPatch < (iBlock*blockSize)+blockSize; iPatch++)
    {
        // GET THE POSITION OF THE upper-left CORNER(row, col) AND
        // STORE THE COORDINATES OF THE PIXELS INSIDE THE PATCH
        for (uint pRow = (iPatch*patchStep)/camRef->getWidth(), pdRow = 0; pRow < iPatchV+patchSize; pRow++, pdRow++)
        {
            for (uint pCol = (iPatch*patchStep)%camRef->getWidth(), pdCol = 0; pCol < iPatchH+patchSize; pCol++, pdCol++)
            {
                patchPos.push_back(Pixel(pCol, pRow));
            }
        }

        // KEYPOINT TO GET THE DESCRIPTOR OF THE CURRENT PATCH IN THE REFERENCE CAMERA
        std::vector<cv::KeyPoint> refPatchKeyPoint;
        //          patchCenter*patchSize+patchCenter IS the index of the center pixel after 'linearizing' the patch
        refPatchKeyPoint.push_back(cv::KeyPoint(patchPos[patchCenter*patchSize+patchCenter].getX(),
                                                patchPos[patchCenter*patchSize+patchCenter].getY(), patchSize));

        // COMPUTE THE DESCRIPTOR OF THE PREVIOUS KEYPOINT
        cv::Mat d;
        descriptor.compute(Image(camRef->getHeight(), camRef->getWidth(), CV_8U, (uchar*)camRef->getData()),
                           refPatchKeyPoint, d);
        refsDescriptors.push_back(d); // This is OK, address X has data of 'd'

        //FOR EVERY OTHER CAMERA
        for (uint iCam = 0; iCam < nTotalCams-1; iCam++)
        {
            //FOR EVERY DISPARITY LEVEL
            for (uint iDispLvl = 0; iDispLvl < disparityLevels; iDispLvl++)
            {
                ...
                ...

                //COMPUTE THE DISPARITY FOR EACH OF THE PIXEL COORDINATES IN THE PATCH
                for (uint iPatchPos = 0; iPatchPos < patchPos.size(); iPatchPos++)
                {
                    disparityPatches.push_back(Pixel(patchPos[iPatchPos].getX()+dispNodeX, patchPos[iPatchPos].getY()+dispNodeY));
                }
            }

            // KEYPOINTS TO GET THE DESCRIPTORS OF THE 50.DISPAIRED-PATCHES IN CURRENT CAMERA
            ...
            ...
            descriptor.compute(Image(camList[iCam]->getHeight(), camList[iCam]->getWidth(), CV_8U, (uchar*)camList[iCam]->getData()),
                               camPatchKeyPoints, d);
            // First time this executes is OK, address is different from the previous 'd'
            // Second time, the address is the same as the previously pushed 'd'
            camsDescriptors.push_back(d);

            disparityPatches.clear();
            camPatchKeyPoints.clear();
        }
    }
}

最佳答案

Mat 是某种像素的智能指针,因此 Mat a=b 将具有 a 和 b 的共享像素。 push_back() 的类似情况

如果您需要“深拷贝”,请使用 Mat::clone()

关于c++ - std::cv::Mat 的 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19523700/

相关文章:

c++ - 在子字符串后插入字符串

c++ - Qt 便携工控机 : only QSharedMemory?

c - 使用 cffi-libffi 按值传递结构?

c++ - Opencv慢代码: Is something wrong?

c++ - 引用同一对象的 vector

java 对象复制,数组索引越界

c++ - 如何维护对 std::priority_queue 容器的引用?

c++ - boost::log 关闭日志文件并打开一个新的

c++ - 隐藏 C++ Gnuplot 管道控制台输出

OpenCV 3.0 与 OpenCL 2.0,各自对应不同的 OpenCL 版本