vector<Mat> opencv 问题

Posted

技术标签:

【中文标题】vector<Mat> opencv 问题【英文标题】:vector<Mat> opencv issues 【发布时间】:2015-05-23 23:33:54 【问题描述】:

我正在尝试将 19x19 大小的图像读入矢量。我有 2429 张这样的图像。但是当我运行我的代码时,我确信一些 Mat 图像没有读入向量中。是不是内存问题。如果是,任何人都可以帮助我。在我的代码中有断言语句后,我确认了这一点。谢谢你的帮助。 编辑: 我删除了所有 if else 语句并用格式说明符替换它。当我构建设计矩阵 X_train 时,恰好在 ex = 1703 我的断言失败。我检查了围绕这些 ex 值设置的图像,它们看起来不错。我无法理解我哪里出错了。

#include <iostream>
#include <vector>
#include <istream>
#include <fstream>
#include <random>
#include <algorithm>

#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#define NO_OF_IMAGES 2429

using namespace std;
using namespace cv;
static int colSize = 0;

vector<Mat> read_faces() 
    vector<Mat> training_images;
    string images_path = "images/train/face";
    string suffix = ".pgm";
    Mat img(19, 19, CV_8UC1);
    for (int i = 0; i < NO_OF_IMAGES; i++) 
        img = imread( cv::format("%s%05d.pgm", images_path.c_str(), i), 0 );
        training_images.push_back(img);
    
    return training_images;


vector<Mat> extract_train_test_set(
    vector<Mat> faces/**< [in] vector of faces or matrices*/,
    vector<Mat> &test_set /**< [out] 10% of images*/) 

    /**
     * Randomly select 90% of these images and collect them into a set training_set and
     * the rest 10% in test_set.
     */

    int percentage_train = (0.9f * NO_OF_IMAGES);
    vector<Mat> training_set;

    for (int i = 0; i < percentage_train; i++) 
        Mat img = faces[i];
        assert(img.empty() == false);
        training_set.push_back(img);
    

    for (int i = percentage_train; i < NO_OF_IMAGES; i++) 
        Mat img = faces[i];
        assert(img.empty() == false);
        test_set.push_back(img);
    

    return training_set;


int main(int argc, char **argv) 

    vector<Mat> faces = read_faces(); /**< Reading faces into a vector of matrices. */

    random_shuffle(faces.begin(), faces.end()); /**< Shuffle the faces vector for creating a training set*/
    cout << faces.size() << endl; /**< Size of the vector of faces is 2429*/

    vector<Mat> training_set; /**< 90% images i.e 2186 are test images. */
    vector<Mat> test_set; /**< 10% images i.e 243 are test images. */

    training_set = extract_train_test_set(faces, test_set);

    cout << " Training set size " << training_set.size() << endl;
    cout << " Test set size " << test_set.size() << endl;

    int dim = training_set[0].rows * training_set[0].cols; /**< 361 dimension vector. */

    Mat X_train(dim, training_set.size(), CV_8UC1); /**< 361 rows and 2186 columns.*/

    Mat m(19, 19, CV_8UC1);
    int ex = 0; /**< Counter for indexing the images */

    while (ex < training_set.size()) 
        m = training_set[ex];/**< Retrieve the image from training vector. */
        for (int i = 0; i < 19; i++) 
            for (int j = 0; j < 19; j++) 
                assert(m.empty() == false);
                X_train.at<uchar>(colSize, ex) = m.at<uchar>(i, j); //each image is a 361 element vector
                colSize++;
            
        
        ex++; /**< Continue to next image. */
        colSize = 0; /**< Set to zero so as to continue to next image. That is a reset row index for next image.*/
    

    ofstream file_handle("images/train.dat", ios::trunc);

    file_handle << X_train;

    file_handle.close();

    cout << "Height " << X_train.rows << " Width " << X_train.cols << endl;

    waitKey(0);

    return 0;

【问题讨论】:

你的 if/elseif 东西太可怕了......也许你错过了一些案例 您遇到了什么问题? 使用重塑docs.opencv.org/modules/core/doc/… 使用:imread( cv::format("%s%05d.pgm", images_path.c_str(), i) );,放弃所有那些可怕的 if 子句,然后再试一次。 各位,给您带来的不便,我深表歉意。 @berak 我听取了您的建议并合并了更改。谢谢你。不幸的是,当我运行我的代码时,我的断言在 ex = 1703 再次失败。感谢您提及格式说明符。 【参考方案1】:

我让它工作了。我没有循环遍历我手动设置 19 行和 19 列(假设每个图像为 19x19)的图像,而是使用了 Mat 的类成员“行”和“列”。我找到的解决方案只是替换为以下内容:

while (ex < training_set.size()) 
    m = training_set[ex];/**< Retrieve the image from training vector. */
    cout << "Fine!! " << ex << endl;
    assert(m.empty() == false);
    for (int i = 0; i < m.rows; i++) 
        for (int j = 0; j < m.cols; j++) 
            X_train.at<uchar>(colSize, ex) = m.at<uchar>(i, j); //each image is a 361 element vector
            colSize++;
        
    
    ex++; /**< Continue to next image. */
    colSize = 0; /**< Set to zero so as to continue to next image. That is a reset row index for next image.*/

【讨论】:

以上是关于vector<Mat> opencv 问题的主要内容,如果未能解决你的问题,请参考以下文章

在vector<Mat> Opencv中加载许多图像

将 Vector<float> 中的数据复制到 Vector<Mat> (Opencv/C++)

vector<Mat> opencv 问题

OpenCV2.4.2将vector<Point2f>转换为Mat,释放mat会报错

阅读 vector<Mat> 或 Video ? (Opencv 和 C++)

c ++如何将视频序列放入OpenCV中的vector<Mat>?