1. 程式人生 > >深度學習CSV格式原始資料用於裁剪影象

深度學習CSV格式原始資料用於裁剪影象

初衷

專案需要,需要做樣本類別訓練,即將每類樣本分放在不同的資料夾,通過網路訓練後得到模型,檢測資料輸出為所屬類別;
先前深度學習輸出為類別和位置,需要遍歷全域性影象,比較耗時。

問題

分類別訓練時,需要蒐集大量樣本並進行裁剪,這是一個很費時間和感情的事情;
恰好在深度學習時,通過labelimage等工具得到樣本資料,如下圖所示:

在這裡插入圖片描述

可否通過這些資料,將樣本裁剪出來呢?
於是乎,寫了個指令碼,並且實現了。

程式碼實現

#include<fstream>
#include<map>
#include<string>
#include<vector>
#include<iostream>
using namespace std;
#include<sstream>        //istringstream 必須包含這個標頭檔案
#include<opencv2/opencv.hpp>
int main()
{
	//圖片所在資料夾
	string path = "D:\\python_objectdetection\\models-master\\models-master\\research\\object_detection\\images_Iray\\test\\";
	//CSV檔案所在路徑,即生成tfrecord前的原始資料
	ifstream fin("D:\\python_objectdetection\\models-master\\models-master\\research\\object_detection\\data\\Iray\\test.csv"); //開啟檔案流操作
	string imgpath = "";
	//輸出圖片儲存位置
	string cutpath = "D:\\train_by_CNN\\images_iray\\";
	//讀圖計數
	int count = 0;
	string line;
	//記錄行數,第一行不操作
	int lines = 0;
	vector<string>classes;

	while (getline(fin, line))   //整行讀取,換行符“\n”區分,遇到檔案尾標誌eof終止讀取
	{
					
		lines++;
				
		istringstream stream_in(line); //將整行字串line讀入到字串流istringstream中

		vector<string> fields; //宣告一個字串向量

		string field;

		while (getline(stream_in, field, ',')) //將字串流sin中的字元讀入到field字串中,以逗號為分隔符
		{
			fields.push_back(field); //將剛剛讀取的字串新增到向量fields中
		}

		if (lines == 1)
			continue;

		imgpath = path + fields[0];

		cv::Mat image = cv::imread(imgpath);

		int xmin = std::stoi(fields[4]);
		int ymin = std::stoi(fields[5]);
		int xmax = std::stoi(fields[6]);
		int ymax = std::stoi(fields[7]);

		cv::Rect roi = cv::Rect(xmin, ymin, abs(xmax - xmin), abs(ymax - ymin));
		cv::Mat image_cut = image(roi);

//我這邊有兩類,所以新建了兩個資料夾
		if (fields[3] == "car")
		{
			count++;

			cutpath = cutpath + "1//" + "car_" + to_string(count) + ".jpg";

			cv::imwrite(cutpath, image_cut);

			cutpath = "D:\\train_by_CNN\\images_iray\\";

		}
		if (fields[3] == "boat")
		{

			count++;

			cutpath = cutpath + "2//" + "boat_" + to_string(count) + ".jpg";

			cv::imwrite(cutpath, image_cut);

			cutpath = "D:\\train_by_CNN\\images_iray\\";
		}
		image.release();
		image_cut.release();
	}		
	fin.close();
}

裁剪後效果這樣,資料夾名就1、2、3區分類別,在tf那邊有相應程式碼生成record格式。

在這裡插入圖片描述

程式碼如下:


import os

import tensorflow as tf

from PIL import Image

import sys

def creat_tf(imgpath):
    cwd = os.getcwd()

    classes = os.listdir(cwd + imgpath)

    # 此處定義tfrecords檔案存放

#存放record格式資料的位置

    writer = tf.python_io.TFRecordWriter("images_iray/train.tfrecords")

    for index, name in enumerate(classes):

        class_path = cwd + imgpath + name + "/"

        print(class_path)

        if os.path.isdir(class_path):

            for img_name in os.listdir(class_path):
                img_path = class_path + img_name

                img = Image.open(img_path)

                img = img.resize((224, 224))

                img_raw = img.tobytes()

                example = tf.train.Example(features=tf.train.Features(feature={

                    'label': tf.train.Feature(int64_list=tf.train.Int64List(value=[int(name)])),

                    'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))

                }))

                writer.write(example.SerializeToString())

                print(img_name)

    writer.close()
    
if __name__ == '__main__':
    #裁剪影象所在資料夾,是那個1、2資料夾上層路徑
    
    imgpath = '/images_iray/'

    creat_tf(imgpath)