手把手带你玩转Tensorflow 物体检测 API (2)——数据准备
致謝聲明
本文在學習《Tensorflow object detection API 搭建屬于自己的物體識別模型(2)——訓練并使用自己的模型》的基礎上優化并總結,此博客鏈接:https://blog.csdn.net/dy_guox/article/details/79111949,感謝此博客作者。
0.前言
在進行本文操作之前,需要先安裝好tensorflow的gpu版本。
本文作者的環境:python3.6、Windows10、tensorflow_gpu1.10
已經安裝好的可以跳過,學習如何安裝tensorflow的gpu版本的讀者請閱讀本文作者的另外一篇文章《深度學習環境搭建-CUDA9.0、cudnn7.3、tensorflow_gpu1.10的安裝》,鏈接:https://www.jianshu.com/p/4ebaa78e0233
本文是寫給目標檢測入門新手的指導文章,會用示意圖將每一步的詳細實現過程展示出來。
本文作者接觸深度學習2個月后,開始進行目標檢測實踐。
本文作者的專題《目標檢測》,鏈接:https://www.jianshu.com/c/fd1d6f784c1f
此專題的宗旨是讓基礎較為薄弱的新手能夠順利實現目標檢測,專題內容偏向于掌握技能,學會工具的使用。
本文作者尚未具備清楚講述目標檢測原理的能力,學習原理請自行另找文章。
| 1 | 目標檢測實踐_tensorflow版SSD運行示例 | https://www.jianshu.com/p/c1d8f1c76de7 |
| 2 | 目標檢測實踐_tensorflow版SSD數據準備 | https://www.jianshu.com/p/3d9436b4cb66 |
| 3 | 目標檢測實踐_tensorflow版SSD訓練自己的數據 | https://www.jianshu.com/p/0e5f9df4686a |
| 4 | 目標檢測實踐_tensorflow版SSD模型測試 | https://www.jianshu.com/p/7464c5e00716 |
1.下載圖片
本文作者給讀者演示的圖片數據是來自ImageNet中的鯉魚分類。
數據集在百度云盤,鏈接: https://pan.baidu.com/s/1NksESNqBX--YqMJ4zptGdw 提取碼: 6p3u
在桌面新建文件夾目標檢測,把下載好的壓縮文件n01440764.tar放到其中,如下圖所示:
image.png
選擇解壓到n01440764,如下圖所示:
image.png
解壓完成后,桌面的目標檢測文件夾中如下圖所示:
image.png
?
2.選擇圖片
在此數據集中,大部分圖片都較為清晰,但是有極少數圖片像素點少,不清晰。
像素點少的圖片不利于模型訓練或模型測試,所以在本章節中實現用python代碼選出部分圖片文件。
在桌面的目標檢測文件夾中打開cmd,即在路徑中輸入cmd后按Enter鍵,如下圖所示:
image.png
在cmd中輸入命令并運行:jupyter notebook,如下圖所示:
image.png
瀏覽器會自動打開1個標簽頁,選擇新建ipynb代碼文件,如下圖所示:
image.png
為ipynb文件重命名,重命名按鈕如下圖紅色箭頭標記處所示:
image.png
修改文件名為get_some_qualified_images,如下圖所示:
image.png
復制下面一段代碼到代碼文件get_some_qualified_images.ipynb的單元格中,復制后運行即可:
?
?
import os import random from PIL import Image import shutil#獲取文件夾中的文件路徑 def getFilePathList(dirPath, partOfFileName=''):allFileName_list = list(os.walk(dirPath))[0][2]fileName_list = [k for k in allFileName_list if partOfFileName in k]filePath_list = [os.path.join(dirPath, k) for k in fileName_list]return filePath_list#獲取一部分像素足夠,即長,寬都大于416的圖片 def get_some_qualified_images(dirPath, sample_number, new_dirPath):jpgFilePath_list = getFilePathList(dirPath, '.JPEG')random.shuffle(jpgFilePath_list)if not os.path.isdir(new_dirPath):os.makedirs(new_dirPath)i = 0for jpgFilePath in jpgFilePath_list:image = Image.open(jpgFilePath)width, height = image.sizeif width >= 416 and height >= 416:i += 1new_jpgFilePath = os.path.join(new_dirPath, '%03d.jpg' %i)shutil.copy(jpgFilePath, new_jpgFilePath)if i == sample_number:break#獲取數量為100的合格樣本存放到selected_images文件夾中 get_some_qualified_images('n01440764', 100, 'selected_images')代碼運行完成后,在桌面的目標檢測文件夾中,會有一個selected_images文件夾,如下圖所示:
image.png
?
3.縮小圖片
在第2章選擇圖片中,選出了100張像素足夠的圖片存放在selected_images文件夾中,即淘汰了像素過小的圖片。
在本章第3章中用代碼實現將像素過大的圖片做縮小。
在jupyter notebook中新建代碼文件get_small_images.ipynb,步驟與上一章中相同:
打開cmd——>運行jupyter notebook——>新建代碼文件——>代碼文件重命名
復制下面一段代碼到代碼文件get_small_images.ipynb的單元格中,復制后運行即可:
?
import os from PIL import Imagedef get_smaller_images(dirPath, new_dirPath):fileName_list = os.listdir(dirPath)filePath_list = [os.path.join(dirPath, fileName) for fileName in fileName_list]imagePath_list = [filePath for filePath in filePath_list if '.jpg' in filePath]if not os.path.isdir(new_dirPath):os.mkdir(new_dirPath)for imagePath in imagePath_list:image = Image.open(imagePath)width, height = image.sizeimageName = imagePath.split('\\')[-1]save_path = os.path.join(new_dirPath, imageName)if width >= 600 and height >= 600:minification = min(width, height) // 300 #此變量表示縮小倍數new_width = width // minificationnew_height = height // minificationresized_image = image.resize((new_width, new_height), Image.ANTIALIAS)print('圖片%s原來的寬%d,高%d, 圖片縮小后寬%d,高%d' %(imageName, width, height, new_width, new_height))resized_image.save(save_path)else:image.save(save_path)get_smaller_images('selected_images', 'smaller_images')在本文作者的實踐中,圖片經過PIL庫打開再保存,保持圖片質量的情況下,能夠縮小圖片文件大小3倍左右。本文作者猜測可能是使用的圖片壓縮算法不同,完成此步后,文件夾大小如下圖所示。
?
image.png
4.給圖片打標簽
使用打標簽工具LabelImg,下載頁面鏈接:https://tzutalin.github.io/labelImg/
如果下載頁面鏈接沒法訪問,也可以從百度云盤中下載。
鏈接: https://pan.baidu.com/s/1jVmkLxqQMZNJIzyv75HilA 提取碼: yysh
下載頁面如下圖所示:
image.png
選擇下載Windows_v1.8.0,如下圖中紅色箭頭標記處所示:
image.png
把壓縮文件windows_v1.8.0.zip放到D盤根目錄中,選擇解壓到當前文件夾。
解壓后D盤根目錄下會有windows_v1.8.0文件夾,LabelImg軟件在文件夾中。
選擇D盤根目錄的原因:如果windows_v1.8.0文件夾路徑中帶有中文,打開LabelImg軟件會閃退。
打開LabelImg軟件,點擊下圖紅色箭頭標記處。
image.png
在打開的軟件界面,點擊Open Dir按鈕,如下圖紅色箭頭標注處所示。
image.png
首先打開桌面的目標檢測文件夾,在選中文件夾smaller_images的情況下,點擊下圖紅色箭頭標記處所示的選擇文件夾按鈕。
注意:只需要鼠標選中文件夾smaller_images,不需要進入文件夾smaller_images中。
image.png
在輸入法為英文輸入的情況下,按鍵盤上的w鍵則可以開始繪制方框,方框會框住圖片中的物體。
完成繪制方框后,還需要為方框標上類別,如下圖所示。
注意:每完成一張圖的打標簽,一定要記得保存!!!
image.png
在本文演示中,需要給圖片中的鯉魚和人臉2個類別打標簽。
鯉魚的標簽名叫做fish,人臉的標簽名叫human_face,打標簽的結果如下圖所示。
注意:用方框框住物體時,盡量框住物體的所有部位,例如本文中的魚,魚鰭是一個重要特征。保證框住物體所有部位的情況下,也不要使方框四周留出過多空白。
image.png
遇到特征不明顯的圖片,可以放棄為此圖片打標簽,舉例如下圖所示:
image.png
為100張圖片打標簽,本文作者共花費44分鐘。
用LabelImg軟件打標簽會給每張圖片產生對應的xml文件。
檢查是否給所有圖片都打上標簽,在文件夾smaller_images中共有99個xml文件,如下圖所示。
因為有1張圖片難以辨認,所以沒有給它打標簽。
image.png
本文作者把已經打標簽好的文件夾smaller_images做成壓縮文件smaller_images.zip,并上傳到百度網盤。
下載鏈接: https://pan.baidu.com/s/1tkCV95pzLyRV5gSRF9sF8A 提取碼: 7j88
?
5.xml轉csv
xml轉csv的意思是,將xml文件中的信息整合到csv文件中。
在桌面的目標檢測文件夾中新建代碼文件xml_to_csv.ipynb,步驟與第2章中相同:
打開cmd——>運行jupyter notebook——>新建代碼文件——>代碼文件重命名
復制下面一段代碼到代碼文件xml_to_csv.ipynb的單元格中,復制后運行即可:
?
import os import pandas as pd import xml.etree.ElementTree as ET from sklearn.model_selection import train_test_splitdef xmlPath_list_to_df(xmlPath_list):xmlContent_list = []for xmlPath in xmlPath_list:tree = ET.parse(xmlPath)root = tree.getroot()for member in root.findall('object'):value = (root.find('filename').text,int(root.find('size')[0].text),int(root.find('size')[1].text),member[0].text,int(member[4][0].text),int(member[4][1].text),int(member[4][2].text),int(member[4][3].text))xmlContent_list.append(value)column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']xmlContent_df = pd.DataFrame(xmlContent_list, columns=column_name) return xmlContent_dfdef dirPath_to_csv(dirPath):fileName_list = os.listdir(dirPath)all_xmlPath_list = [os.path.join(dirPath, fileName) for fileName in fileName_list if '.xml' in fileName]train_xmlPath_list, test_xmlPath_list = train_test_split(all_xmlPath_list, test_size=0.1, random_state=1)train_df = xmlPath_list_to_df(train_xmlPath_list)train_df.to_csv('train.csv')print('成功產生文件train.csv,訓練集共有%d張圖片' %len(train_xmlPath_list))test_df = xmlPath_list_to_df(test_xmlPath_list)test_df.to_csv('test.csv')print('成功產生文件test.csv,測試集共有%d張圖片' %len(test_xmlPath_list))dirPath_to_csv('smaller_images')為了使讀者與本文作者的復現結果一致,本文作者將函數train_test_split的參數random_state的值設為1,這樣每次劃分的訓練集和測試集總是相同。如果不設置此參數,則每次劃分的訓練集和測試集不同。
上面一段代碼的運行結果如下:
成功產生文件train.csv,訓練集共有89張圖片
成功產生文件test.csv,測試集共有10張圖片
6.csv轉tfrecord
csv轉tfrecord的意思是,將csv文件中的信息和圖片數據整合到tfrecord文件中。
6.1 配置環境
下載文件object_detection.zip
鏈接:https://pan.baidu.com/s/1Q9SxtKlOqEty08tpFeUUHA 提取碼: p2sm
選擇提取到"object_detection",如下圖所示:
image.png
按照鏈接https://www.jianshu.com/p/0e5f9df4686a 中的第1章《解決第1個報錯》添加環境變量。
?
6.2 編輯和運行代碼
在桌面的目標檢測文件夾中新建代碼文件csv_to_tfrecord.ipynb,步驟與第2章中相同:
打開cmd——>運行jupyter notebook——>新建代碼文件——>代碼文件重命名
復制下面一段代碼到代碼文件csv_to_tfrecord.ipynb的單元格中,復制后運行即可:
?
import os import pandas as pd import tensorflow as tf from object_detection.utils import dataset_util import shutildef csv2tfrecord(csv_path, imageDir_path, tfrecord_path):objectInfo_df = pd.read_csv(csv_path)tfrecord_writer = tf.python_io.TFRecordWriter(tfrecord_path)for filename, group in objectInfo_df.groupby('filename'):height = group.iloc[0]['height']width = group.iloc[0]['width']filename_bytes = filename.encode('utf-8')image_path = os.path.join(imageDir_path, filename)with open(image_path, 'rb') as file:encoded_jpg = file.read()image_format = b'jpg'xmin_list = list(group['xmin'] / width)xmax_list = list(group['xmax'] / width)ymin_list = list(group['ymin'] / height)ymax_list = list(group['ymax'] / height)classText_list = [classText.encode('utf-8') for classText in group['class']]classLabel_list = [classText_to_classLabel(classText) for classText in group['class']]tf_example = tf.train.Example(features = tf.train.Features(feature = {'image/height': dataset_util.int64_feature(height),'image/width': dataset_util.int64_feature(width),'image/filename': dataset_util.bytes_feature(filename_bytes),'image/source_id': dataset_util.bytes_feature(filename_bytes),'image/encoded': dataset_util.bytes_feature(encoded_jpg),'image/format': dataset_util.bytes_feature(image_format),'image/object/bbox/xmin': dataset_util.float_list_feature(xmin_list),'image/object/bbox/xmax': dataset_util.float_list_feature(xmax_list),'image/object/bbox/ymin': dataset_util.float_list_feature(ymin_list),'image/object/bbox/ymax': dataset_util.float_list_feature(ymax_list),'image/object/class/text': dataset_util.bytes_list_feature(classText_list),'image/object/class/label': dataset_util.int64_list_feature(classLabel_list),}))tfrecord_writer.write(tf_example.SerializeToString())tfrecord_writer.close()print('成功產生tfrecord文件,保存在路徑:%s' %tfrecord_path)#如果訓練自己的模型,目標檢測的類別不同,需要修改此處 def classText_to_classLabel(row_label):if row_label == 'fish':return 1elif row_label == 'human_face':return 2else:return Nonedir_name = 'training' if not os.path.isdir(dir_name):os.mkdir(dir_name) csv2tfrecord('train.csv', 'smaller_images', 'training/train.tfrecord') csv2tfrecord('test.csv', 'smaller_images', 'training/test.tfrecord')本文作者花費了2個小時左右將原博客作者的代碼精簡成上面一段代碼,調用庫更少,調用方法更常用,變量名命名表達意思更準確,使讀者更容易理解本段代碼的作用。
上面一段代碼的運行結果如下:
成功產生tfrecord文件,保存在路徑:training/train.tfrecord
成功產生tfrecord文件,保存在路徑:training/test.tfrecord
上面一段代碼運行完成后,桌面的目標檢測文件夾中會產生一個文件夾training,如下圖紅色箭頭標注處所示。
image.png
在文件夾training中,有2個tfrecord文件,如下圖所示:
image.png
?
7.編寫pbtxt文件
在桌面文件夾目標檢測的文件夾training中,創建文本文件my_label_map.pbtxt。
復制下面一段內容到文本文件my_label_map.pbtxt中。
?
item {name : "fish"id : 1 } item {name : "human_face"id : 2 }復制后保存即可,此時文件夾training中有3個文件,如下圖所示:
image.png
有一個細節需要特別注意,因為此細節,本文作者花費了1天半時間才解決報錯問題。
文本文件fish_label.pbtxt在Windows系統下默認編碼格式是ANSI格式,工程中需要的就是此格式。
但是本文作者在認為python3對utf-8編碼支持較好,所以把文本文件fish_label.pbtxt的編碼改成了utf-8格式,導致工程報錯。
?
8.編寫配置文件
在桌面文件夾目標檢測的文件夾training中,創建配置文件ssdlite_mobilenet_v2_coco.config。
本文作者給讀者提供2種方式獲得正確的配置文件。
8.1 網盤下載
本文作者將適用于本文的配置文件的各項參數都已經設置好,并且上傳百度網盤。
鏈接: https://pan.baidu.com/s/1ERp0zJ4cpI5VHHeHcyI_Rg 提取碼: ud28
8.2 修改原生配置文件
如果讀者已經閱讀過《目標檢測》系列的第一篇文章:《目標檢測第1步-運行tensorflow官方示例》,鏈接:https://www.jianshu.com/p/c1d8f1c76de7
可以在object_detection文件夾中的samples/config路徑下,找到原生配置文件ssdlite_mobilenet_v2_coco.config,如下圖紅色箭頭標記處所示。
image.png
原生配置文件ssdlite_mobilenet_v2_coco.config先復制1份到桌面文件目標檢測的文件夾training中。
原生配置文件中的需要修改的部分:
?
修改配置文件ssdlite_mobilenet_v2_coco.config并保存后,此時文件夾training中有4個文件,如下圖所示:
image.png
?
9.總結
1.本篇文章到此結束,詳細地介紹了數據準備的過程。
本篇文章的階段性成果training文件夾已經上傳百度云盤。
鏈接: https://pan.baidu.com/s/1Kgp9geSkTFVa_4tfc7ZPew 提取碼: 9sy3
2.《目標檢測》系列的下一篇文章《目標檢測實踐_tensorflow版SSD訓練自己的數據》,鏈接:https://www.jianshu.com/p/0e5f9df4686a
作者:瀟灑坤
鏈接:https://www.jianshu.com/p/3d9436b4cb66
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
總結
以上是生活随笔為你收集整理的手把手带你玩转Tensorflow 物体检测 API (2)——数据准备的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Supervisor管理springbo
- 下一篇: matlab for循环太慢,Matla