FC2カウンター FPGAの部屋 カーブ、直線用白線間走行用畳み込みニューラルネットワーク5(トレーニング用データの生成)
fc2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

カーブ、直線用白線間走行用畳み込みニューラルネットワーク5(トレーニング用データの生成)

カーブ、直線用白線間走行用畳み込みニューラルネットワーク4(学習画像を増やす)”の続き。

前回は、 41 + 18 + 18 = 71 枚の学習画像をコントラストを変えたり、ぼかしたり、ガンマ値を変えたり、ノイズを加えたりして、1,386 枚に増やした。今回はその学習画像をMNISTのデータ形式に変換する。

MNIST手書き数字のデータフォーマットは、”MNIST手書き数字のデータフォーマット”の記事の中で解析している。
白線追従走行用畳み込みニューラルネットワークの製作3(トレーニング、ラベル・ファイルの作成)”で直線走行用のトレーニング用データを作成したので、それを参照して、カーブ、直線用白線走行用のトレーニング用画像・ファイルとトレーニング用ラベル・ファイルを作成していこう。

トレーニング・ファイルとラベル・ファイルを作成するプラットフォームも使い慣れたVivado HLS を使用していこう。
Vivado HLS 2017.3 で curve_dataset_bmp3 プロジェクトを作成した。
curve_tracing_cnn_25_171215.png

curve_dataset_bmp.h を貼っておく。

// curve_dataset_bmp.h
// 2017/11/29 by marsee
//

#ifndef __CURVE_DATASET_BMP_H__
#define __CURVE_DATASET_BMP_H__

#include "hls_video.h"

#define BMP_HEIGHT    600
#define BMP_WIDTH    800

#define REDUCTION_RATIO    0.075    // 1/13.3333... 60x45

#define DATASET_HEIGHT    10
#define DATASET_WIDTH    56

#define STRAIGHT_BMP_FILE_NAME        straight
#define LEFT_TURN_BMP_FILE_NAME        left_turn
#define RIGHT_TURN_BMP_FILE_NAME    right_turn
#define STRAIGHT_NUM_OF_IMAGE        738
#define LEFT_TURN_NUM_OF_IMAGE        324
#define    RIGHT_TURN_NUM_OF_IMAGE        324

typedef hls::Scalar<3unsigned char> RGB_PIXEL;
typedef hls::Mat<BMP_HEIGHT, BMP_WIDTH, HLS_8UC3> RGB_IMAGE;
typedef hls::Mat<BMP_HEIGHT, BMP_WIDTH, HLS_8UC1> GRAY_IMAGE;

#endif


次に、curve_dataset_bmp_nowr.cpp を貼っておく。

// curve_dataset_bmp_nowr.cpp
// 2017/11/29 by marsee
//

#include <iostream>
#include "hls_opencv.h"
#include "curve_dataset_bmp.h"
#include <arpa/inet.h>

const char IMAGE_DIR[] = "train_data_171129";

int main(){
    char straight_fn[256] = "straight";
    char left_turn_fn[256] = "left_turn";
    char right_turn_fn[256] = "right_turn";
    char bmp_file[256];
    FILE *ftin, *ftln;
    char train_image_name[256] = "train_curve_run_image";
    char train_label_name[256] = "train_curve_run_label";
    uint32_t buf[5];
    uint8_t bufchar[100];


    if ((ftin = fopen(train_image_name, "wb")) == NULL){
        fprintf(stderr, "Can't open %s\n", train_image_name);
        exit(1);
    }
    if ((ftln = fopen(train_label_name, "wb")) == NULL){
        fprintf(stderr, "Can't open %s\n", train_label_name);
        exit(1);
    }

    // Writed header
    buf[0] = htonl(0x803); // magic number
    buf[1] = htonl((STRAIGHT_NUM_OF_IMAGE+LEFT_TURN_NUM_OF_IMAGE+RIGHT_TURN_NUM_OF_IMAGE)*25); // number of image
    buf[2] = htonl(10); // number of rows (10)
    buf[3] = htonl(56); // number of columns (56)
    fwrite(buf, sizeof(uint32_t), 4, ftin);

    buf[0] = htonl(0x801); // magic number
    buf[1] = htonl((STRAIGHT_NUM_OF_IMAGE+LEFT_TURN_NUM_OF_IMAGE+RIGHT_TURN_NUM_OF_IMAGE)*25); // number of image
    fwrite(buf, sizeof(uint32_t), 2, ftln);

    // refereed to http://opencv.jp/cookbook/opencv_img.html
    // straight
    for(int i=0; i<STRAIGHT_NUM_OF_IMAGE; i++){
        sprintf(bmp_file, "%s/%s%d.bmp", IMAGE_DIR, straight_fn, i);
        cv::Mat straight_img = cv::imread(bmp_file,1);
        if(straight_img.empty()){
            fprintf(stderr,"Error: %s\n", bmp_file);
            return(-1);
        }
        cv::Mat reduct_img(straight_img.rows*0.075, straight_img.cols*0.075, straight_img.type());
        cv::resize(straight_img, reduct_img, reduct_img.size(), cv::INTER_LINEAR);
        cv::Mat gray_img;
        cv::cvtColor(reduct_img, gray_img, CV_BGR2GRAY);

        //sprintf(bmp_file, "%s_RED%d.bmp", straight_fn, i);
        //cv::imwrite(bmp_file, gray_img);

        for(int y=0; y<5; y++){
            for(int x=0; x<5; x++){
                cv::Rect rect_center(x, 30+y, 5610);
                cv::Mat img_rect(gray_img, rect_center);
                //sprintf(bmp_file, "%s_RED_rect%d_%d%d.bmp", straight_fn, i, y, x);
                //cv::imwrite(bmp_file, img_rect);

                for(int iy=0; iy<img_rect.rows; iy++){
                    for(int ix=0; ix<img_rect.cols; ix++){
                        bufchar[ix] = img_rect.at<uchar>(iy, ix);
                    }
                    fwrite(bufchar, sizeof(uint8_t), img_rect.cols, ftin); // image write
                }
                bufchar[0] = 0x1;
                fwrite(bufchar, sizeof(uint8_t), 1, ftln); // label write
            }
        }
    }

    // left turn
    for(int i=0; i<LEFT_TURN_NUM_OF_IMAGE; i++){
        sprintf(bmp_file, "%s/%s%d.bmp", IMAGE_DIR, left_turn_fn, i);
        cv::Mat left_turn_img = cv::imread(bmp_file,1);
        if(left_turn_img.empty()){
            fprintf(stderr,"Error: %s\n", bmp_file);
            return(-1);
        }
        cv::Mat reduct_img(left_turn_img.rows*0.075, left_turn_img.cols*0.075, left_turn_img.type());
        cv::resize(left_turn_img, reduct_img, reduct_img.size(), cv::INTER_LINEAR);
        cv::Mat gray_img;
        cv::cvtColor(reduct_img, gray_img, CV_BGR2GRAY);

        //sprintf(bmp_file, "%s_RED%d.bmp", left_turn_fn, i);
        //cv::imwrite(bmp_file, gray_img);

        for(int y=0; y<5; y++){
            for(int x=0; x<5; x++){
                cv::Rect rect_center(x, 30+y, 5610);
                cv::Mat img_rect(gray_img, rect_center);
                //sprintf(bmp_file, "%s_RED_rect%d_%d%d.bmp", left_turn_fn, i, y, x);
                //cv::imwrite(bmp_file, img_rect);

                for(int iy=0; iy<img_rect.rows; iy++){
                    for(int ix=0; ix<img_rect.cols; ix++){
                        bufchar[ix] = img_rect.at<uchar>(iy, ix);
                    }
                    fwrite(bufchar, sizeof(uint8_t), img_rect.cols, ftin); // image write
                }
                bufchar[0] = 0x0;
                fwrite(bufchar, sizeof(uint8_t), 1, ftln); // label write
            }
        }
    }

    // right turn
    for(int i=0; i<RIGHT_TURN_NUM_OF_IMAGE; i++){
        sprintf(bmp_file, "%s/%s%d.bmp", IMAGE_DIR, right_turn_fn, i);
        cv::Mat right_turn_img = cv::imread(bmp_file,1);
        if(right_turn_img.empty()){
            fprintf(stderr,"Error: %s\n", bmp_file);
            return(-1);
        }
        cv::Mat reduct_img(right_turn_img.rows*0.075, right_turn_img.cols*0.075, right_turn_img.type());
        cv::resize(right_turn_img, reduct_img, reduct_img.size(), cv::INTER_LINEAR);
        cv::Mat gray_img;
        cv::cvtColor(reduct_img, gray_img, CV_BGR2GRAY);

        //sprintf(bmp_file, "%s_RED%d.bmp", right_turn_fn, i);
        //cv::imwrite(bmp_file, gray_img);

        for(int y=0; y<5; y++){
            for(int x=0; x<5; x++){
                cv::Rect rect_center(x, 30+y, 5610);
                cv::Mat img_rect(gray_img, rect_center);
                //sprintf(bmp_file, "%s_RED_rect%d_%d%d.bmp", right_turn_fn, i, y, x);
                //cv::imwrite(bmp_file, img_rect);

                for(int iy=0; iy<img_rect.rows; iy++){
                    for(int ix=0; ix<img_rect.cols; ix++){
                        bufchar[ix] = img_rect.at<uchar>(iy, ix);
                    }
                    fwrite(bufchar, sizeof(uint8_t), img_rect.cols, ftin); // image write
                }
                bufchar[0] = 0x2;
                fwrite(bufchar, sizeof(uint8_t), 1, ftln); // label write
            }
        }
    }

    fclose(ftin);
    fclose(ftln);

    return(0);
}


curve_dataset_bmp_nowr.cpp では数が増えすぎてしまうので、学習画像をBMPファイルにしていないが、画像を出力した curve_dataset_bmp2 で出力した学習画像の一部を示す。
まずは、左旋回の学習画像を示す。
curve_tracing_cnn_26_171215.png

右旋回の画像を示す。
curve_tracing_cnn_27_171215.png

直進の画像を示す。
curve_tracing_cnn_28_171215.png

C シミュレーションを行ったところ、train_curve_run_image と train_curve_run_label ができた。
curve_tracing_cnn_29_171215.png

curve_tracing_cnn_30_171215.png

train_curve_run_image をバイナリ・エディタで見た。
curve_tracing_cnn_31_171215.png

最初の 0x0000 0803 が画像ファイルのマジック・ナンバーだ。その次の 0x0000 875a は16進数なので、10進数に直すと34,650 となって学習画像の数を表す。0x0000 000a は10 進数にすると 10 で、画像の縦のピクセル数を表す。次の 0000 0038 は、10進数に直すと 56 で画像の横のピクセル数を表す。

train_curve_run_label を示す。
curve_tracing_cnn_32_171215.png

最初の 0x0000 0801 はラベル・ファイルのマジック・ナンバーだ。その次の 0x0000 875a は16進数なので、10進数に直すと 34,650 となってトレーニング・ラベルの数を表す。

これで、トレーニング用画像・ファイルとトレーニング用ラベル・ファイルを作成することができた。
  1. 2017年12月15日 05:04 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/4004-2571812d
この記事にトラックバックする(FC2ブログユーザー)