我认为我的向量存在根本问题。功能在
之下void eventCapture()
{
vector<cv::Mat> capturedAll;
getCaptures(capturedAll, 10, 500);
int csize = capturedAll.size();
// Here gives always the last capture
// It is not related with imshow
// imwrite also saves the last capture as wrong
for (int i = 0; i < 10; i++) {
cv::imshow("Images", capturedAll[i]);
string imgname = "imgcaps" + to_string(i) + ".jpg";
cv::imwrite(imgname, capturedAll[i]);
cv::waitKey(100);
}
}
void getCaptures(vector<cv::Mat>& capStore, int count, int tdif)
{
QElapsedTimer capTimer;
capTimer.start();
for (int i = 0; i < count; i++) {
capTimer.restart();
// get_capture takes a photo from webcam
cv::Mat capMat = webCam.get_capture();
capStore.push_back(capMat);
string imgname = "localsave" + to_string(i) + ".jpg";
// Saved image here is giving correct result
cv::imwrite(imgname, capMat);
while (!capTimer.hasExpired(tdif))
qApp->processEvents();
}
}
我也试过使用迭代器,但它给出了同样错误的结果。
答案 0 :(得分:1)
我认为问题是关于cv :: Mat的指针。 改变下面部分解决了问题。 但我完全不明白。每次在循环中我都会再次初始化capMat。
cv::Mat capMat = webCam.get_capture();
capStore.push_back(capMat.clone());
答案 1 :(得分:0)
如果您在Qt工作(正如您的标签所示),完全避免这种情况的最佳方法是将图像深度复制到QImage
,以避免创建cv::Mat
的副本。这是从QImage
创建cv::Mat
的安全方法,它还会在删除最后QImage
个引用时释放内存:
cv::Mat* capture;
size_t bufferSize = capture->cols * capture->rows * capture->channels();
auto pixelFormat = toPixelFormat(capture->format);
auto outputBuffer = new uchar[bufferSize];
// This will not work for sparse mats - you have to copy row-by-row
memcpy(outputBuffer, capture->data, bufferSize);
// Have to pass stride since QImage is padding the rows for non power-of-two sizes
QImage image(outputBuffer, capture->cols, capture->rows, capture->cols * capture->channels(), pixelFormat, DeleteImageData, outputBuffer);
您需要将cv::Mat
格式转换为更正QImage::Format,例如:
QImage::Format ImageFilterPrivate::getOpenCVType(int openCvFormat) {
switch(openCvFormat) {
case CV_8UC4: return QImage::Format_ARGB32;
case CV_8UC3: return QImage::Format_RGB888;
// ... etc.
}
}
某些OpenCV格式(例如16位灰度级在Qt中没有匹配的类型)。您还需要提供一个函数,该函数将在QImage
的最后一次引用丢失后删除已分配的数据,以避免内存泄漏(可以作为lambda传递):
void DeleteImageData(void* data) {
auto buffer = static_cast<unsigned char*>(data);
delete buffer;
}