FC2カウンター FPGAの部屋 2017年08月01日

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

FPGAの部屋

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

MNIST手書き数字のデータフォーマット

MNIST手書き数字のデータフォーマットを解析してみた。MNIST手書き数字のデータフォーマットに、今回、白線追従走行用のデータフォーマットを合わせた方が都合が良いのでやってみた。

日本語で参照したのは、”MNIST 手書き数字データを画像ファイルに変換する”。ここには、画像ファイルのフォーマットしか掲載されていなかったため、ラベルファイルのフォーマットも併せて、”MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges”を参照した。

MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges”から画像ファイルとラベルファイルのフォーマットを引用する。

TRAINING SET LABEL FILE (train-labels-idx1-ubyte):

[offset] [type]          [value]          [description] 
0000     32 bit integer  0x00000801(2049) magic number (MSB first) 
0004     32 bit integer  60000            number of items 
0008     unsigned byte   ??               label 
0009     unsigned byte   ??               label 
........ 
xxxx     unsigned byte   ??               label
The labels values are 0 to 9.

TRAINING SET IMAGE FILE (train-images-idx3-ubyte):

[offset] [type]          [value]          [description] 
0000     32 bit integer  0x00000803(2051) magic number 
0004     32 bit integer  60000            number of images 
0008     32 bit integer  28               number of rows 
0012     32 bit integer  28               number of columns 
0016     unsigned byte   ??               pixel 
0017     unsigned byte   ??               pixel 
........ 
xxxx     unsigned byte   ??               pixel
Pixels are organized row-wise. Pixel values are 0 to 255. 0 means background (white), 255 means foreground (black).

TEST SET LABEL FILE (t10k-labels-idx1-ubyte):

[offset] [type]          [value]          [description] 
0000     32 bit integer  0x00000801(2049) magic number (MSB first) 
0004     32 bit integer  10000            number of items 
0008     unsigned byte   ??               label 
0009     unsigned byte   ??               label 
........ 
xxxx     unsigned byte   ??               label
The labels values are 0 to 9.

TEST SET IMAGE FILE (t10k-images-idx3-ubyte):

[offset] [type]          [value]          [description] 
0000     32 bit integer  0x00000803(2051) magic number 
0004     32 bit integer  10000            number of images 
0008     32 bit integer  28               number of rows 
0012     32 bit integer  28               number of columns 
0016     unsigned byte   ??               pixel 
0017     unsigned byte   ??               pixel 
........ 
xxxx     unsigned byte   ??               pixel
Pixels are organized row-wise. Pixel values are 0 to 255. 0 means background (white), 255 means foreground (black). 


画像ファイルは 0 が白で 255 が黒だそうだ。そうか手書き数字は白地に黒だったのか。。。知らなかった。

実際のデータを見てみよう。トレーニングデータは大きいので、テストデータを見ていこう。
最初に画像ファイルの t10k-images-idx3-ubyte をバイナリエディタで見た。
MNIST_dataset_1_170801.png

最初の 0x0000 0803 が画像ファイルのマジック・ナンバーだ。その次の 0x0000 2710 は16進数なので、10進数に直すと10,000 となってデータの数を表す。0x0000 001c は10 進数にすると 28 だ。その次も同様。その後からは1バイトずつ、つまり、0 ~ 255 までのピクセル値を表す。

次にラベル・ファイルの t10k-labels-idx1-ubyte を見てみよう。
MNIST_dataset_2_170801.png

最初の 0x0000 0801 はラベル・ファイルのマジック・ナンバーだ。その次の 0x0000 2710 は16進数なので、10進数に直すと10,000 となってデータの数を表す。その次からはラベルが続いている。最初のラベルは0x07 で、つまり最初の数字は 7 であるということを表す。その次の数字は 2 だ。
  1. 2017年08月01日 12:37 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

白線追従走行用畳み込みニューラルネットワークの製作2(画像縮小、切り出し)

白線追従走行用畳み込みニューラルネットワークの製作1(概要)”の続き。

前回から間が空いてしまったが、前回集めた直線の白線画像をデータセットにする第1段階として、画像縮小と切り出しを行うソフトウェアを作成してみよう。
Vivado HLSでハードウェア化しやすく、短いコードで書けるようにOpenCVを使用することにする。もちろんVivado HLSを使用して、Vivado HLSのテストベンチとして、C++ ソースファイルを用意する。環境はネイティブUbuntu16.04 でVivado HLS 2017.2 を使用している。

これからの白線追従のためのニューラルネット学習のためのデータ・セット作成手順を書いておく。

1. 800x600の白線画像を1/13.333...(0.075)の60x45に縮める。
2. 60x45のうちの下から60x14を中間BMPファイルとしてセーブ
3. 60x14のうちの56x10を切り出してBMPファイルに。1つにつき5x5の25個できる。
4. 左右直進をやる。
直進10枚x25+左旋回10x25+右旋回10x25=750このデータセットをとりあえず、作ってみようか?
56x10=560なのでMNISTデータセットよりも小さくなる。


現在のソースコードを貼っておく。まずは、ヘッダファイルの straight_dataset_bmp.h から。
(2017/08/03 :修正 バグフィックス)


// straight_dataset_bmp.h
// 2017/07/24 by marsee
//

#ifndef __STRAIGHT_DATASET_BMP_H__
#define __STRAIGHT_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_TRUN_BMP_FILE_NAME left_turn
#define RIGHT_TRUN_BMP_FILE_NAME right_turn
#define STRAIGHT_NUM_OF_IMAGE 10
#define LEFT_TRUN_NUM_OF_IMAGE 10
#define RIGHT_TRUNNUM_OF_IMAGE 10

typedef hls::Scalar<3, unsigned 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


次に、straight_dataset_bmp.cpp を貼っておく。まだ、直進の画像だけをしょりするコードだ。


// 2017/07/24 by marsee
//

#include <iostream>
#include "hls_opencv.h"
#include "straight_dataset_bmp.h"

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];
cv::Rect rect_center(2, 33, 56, 10);

// refereed to http://opencv.jp/cookbook/opencv_img.html
// straight
for(int i=0; i<STRAIGHT_NUM_OF_IMAGE; i++){
sprintf(bmp_file, "%s%d.bmp", straight_fn, i);
cv::Mat straight_img = cv::imread(bmp_file,1);
if(straight_img.empty())
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);

cv::Rect rect_center(2, 33, 56, 10);
cv::Mat img_rect(gray_img, rect_center);
sprintf(bmp_file, "%s_RED_rect%d.bmp", straight_fn, i);
cv::imwrite(bmp_file, img_rect);
}

return(0);
}


Vivado HLS 2017.2 の画面を示す。C シミュレーションが終了したところだ。
wlt_cnn_6_170801.png

60x45 に縮小した 0 番目の直進の画像を示す。
wlt_cnn_7_170801.png

60x45 に縮小した 9 番目の直進の画像を示す。
wlt_cnn_8_170801.png

60x45 の画像から白線の 60x14 の画像を切り出して、その真ん中の56x10 の画像を更に切り出した。これは 0 番目の画像から切り出した。
wlt_cnn_9_170801.png

60x45 の画像から白線の 60x14 の画像を切り出して、その真ん中の56x10 の画像を更に切り出した。これは 9 番目の画像から切り出した。
wlt_cnn_10_170801.png

大体うまく行っているかな?1 つの白線画像から 5x5 = 25 個のトレーニング用画像ができるはずだ。
  1. 2017年08月01日 05:09 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0