将 OpenCv Mat 插入 C++ std::vector
Posted
技术标签:
【中文标题】将 OpenCv Mat 插入 C++ std::vector【英文标题】:Insert OpenCv Mat to C++ std::vector 【发布时间】:2012-07-04 16:28:59 【问题描述】:我正在将 Mat 对象推入 std::vector。
但是,当我在那之后尝试访问元素(Mat)时,它没有给我之前推送的图像,这取决于 frameOrientation。
例如,在下面的情况下,我得到的“after_push_rotated2.jpg”与“before_push_rotated3.jpg”相同,这是不应该的。
如果我将 frameOrientation 设置为所有“2s”或“4s”,“after_push_rotated1/2/3.jpg”都相同并且等于“before_push_rotated3.jpg”。
这里有什么问题?
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <iostream>
#include <vector>
using namespace cv;
using namespace std;
vector<Mat> checkOrientationAndRotate()
Mat frame1 = imread("1.jpg" );
Mat frame2 = imread("2.jpg" );
Mat frame3 = imread("3.jpg" );
vector<Mat> frameList;
vector<Mat> frameList_rotated;
frameList.push_back(frame1);
frameList.push_back(frame2);
frameList.push_back(frame3);
Mat transposedFrame;
Mat rotatedFrame;
int i=0;
for (vector<Mat>::iterator iter = frameList.begin(); iter != frameList.end(); iter++)
//Check for orientation of that frame
int frameOrientation;
if (i==0) frameOrientation = 1;
if (i==1) frameOrientation = 2;
if (i==2) frameOrientation = 4;
switch (frameOrientation)
case 1: //1 - no rotate
rotatedFrame = *iter;
break;
case 2: //2 - rotate it ACW 90 deg
transpose(*iter, transposedFrame);
flip(transposedFrame, rotatedFrame, 0);
break;
case 3: //3 - rotate it 180deg
flip(*iter, rotatedFrame, -1);
break;
case 4: //4 - rotate it CW 90 deg
transpose(*iter, transposedFrame);
flip(transposedFrame, rotatedFrame, 1);
break;
default:
break;
//Check frame before pushing into vector
if (i==0) imwrite("before_push_rotated1.jpg",rotatedFrame);
if (i==1) imwrite("before_push_rotated2.jpg",rotatedFrame);
if (i==2) imwrite("before_push_rotated3.jpg",rotatedFrame);
frameList_rotated.push_back(rotatedFrame);
//Check frame after pushing into vector.
//Depending on the frameorientation, the frames are not the frames pushed in earlier!
int n=0;
for (vector<Mat>::iterator iter = frameList_rotated.begin(); iter != frameList_rotated.end(); iter++)
Mat frame = *iter;
if (n==0) imwrite("after_push_rotated1.jpg",frame);
if (n==1) imwrite("after_push_rotated2.jpg",frame);
if (n==2) imwrite("after_push_rotated3.jpg",frame);
n++;
i++;
//for
return frameList_rotated;
void main()
vector<Mat> frameList_rotated = checkOrientationAndRotate();
【问题讨论】:
【参考方案1】:[我最近没有使用 OpenCV,所以我可能是错的,如果我是,请告诉我:)]
Mat
代表(某种)图像标题,而不是图像数据。 OpenCV 在内部维护了一种引用计数机制,以避免在不同区域复制大量图像像素数据。意思是当你说:
Mat a = b; // Only headers are copied, both a and b refer to the same image.
在上述情况下,如果您修改b
,更改也会反映在a
中。在这种情况下您需要使用的是:
Mat a = b.clone();
关于你的情况,我真的认为下面这行应该可以解决问题(如果不是,控制流可能还有其他问题,呵呵):
尝试替换:
Mat transposedFrame;
Mat rotatedFrame;
与:
//create a new image, not just the headers..
Mat transposedFrame(Size(image_width, image_height), image.type());
Mat rotatedFrame(Size(image_width, image_height), image.type());
【讨论】:
非常感谢您解释 Mat 的工作原理。我一直对它的理解是错误的!顺便说一句,我通过将“transposedFrame”和“rotatedFrame”的声明转移到“for”循环中来快速解决这个问题。 很高兴知道它有帮助,而且我对它的想法并没有随着时间的推移而消失.. :)以上是关于将 OpenCv Mat 插入 C++ std::vector的主要内容,如果未能解决你的问题,请参考以下文章
在 OpenCV 中 std::vector 而不是 cv::Mat 的 `type` 的解释是啥,我该如何更改它? (C++)
是否可以将 UTexture2D 转换为 OpenCV::Mat
opencv c++ mat to vector<keypoint>