opencv讀取mnist數據集

1.源碼實現

#include <iostream>
#include <string>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

//小端存儲轉換
unsigned int reverseInt(unsigned int i)
{
    unsigned char c1, c2, c3, c4;

    c1 = i & 0xff;
    c2 = (i >> 8) & 0xff;
    c3 = (i >> 16) & 0xff;
    c4 = (i >> 24) & 0xff;

    return ((unsigned int)c1 << 24) + ((unsigned int)c2 << 16) + ((unsigned int)c3 << 8) + c4;
}

Mat read_mnist_image(const string fileName)
{
    unsigned int magic_number = 0;
    unsigned int number_of_images = 0;
    unsigned int n_rows = 0;
    unsigned int n_cols = 0;
    Mat DataMat;

    ifstream file(fileName, ios::binary);
    if(file.is_open())
    {
        cout << "成功打開圖像集..." << endl;

        file.read((char *)&magic_number, sizeof(magic_number));         //幻數(文件格式)
        file.read((char *)&number_of_images, sizeof(number_of_images));     //圖片總數
        file.read((char *)&n_rows, sizeof(n_rows));             //每個圖像的行數
        file.read((char *)&n_cols, sizeof(n_cols));             //每個圖像的列數

        magic_number = reverseInt(magic_number);
        number_of_images = reverseInt(number_of_images);
        n_rows = reverseInt(n_rows);
        n_cols = reverseInt(n_cols);

        cout << "幻數(文件格式): " << magic_number << endl;
        cout << "圖片總數: " << number_of_images << endl;
        cout << "每個圖像的行數: " << n_rows << endl;
        cout << "每個圖像的列數: " << n_cols << endl;

        cout << "開始讀取Image數據..." << endl;

        DataMat = Mat::zeros(number_of_images, n_rows*n_cols, CV_32FC1);

        for(int i=0; i<number_of_images; i++)
        {
            for(int j=0; j<n_rows*n_cols; j++)
            {
                unsigned char temp = 0;

                file.read((char *)&temp, sizeof(temp));

                float pixel = float(temp);

                DataMat.at<float>(i, j) = pixel;
            }
        }

        cout << "讀取Image數據完畢..." << endl;
    }

    file.close();

    return DataMat;
}

Mat read_mnist_label(const string fileName)
{
    unsigned int magic_number = 0;
    unsigned int number_of_items = 0;
    Mat LabelMat;

    ifstream file(fileName, ios::binary);
    if(file.is_open())
    {
        cout << "成功打開標籤集..." << endl;

        file.read((char *)&magic_number, sizeof(magic_number));         //幻數(文件格式)
        file.read((char *)&number_of_items, sizeof(number_of_items));       //標籤總數

        magic_number = reverseInt(magic_number);
        number_of_items = reverseInt(number_of_items);

        cout << "幻數(文件格式): " << magic_number << endl;
        cout << "標籤總數: " << number_of_items << endl;

        cout << "開始讀取Label數據..." << endl;

        LabelMat = Mat::zeros(number_of_items, 1, CV_32SC1);

        for(int i=0; i<number_of_items; i++)
        {
            unsigned char temp = 0;

            file.read((char *)&temp, sizeof(temp));

            LabelMat.at<unsigned int>(i, 0) = (unsigned int)temp;
        }

        cout << "讀取Label數據完畢..." << endl;
    }

    file.close();

    return LabelMat;
}

int main()
{
    string train_images_path = "./train-images-idx3-ubyte";
    string train_labels_path = "./train-labels-idx1-ubyte";

    //讀取標籤數據集
    Mat train_labels = read_mnist_label(train_labels_path);

    //讀取圖像數據集
    Mat train_images = read_mnist_image(train_images_path);

    //打印第二個標籤
    Mat label1 = train_labels.rowRange(1, 2);
    cout << "第二個標籤: " << label1 << endl;

    //取第二張圖片
    Mat img1 = train_images.rowRange(1, 2);

    //改變形狀爲(28, 28)
    img1 = img1.reshape(1, 28);

    //保存圖片
    imwrite("mnist_train_1.jpg", img1);

    return 0;
}

2.編譯源碼

$ g++ -o test test.cpp -std=c++11 -I/usr/local/include -L/usr/local/lib -lopencv_core -lopencv_highgui -lopencv_imgproc -Wl,-rpath=/usr/local/lib

3.運行程序

$ ./test
成功打開標籤集...
幻數(文件格式): 2049
標籤總數: 60000
開始讀取Label數據...
讀取Label數據完畢...
成功打開圖像集...
幻數(文件格式): 2051
圖片總數: 60000
每個圖像的行數: 28
每個圖像的列數: 28
開始讀取Image數據...
讀取Image數據完畢...
第二個標籤: [0]

4.結果展示

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章