├── Documents
├── Documents.jpg
├── dd.png
├── ddd.png
├── ee.jpg
├── er.jpg
├── tt.png
└── yy.jpg
├── Plant_detection_image.py
├── Plant_detection_video.py
├── Plant_detection_webcam.py
├── README.md
├── generate_tfrecord.py
├── inference_graph
├── checkpoint
├── frozen_inference_graph.pb
├── model.ckpt.data-00000-of-00001
├── model.ckpt.index
├── model.ckpt.meta
├── pipeline.config
└── saved_model
│ └── saved_model.pb
├── training
├── labelmap.pbtxt
└── ssd_mobilenet_v1_pets.config
└── xml_to_csv.py
/Documents/Documents.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KundanBalse/Plant-Detection-Using-TensorFlow/a4b1d6e0195f4e2f633949facecfbef4faafee29/Documents/Documents.jpg
--------------------------------------------------------------------------------
/Documents/dd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KundanBalse/Plant-Detection-Using-TensorFlow/a4b1d6e0195f4e2f633949facecfbef4faafee29/Documents/dd.png
--------------------------------------------------------------------------------
/Documents/ddd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KundanBalse/Plant-Detection-Using-TensorFlow/a4b1d6e0195f4e2f633949facecfbef4faafee29/Documents/ddd.png
--------------------------------------------------------------------------------
/Documents/ee.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KundanBalse/Plant-Detection-Using-TensorFlow/a4b1d6e0195f4e2f633949facecfbef4faafee29/Documents/ee.jpg
--------------------------------------------------------------------------------
/Documents/er.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KundanBalse/Plant-Detection-Using-TensorFlow/a4b1d6e0195f4e2f633949facecfbef4faafee29/Documents/er.jpg
--------------------------------------------------------------------------------
/Documents/tt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KundanBalse/Plant-Detection-Using-TensorFlow/a4b1d6e0195f4e2f633949facecfbef4faafee29/Documents/tt.png
--------------------------------------------------------------------------------
/Documents/yy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KundanBalse/Plant-Detection-Using-TensorFlow/a4b1d6e0195f4e2f633949facecfbef4faafee29/Documents/yy.jpg
--------------------------------------------------------------------------------
/Plant_detection_image.py:
--------------------------------------------------------------------------------
1 | ######## Image Plant Detection Using Tensorflow-trained Classifier #########
2 | #
3 | # Author: Kundan Balse
4 | # Date: 15/4/2018
5 | # Description:
6 | # This program uses a TensorFlow-trained classifier to perform plant detection.
7 | # It loads the classifier uses it to perform object detection on an image.
8 | # It draws boxes and scores around the objects of interest in the image.
9 |
10 | ## Some of the code is copied from Google's example at
11 | ## https://github.com/tensorflow/models/blob/master/research/object_detection/object_detection_tutorial.ipynb
12 |
13 | ## and some is copied from Dat Tran's example at
14 | ## https://github.com/datitran/object_detector_app/blob/master/object_detection_app.py
15 |
16 | ## but I changed it to make it more understandable to me.
17 |
18 | # Import packages
19 | import os
20 | import cv2
21 | import numpy as np
22 | import tensorflow as tf
23 | import sys
24 |
25 | # This is needed since the notebook is stored in the object_detection folder.
26 | sys.path.append("..")
27 |
28 | # Import utilites
29 | from utils import label_map_util
30 | from utils import visualization_utils as vis_util
31 |
32 | # Name of the directory containing the object detection module we're using
33 | MODEL_NAME = 'inference_graph'
34 | IMAGE_NAME = 'test1.jpg'
35 |
36 | # Grab path to current working directory
37 | CWD_PATH = os.getcwd()
38 |
39 | # Path to frozen detection graph .pb file, which contains the model that is used
40 | # for object detection.
41 | PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,'frozen_inference_graph.pb')
42 |
43 | # Path to label map file
44 | PATH_TO_LABELS = os.path.join(CWD_PATH,'training','labelmap.pbtxt')
45 |
46 | # Path to image
47 | PATH_TO_IMAGE = os.path.join(CWD_PATH,IMAGE_NAME)
48 |
49 | # Number of classes the object detector can identify
50 | NUM_CLASSES = 6
51 |
52 | # Load the label map.
53 | # Label maps map indices to category names, so that when our convolution
54 | # network predicts `5`, we know that this corresponds to `king`.
55 | # Here we use internal utility functions, but anything that returns a
56 | # dictionary mapping integers to appropriate string labels would be fine
57 | label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
58 | categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
59 | category_index = label_map_util.create_category_index(categories)
60 |
61 | # Load the Tensorflow model into memory.
62 | detection_graph = tf.Graph()
63 | with detection_graph.as_default():
64 | od_graph_def = tf.GraphDef()
65 | with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
66 | serialized_graph = fid.read()
67 | od_graph_def.ParseFromString(serialized_graph)
68 | tf.import_graph_def(od_graph_def, name='')
69 |
70 | sess = tf.Session(graph=detection_graph)
71 |
72 | # Define input and output tensors (i.e. data) for the object detection classifier
73 |
74 | # Input tensor is the image
75 | image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
76 |
77 | # Output tensors are the detection boxes, scores, and classes
78 | # Each box represents a part of the image where a particular object was detected
79 | detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
80 |
81 | # Each score represents level of confidence for each of the objects.
82 | # The score is shown on the result image, together with the class label.
83 | detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
84 | detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')
85 |
86 | # Number of objects detected
87 | num_detections = detection_graph.get_tensor_by_name('num_detections:0')
88 |
89 | # Load image using OpenCV and
90 | # expand image dimensions to have shape: [1, None, None, 3]
91 | # i.e. a single-column array, where each item in the column has the pixel RGB value
92 | image = cv2.imread(PATH_TO_IMAGE)
93 | image_expanded = np.expand_dims(image, axis=0)
94 |
95 | # Perform the actual detection by running the model with the image as input
96 | (boxes, scores, classes, num) = sess.run(
97 | [detection_boxes, detection_scores, detection_classes, num_detections],
98 | feed_dict={image_tensor: image_expanded})
99 |
100 | # Draw the results of the detection (aka 'visulaize the results')
101 |
102 | vis_util.visualize_boxes_and_labels_on_image_array(
103 | image,
104 | np.squeeze(boxes),
105 | np.squeeze(classes).astype(np.int32),
106 | np.squeeze(scores),
107 | category_index,
108 | use_normalized_coordinates=True,
109 | line_thickness=8,
110 | min_score_thresh=0.80)
111 |
112 | # All the results have been drawn on image. Now display the image.
113 | cv2.imshow('Object detector', image)
114 |
115 | # Press any key to close the image
116 | cv2.waitKey(0)
117 |
118 | # Clean up
119 | cv2.destroyAllWindows()
120 |
--------------------------------------------------------------------------------
/Plant_detection_video.py:
--------------------------------------------------------------------------------
1 | ######## Plant Detection Using Tensorflow-trained Classifier #########
2 | #
3 | # Author: kundan balse
4 | # Date: 15/4/2018
5 | # Description:
6 | # This program uses a TensorFlow-trained classifier to perform plant detection.
7 | # It loads the classifier uses it to perform object detection on a video.
8 | # It draws boxes and scores around the objects of interest in each frame
9 | # of the video.
10 |
11 | ## Some of the code is copied from Google's example at
12 | ## https://github.com/tensorflow/models/blob/master/research/object_detection/object_detection_tutorial.ipynb
13 |
14 | ## and some is copied from Dat Tran's example at
15 | ## https://github.com/datitran/object_detector_app/blob/master/object_detection_app.py
16 |
17 | ## but I changed it to make it more understandable to me.
18 |
19 | # Import packages
20 | import os
21 | import cv2
22 | import numpy as np
23 | import tensorflow as tf
24 | import sys
25 |
26 | # This is needed since the notebook is stored in the object_detection folder.
27 | sys.path.append("..")
28 |
29 | # Import utilites
30 | from utils import label_map_util
31 | from utils import visualization_utils as vis_util
32 |
33 | # Name of the directory containing the object detection module we're using
34 | MODEL_NAME = 'inference_graph'
35 | VIDEO_NAME = 'test.mov'
36 |
37 | # Grab path to current working directory
38 | CWD_PATH = os.getcwd()
39 |
40 | # Path to frozen detection graph .pb file, which contains the model that is used
41 | # for object detection.
42 | PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,'frozen_inference_graph.pb')
43 |
44 | # Path to label map file
45 | PATH_TO_LABELS = os.path.join(CWD_PATH,'training','labelmap.pbtxt')
46 |
47 | # Path to video
48 | PATH_TO_VIDEO = os.path.join(CWD_PATH,VIDEO_NAME)
49 |
50 | # Number of classes the object detector can identify
51 | NUM_CLASSES = 6
52 |
53 | # Load the label map.
54 | # Label maps map indices to category names, so that when our convolution
55 | # network predicts `5`, we know that this corresponds to `king`.
56 | # Here we use internal utility functions, but anything that returns a
57 | # dictionary mapping integers to appropriate string labels would be fine
58 | label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
59 | categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
60 | category_index = label_map_util.create_category_index(categories)
61 |
62 | # Load the Tensorflow model into memory.
63 | detection_graph = tf.Graph()
64 | with detection_graph.as_default():
65 | od_graph_def = tf.GraphDef()
66 | with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
67 | serialized_graph = fid.read()
68 | od_graph_def.ParseFromString(serialized_graph)
69 | tf.import_graph_def(od_graph_def, name='')
70 |
71 | sess = tf.Session(graph=detection_graph)
72 |
73 | # Define input and output tensors (i.e. data) for the object detection classifier
74 |
75 | # Input tensor is the image
76 | image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
77 |
78 | # Output tensors are the detection boxes, scores, and classes
79 | # Each box represents a part of the image where a particular object was detected
80 | detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
81 |
82 | # Each score represents level of confidence for each of the objects.
83 | # The score is shown on the result image, together with the class label.
84 | detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
85 | detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')
86 |
87 | # Number of objects detected
88 | num_detections = detection_graph.get_tensor_by_name('num_detections:0')
89 |
90 | # Open video file
91 | video = cv2.VideoCapture("C:/tensorflow1/models/research/object_detection/test.mp4")
92 |
93 | while(video.isOpened()):
94 |
95 | # Acquire frame and expand frame dimensions to have shape: [1, None, None, 3]
96 | # i.e. a single-column array, where each item in the column has the pixel RGB value
97 | ret, frame = video.read()
98 | frame_expanded = np.expand_dims(frame, axis=0)
99 |
100 | # Perform the actual detection by running the model with the image as input
101 | (boxes, scores, classes, num) = sess.run(
102 | [detection_boxes, detection_scores, detection_classes, num_detections],
103 | feed_dict={image_tensor: frame_expanded})
104 |
105 | # Draw the results of the detection (aka 'visulaize the results')
106 | vis_util.visualize_boxes_and_labels_on_image_array(
107 | frame,
108 | np.squeeze(boxes),
109 | np.squeeze(classes).astype(np.int32),
110 | np.squeeze(scores),
111 | category_index,
112 | use_normalized_coordinates=True,
113 | line_thickness=8,
114 | min_score_thresh=0.80)
115 |
116 | # All the results have been drawn on the frame, so it's time to display it.
117 | cv2.imshow('Object detector', frame)
118 |
119 | # Press 'q' to quit
120 | if cv2.waitKey(1) == ord('q'):
121 | break
122 |
123 | # Clean up
124 | video.release()
125 | cv2.destroyAllWindows()
126 |
--------------------------------------------------------------------------------
/Plant_detection_webcam.py:
--------------------------------------------------------------------------------
1 | ######## Webcam Plant Detection Using Tensorflow-trained Classifier #########
2 | #
3 | # Author: Kundan Balse
4 | # Date: 15/4/2018
5 | # Description:
6 | # This program uses a TensorFlow-trained classifier to perform plant detection.
7 | # It loads the classifier uses it to perform plant detection on a webcam feed.
8 | # It draws boxes and scores around the plant of interest in each frame from
9 | # the webcam.
10 |
11 | ## Some of the code is copied from Google's example at
12 | ## https://github.com/tensorflow/models/blob/master/research/object_detection/object_detection_tutorial.ipynb
13 |
14 | ## and some is copied from Dat Tran's example at
15 | ## https://github.com/datitran/object_detector_app/blob/master/object_detection_app.py
16 |
17 | ## but I changed it to make it more understandable to me.
18 |
19 |
20 | # Import packages
21 | import os
22 | import cv2
23 | import numpy as np
24 | import tensorflow as tf
25 | import sys
26 |
27 | # This is needed since the notebook is stored in the object_detection folder.
28 | sys.path.append("..")
29 |
30 | # Import utilites
31 | from utils import label_map_util
32 | from utils import visualization_utils as vis_util
33 |
34 | # Name of the directory containing the object detection module we're using
35 | MODEL_NAME = 'inference_graph'
36 |
37 | # Grab path to current working directory
38 | CWD_PATH = os.getcwd()
39 |
40 | # Path to frozen detection graph .pb file, which contains the model that is used
41 | # for object detection.
42 | PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,'frozen_inference_graph.pb')
43 |
44 | # Path to label map file
45 | PATH_TO_LABELS = os.path.join(CWD_PATH,'training','labelmap.pbtxt')
46 |
47 | # Number of classes the object detector can identify
48 | NUM_CLASSES = 6
49 |
50 | ## Load the label map.
51 | # Label maps map indices to category names, so that when our convolution
52 | # network predicts `5`, we know that this corresponds to `guava`.
53 | # Here we use internal utility functions, but anything that returns a
54 | # dictionary mapping integers to appropriate string labels would be fine
55 | label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
56 | categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
57 | category_index = label_map_util.create_category_index(categories)
58 |
59 | # Load the Tensorflow model into memory.
60 | detection_graph = tf.Graph()
61 | with detection_graph.as_default():
62 | od_graph_def = tf.GraphDef()
63 | with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
64 | serialized_graph = fid.read()
65 | od_graph_def.ParseFromString(serialized_graph)
66 | tf.import_graph_def(od_graph_def, name='')
67 |
68 | sess = tf.Session(graph=detection_graph)
69 |
70 |
71 | # Define input and output tensors (i.e. data) for the object detection classifier
72 |
73 | # Input tensor is the image
74 | image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
75 |
76 | # Output tensors are the detection boxes, scores, and classes
77 | # Each box represents a part of the image where a particular object was detected
78 | detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
79 |
80 | # Each score represents level of confidence for each of the objects.
81 | # The score is shown on the result image, together with the class label.
82 | detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
83 | detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')
84 |
85 | # Number of objects detected
86 | num_detections = detection_graph.get_tensor_by_name('num_detections:0')
87 |
88 | # Initialize webcam feed
89 | video = cv2.VideoCapture(0)
90 | ret = video.set(3,1280)
91 | ret = video.set(4,720)
92 |
93 | while(True):
94 |
95 | # Acquire frame and expand frame dimensions to have shape: [1, None, None, 3]
96 | # i.e. a single-column array, where each item in the column has the pixel RGB value
97 | ret, frame = video.read()
98 | frame_expanded = np.expand_dims(frame, axis=0)
99 |
100 | # Perform the actual detection by running the model with the image as input
101 | (boxes, scores, classes, num) = sess.run(
102 | [detection_boxes, detection_scores, detection_classes, num_detections],
103 | feed_dict={image_tensor: frame_expanded})
104 |
105 | # Draw the results of the detection (aka 'visulaize the results')
106 | vis_util.visualize_boxes_and_labels_on_image_array(
107 | frame,
108 | np.squeeze(boxes),
109 | np.squeeze(classes).astype(np.int32),
110 | np.squeeze(scores),
111 | category_index,
112 | use_normalized_coordinates=True,
113 | line_thickness=8,
114 | min_score_thresh=0.85)
115 |
116 | # All the results have been drawn on the frame, so it's time to display it.
117 | cv2.imshow('Object detector', frame)
118 |
119 | # Press 'q' to quit
120 | if cv2.waitKey(1) == ord('q'):
121 | break
122 |
123 | # Clean up
124 | video.release()
125 | cv2.destroyAllWindows()
126 |
127 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Plant-Detection-Using-TensorFlow
2 |
3 | __Plant identification based on leaf structure__
4 |
5 | ## Introduction
6 |
7 | Plants exist everywhere we live, as well as places without us. Many of them carry significant information for the development of human society. The relationship between human beings and plants are also very close. In addition, plants are important means of circumstances and production of human beings. Regrettably, the amazing development of human civilization has disturbed this balance to a greater extent than realized. It is one of the biggest duties of human beings to save the plants from various dangers. So, the diverseness of the plant community should be restored and put everything back to balance. The urgent situation is that many plants are at the risk of extinction. So, it is very necessary to set up a database for plant protection We believe that the first step is to teach a computer how to classify plants.
8 |
9 | The tutorial is written for Windows 10, and it will also work for Windows 7 and 8. The general procedure can also be used for Linux operating systems, but file paths and package installation commands will need to change accordingly.
10 |
11 | __Special Thanks To: EdjeElectronics, Sentdex__
12 |
13 | If you encounter any problems while doing this project please do refer the link given below for the solutions https://github.com/EdjeElectronics/TensorFlow-Object-Detection-API-Tutorial-Train-Multiple-Objects-Windows-10
14 |
15 | ## Steps
16 |
17 | ### 1. Install TensorFlow (skip this step if TensorFlow-GPU 1.5 is already installed) or TensorFlow-CPU
18 |
19 | Install TensorFlow-GPU and CPU by following the instructions or you can follow YouTube Video by Mark Jay.
20 |
21 | The video is made for TensorFlow-GPU v1.4, but the “pip install --upgrade tensorflow-gpu or pip install --upgrade tensorflow (FOR CPU)” command will automatically download version 1.5. Download and install CUDA v9.0 and cuDNN v7.0 (rather than CUDA v8.0 and cuDNN v6.0 as instructed in the video), because they are supported by TensorFlow-GPU v1.5. As future versions of TensorFlow are released, you will likely need to continue updating the CUDA and cuDNN versions to the latest supported version.
22 | Be sure to install Anaconda with Python 3.6 as instructed in the video, as the Anaconda virtual environment will be used for the rest of this tutorial.
23 | Visit TensorFlow's website for further installation details, including how to install it on other operating systems (like Linux). The object detection repository itself also has installation instructions.
24 |
25 | ### 2. Set up TensorFlow Directory and Anaconda Virtual Environment
26 |
27 | The TensorFlow Object Detection API requires using the specific directory structure provided in its GitHub repository. It also requires several additional Python packages, specific additions to the PATH and PYTHONPATH variables, and a few extra setup commands to get everything set up to run or train an object detection model.
28 | This portion of the tutorial goes over the full set up required. It is fairly meticulous, but follow the instructions closely, because improper setup can cause unwieldy errors down the road.
29 |
30 | #### 2a. Download TensorFlow Object Detection API repository from GitHub
31 |
32 | Create a folder directly in C: and name it “tensorflow1”. This working directory will contain the full TensorFlow object detection framework, as well as your training images, training data, trained classifier, configuration files, and everything else needed for the object detection classifier.
33 | Download the full TensorFlow object detection repository located at https://github.com/tensorflow/models by clicking the “Clone or Download” button and downloading the zip file. Open the downloaded zip file and extract the “models-master” folder directly into the C:\tensorflow1 directory you just created. Rename “models-master” to just “models”. (Note, this tutorial was done using this GitHub commit of the TensorFlow Object Detection API. If portions of this tutorial do not work, it may be necessary to download and use this exact commit rather than the most up-to-date version.)
34 |
35 | #### 2b. Download the ssd_mobilenet_v1_coco model from TensorFlow's model zoo
36 | (https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md)
37 | TensorFlow provides several object detection models (pre-trained classifiers with specific neural network architectures) in its model zoo. Some models (such as the SSD-MobileNet model) have an architecture that allows for faster detection but with less accuracy, while some models (such as the Faster-RCNN model) give slower detection but with more accuracy. I initially started with the SSD-MobileNet-V1 model because my local machine(laptop) configurations is lower and I am training my dataset on CPU (no GPU). If you have the higher configuration laptop with decent NVDIA graphics card then you can make use of Faster-RCNN-Inception-V2 model, and the detection works considerably better, but with a noticeably slower speed. This tutorial will use the ssd_mobilenet_v1_coco model. Download the model here (http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v2_coco_2018_03_29.tar.gz). Open the downloaded ssd_mobilenet_v1_coco file with a file archiver such as WinZip or 7-Zip and extract the ssd_mobilenet_v1_coco folder to the
38 | C:\tensorflow1\models\research\object_detection folder. (Note: The model date and version will likely change in the future, but it should still work with this tutorial.)
39 |
40 | #### 2c. Download this tutorial's repository from GitHub
41 |
42 | Download the full repository located on this page (scroll to the top and click Clone or Download) and extract all the contents directly into the C:\tensorflow1\models\research\object_detection directory. (You can overwrite the existing "README.md" file.) This establishes a specific directory structure that will be used for the rest of the tutorial.
43 |
44 | link = (https://github.com/KundanBalse/Plant-Detection-Using-TensorFlow)
45 |
46 | Delete the following files (do not delete the folders):
47 |
48 | • All files in \object_detection\images\train and \object_detection\images\test
49 |
50 | • The “test_labels.csv” and “train_labels.csv” files in \object_detection\images
51 |
52 | • All files in \object_detection\training
53 |
54 | • All files in \object_detection\inference_graph
55 |
56 | Now, you are ready to start from scratch in training your own Plant detector. This tutorial will assume that all the files listed above were deleted and will go on to explain how to generate the files for your own training dataset.
57 |
58 | #### 2d. Set up new Anaconda virtual environment
59 |
60 | Next, we'll work on setting up a virtual environment in Anaconda for tensorflow. From the Start menu in Windows, search for the Anaconda Prompt utility, right click on it, and click “Run as Administrator”. If Windows asks you if you would like to allow it to make changes to your computer, click Yes.
61 | In the command terminal that pops up, create a new virtual environment called “tensorflow1” by issuing the following command:
62 |
63 | C:\> conda create -n tensorflow1 pip python=3.5
64 |
65 | Then, activate the environment by issuing:
66 |
67 | C:\> activate tensorflow1
68 |
69 | Install tensorflow in this environment by issuing:
70 |
71 | (tensorflow1) C:\> pip install --ignore-installed --upgrade tensorflow
72 |
73 | Install the other necessary packages by issuing the following commands:
74 |
75 | (tensorflow1) C:\> conda install -c anaconda protobuf
76 |
77 | (tensorflow1) C:\> pip install pillow
78 |
79 | (tensorflow1) C:\> pip install lxml
80 |
81 | (tensorflow1) C:\> pip install Cython
82 |
83 | (tensorflow1) C:\> pip install jupyter
84 |
85 | (tensorflow1) C:\> pip install matplotlib
86 |
87 | (tensorflow1) C:\> pip install pandas
88 |
89 | (tensorflow1) C:\> pip install opencv-python
90 |
91 | (Note: The ‘pandas’ and ‘opencv-python’ packages are not needed by TensorFlow, but they are used in the Python scripts to generate TFRecords and to work with images, videos, and webcam feeds.)
92 |
93 | #### 2e. Configure PYTHONPATH environment variable
94 |
95 | A PYTHONPATH variable must be created that points to the \models, \models\research, and \models\research\slim directories. Do this by issuing the following commands (from any directory):
96 |
97 | (tensorflow1) C:\> set PYTHONPATH=C:\tensorflow1\models;C:\tensorflow1\models\research;C:\tensorflow1\models\research\slim
98 |
99 | (Note: Every time the "tensorflow1" virtual environment is exited, the PYTHONPATH variable is reset and needs to be set up again.)
100 |
101 |
102 | #### 2f. Compile Protobufs and run setup.py
103 |
104 | Next, compile the Protobuf files, which are used by TensorFlow to configure model and training parameters. Unfortunately, the short protoc compilation command posted on TensorFlow’s Object Detection API installation page does not work on Windows. Every .proto file in the \object_detection\protos directory must be called out individually by the command.
105 | In the Anaconda Command Prompt, change directories to the \models\research directory and copy and paste the following command into the command line and press Enter:
106 |
107 | (protoc --python_out=. .\object_detection\protos\anchor_generator.proto .\object_detection\protos\argmax_matcher.proto .\object_detection\protos\bipartite_matcher.proto .\object_detection\protos\box_coder.proto .\object_detection\protos\box_predictor.proto .\object_detection\protos\eval.proto .\object_detection\protos\faster_rcnn.proto .\object_detection\protos\faster_rcnn_box_coder.proto .\object_detection\protos\grid_anchor_generator.proto .\object_detection\protos\hyperparams.proto .\object_detection\protos\image_resizer.proto .\object_detection\protos\input_reader.proto .\object_detection\protos\losses.proto .\object_detection\protos\matcher.proto .\object_detection\protos\mean_stddev_box_coder.proto .\object_detection\protos\model.proto .\object_detection\protos\optimizer.proto .\object_detection\protos\pipeline.proto .\object_detection\protos\post_processing.proto .\object_detection\protos\preprocessor.proto .\object_detection\protos\region_similarity_calculator.proto .\object_detection\protos\square_box_coder.proto .\object_detection\protos\ssd.proto .\object_detection\protos\ssd_anchor_generator.proto .\object_detection\protos\string_int_label_map.proto .\object_detection\protos\train.proto .\object_detection\protos\keypoint_box_coder.proto .\object_detection\protos\multiscale_anchor_generator.proto .\object_detection\protos\graph_rewriter.proto)
108 |
109 | This creates a name_pb2.py file from every name.proto file in the \object_detection\protos folder.
110 | (Note: TensorFlow occassionally adds new .proto files to the \protos folder. If you get an error saying ImportError: cannot import name 'something_something_pb2', you may need to update the protoc command to include the new .proto files.)
111 | Finally, run the following commands from the C:\tensorflow1\models\research directory:
112 |
113 | (tensorflow1) C:\tensorflow1\models\research> python setup.py build
114 |
115 | (tensorflow1) C:\tensorflow1\models\research> python setup.py install
116 |
117 | #### 2g. Test TensorFlow setup to verify it works
118 |
119 | The TensorFlow Object Detection API is now all set up to use pre-trained models for object detection, or to train a new one. You can test it out and verify your installation is working by launching the object_detection_tutorial.ipynb script with Jupyter. From the \object_detection directory, issue this command:
120 |
121 | (tensorflow1)C:\tensorflow1\models\research\object_detection>juprter notebook object_detection_tutorial.ipynb
122 |
123 | This opens the script in your default web browser and allows you to step through the code one section at a time. You can step through each section by clicking the “Run” button in the upper toolbar. The section is done running when the “In [* ]” text next to the section populates with a number.
124 | (Note: part of the script downloads the ssd_mobilenet_v1 model from GitHub, which is about 74MB. This means it will take some time to complete the section, so be patient.)
125 | Once you have stepped all the way through the script, you should see two labelled images at the bottom section the page. If you see this, then everything is working properly! If not, the bottom section will report any errors encountered. See the Appendix for a list of errors I encountered while setting this up.
126 |
127 |
128 |
129 | ### 3. Gather and Label Images
130 |
131 | Now that the TensorFlow Object Detection API is all set up and ready to go, we need to provide the images it will use to train a new detection classifier.
132 |
133 |
134 | #### 3a. Collect Images
135 |
136 | TensorFlow needs hundreds of images of an object to train a good detection classifier. To train a robust classifier, the training images should have random plants in the image along with the desired plants and should have a variety of backgrounds and lighting conditions. There should be some images where the desired plant is partially obscured, overlapped with something else, or only halfway in the picture.
137 |
138 |
139 |
140 | For my plant Detection classifier, I have 5 different plants I want to detect (ivy tree, garden geranium, common guava, sago cycad, painters palette). I used my cell phone (Redmi note 4) to take about 80 pictures of each plant on its own, with various other non-desired objects in the pictures. And also, some images with overlapped leaves so that I can detect the plants effectively. Totally I took around 480 images of 5 different plants each having approx. 80 images.
141 | Make sure the images aren’t too large. They should be less than 200KB each, and their resolution shouldn’t be more than 720x1280. The larger the images are, the longer it will take to train the classifier. You can use the resizer.py script in this repository to reduce the size of the images.
142 |
143 | After you have all the pictures you need, move 20% of them to the \object_detection\images\test directory, and 80% of them to the \object_detection\images\train directory. Make sure there are a variety of pictures in both the \test and \train directories.
144 |
145 | #### 3b. Label Images
146 |
147 | Here comes the fun part! With all the pictures gathered, it’s time to label the desired objects in every picture. LabelImg is a great tool for labeling images, and its GitHub page has very clear instructions on how to install and use it.
148 |
149 | LabelImg download link (https://tzutalin.github.io/labelImg/)
150 |
151 | Download and install LabelImg, point it to your \images\train directory, and then draw a box around each plant leaf in each image. Repeat the process for all the images in the \images\test directory. This will take a while!
152 | LabelImg saves a .xml file containing the label data for each image. These .xml files will be used to generate TFRecords, which are one of the inputs to the TensorFlow trainer. Once you have labeled and saved each image, there will be one .xml file for each image in the \test and \train directories.
153 |
154 |
155 | ### 4. Generate Training Data
156 |
157 | First, the image .xml data will be used to create .csv files containing all the data for the train and test images. From the \object_detection folder, issue the following command in the Anaconda command prompt:
158 |
159 | (tensorflow1) C:\tensorflow1\models\research\object_detection> python xml_to_csv.py
160 |
161 | This creates a train_labels.csv and test_labels.csv file in the \object_detection\images folder.
162 |
163 | Next, open the generate_tfrecord.py file in a text editor. Replace the label map starting at line 31 with your own label map, where each object is assigned an ID number. This same number assignment will be used when configuring the labelmap.pbtxt file in Step 5b.
164 | For example, say you are training a classifier to detect basketballs, shirts, and shoes. You will replace the following code in generate_record.py:
165 |
166 | #To-do this replace with labelmap
167 | ~~~
168 | def class_text_to_int(row_label):
169 | if row_label == 'common guava':
170 | return 1
171 | elif row_label == 'ivy tree':
172 | return 2
173 | elif row_label == 'garden geranium':
174 | return 3
175 | elif row_label == 'painters palette':
176 | return 4
177 | elif row_label == 'sago cycad':
178 | return 5
179 | else:
180 | None
181 | ~~~
182 |
183 | Then, generate the TFRecord files by issuing these commands from the \object_detection folder:
184 |
185 | (python generate_tfrecord.py --csv_input=images\train_labels.csv --image_dir=images\train --output_path=train.record)
186 |
187 | (python generate_tfrecord.py --csv_input=images\test_labels.csv --image_dir=images\test --output_path=test.record)
188 |
189 | These generate a train.record and a test.record file in \object_detection. These will be used to train the new object detection classifier.
190 |
191 | ### 5. Create Label Map and Configure Training
192 |
193 | The last thing to do before training is to create a label map and edit the training configuration file.
194 |
195 | #### 5a. Label map
196 |
197 | The label map tells the trainer what each plant is by defining a mapping of class names to class ID numbers. Use a text editor to create a new file and save it as labelmap.pbtxt in the C:\tensorflow1\models\research\object_detection\training folder. (Make sure the file type is. pbtxt, not .txt!) In the text editor, copy or type in the label map in the format below (the example below is the label map for my Plant Detector):
198 |
199 | ~~~
200 |
201 | item {
202 | id: 1
203 | name: 'common guava'
204 | }
205 | item {
206 | id: 2
207 | name: 'ivy tree'
208 | }
209 | item {
210 | id: 3
211 | name: 'garden geranium'
212 | }
213 | item {
214 | id: 4
215 | name: 'painters palette'
216 | }
217 | item {
218 | id: 5
219 | name: 'sago cycad'
220 | }
221 |
222 | ~~~
223 | The label map ID numbers should be the same as what is defined in the generate_tfrecord.py file.
224 |
225 | #### 5b. Configure training
226 |
227 | Finally, the object detection training pipeline must be configured. It defines which model and what parameters will be used for training. This is the last step before running training!
228 | Navigate to C:\tensorflow1\models\research\object_detection\samples\configs and copy the ssd_mobilenet_v1_pets.config file into the \object_detection\training directory. Then, open the file with a text editor. There are several changes to make to the .config file, mainly changing the number of classes and examples, and adding the file paths to the training data.
229 |
230 | Make the following changes to the faster_rcnn_inception_v2_pets.config file. Note: The paths must be entered with single forward slashes (NOT backslashes), or TensorFlow will give a file path error when trying to train the model! Also, the paths must be in double quotation marks ( " ), not single quotation marks ( ' ).
231 | Line 9. Change num_classes to the number of different objects you want the classifier to detect it would be num_classes : 5 (because 5 different plants)
232 |
233 | Line 110. Change fine_tune_checkpoint to:
234 | fine_tune_checkpoint:"C:/tensorflow1/models/research/object_detection ssd_mobilenet_v1_coco_2017_11_17 /model.ckpt"
235 |
236 | Lines 126 and 128. In the train_input_reader section, change input_path and label_map_path to:
237 |
238 | input_path : "C:/tensorflow1/models/research/object_detection/train.record"
239 |
240 | label_map_path: "C:/tensorflow1/models/research/object_detection/training/labelmap.pbtxt"
241 |
242 | Line 132. Change num_examples to the number of images you have in the \images\test directory.
243 |
244 | Lines 140 and 142. In the eval_input_reader section, change input_path and label_map_path to:
245 |
246 | input_path: "C:/tensorflow1/models/research/object_detection/test.record"
247 |
248 | label_map_path: "C:/tensorflow1/models/research/object_detection/training/labelmap.pbtxt"
249 |
250 | Save the file after the changes have been made. That’s it! The training job is all configured and ready to go!
251 |
252 | ### 6. Run the Training
253 |
254 | Here we go! From the \object_detection directory, issue the following command to begin training:
255 |
256 | (python train.py --logtostderr --train_dir=training/ --pipeline_config_path=training/ ssd_mobilenet_v1_pets.config)
257 |
258 | If everything has been set up correctly, TensorFlow will initialize the training. The initialization can take up to 30 seconds before the actual training begins.
259 |
260 | Each step of training reports the loss. It will start high and get lower and lower as training progresses. For my training on the Faster-RCNN-Inception-V2 model, it started at about 3.0 and quickly dropped below 0.8. I recommend allowing your model to train until the loss consistently drops below 0.05, which will take about 40,000 steps, or about 2 hours (depending on how powerful your CPU and GPU are). Note: The loss numbers will be different if a different model is used. MobileNet-SSD starts with a loss of about 20 and should be trained until the loss is consistently under 2.
261 | You can view the progress of the training job by using TensorBoard. To do this, open a new instance of Anaconda Prompt, activate the tensorflow1 virtual environment, change to the C:\tensorflow1\models\research\object_detection directory, and issue the following command:
262 |
263 | (tensorflow1) C:\tensorflow1\models\research\object_detection>tensorboard --logdir=training
264 |
265 | This will create a webpage on your local machine at YourPCName:6006, which can be viewed through a web browser. The TensorBoard page provides information and graphs that show how the training is progressing. One important graph is the Loss graph, which shows the overall loss of the classifier over time.
266 | The training routine periodically saves checkpoints about every five minutes. You can terminate the training by pressing Ctrl+C while in the command prompt window. I typically wait until just after a checkpoint has been saved to terminate the training. You can terminate training and start it later, and it will restart from the last saved checkpoint. The checkpoint at the highest number of steps will be used to generate the frozen inference graph.
267 |
268 |
269 | ### 7. Export Inference Graph
270 |
271 | Now that training is complete, the last step is to generate the frozen inference graph (. pb file). From the \object_detection folder, issue the following command, where “XXXX” in “model.ckpt-XXXX” should be replaced with the highest-numbered .ckpt file in the training folder:
272 |
273 | (python export_inference_graph.py --input_type image_tensor --pipeline_config_path training/faster_rcnn_inception_v2_pets.config --trained_checkpoint_prefix training/model.ckpt-XXXX --output_directory inference_graph)
274 |
275 | This creates a frozen_inference_graph.pb file in the \object_detection\inference_graph folder. The .pb file contains the object detection classifier.
276 |
277 |
278 | ### 8. Use Your Newly Trained Object Detection Classifier!
279 |
280 | The Plant detector is all ready to go! I’ve written Python scripts to test it out on an image, video, or webcam feed.
281 | Before running the Python scripts, you need to modify the NUM_CLASSES variable in the script to equal the number of classes you want to detect. (For my Plant Detector, there are 5 plants I want to detect, so NUM_CLASSES = 5.)
282 |
283 | To test your object detector, move a picture of the object or objects into the \object_detection folder, and change the IMAGE_NAME variable in the Object_detection_image.py to match the file name of the picture. Alternatively, you can use a video of the objects (using Object_detection_video.py), or just plug in a USB webcam and point it at the objects (using Object_detection_webcam.py).
284 |
285 | To run any of the scripts, type “idle” in the Anaconda Command Prompt (with the “tensorflow1” virtual environment activated) and press ENTER. This will open IDLE, and from there, you can open any of the scripts and run them.
286 |
287 | If everything is working properly, the object detector will initialize for about 10 seconds and then display a window showing any objects it’s detected in the image!
288 |
289 | If you encounter errors, please check out the Appendix: it has a list of errors that I ran in to while setting up my object detection classifier. You can also trying Googling the error. There is usually useful information on Stack Exchange or in TensorFlow’s Issues on GitHub.
290 |
291 | __link for Plant Identification in Real Time Video__ = (https://drive.google.com/open?id=1nc7SAEPdD5AvG17GJfKLj-O80X1QlmZO)
292 |
293 |
294 |
295 | ### Appendix: Common Errors
296 |
297 | It appears that the TensorFlow Object Detection API was developed on a Linux-based operating system, and most of the directions given by the documentation are for a Linux OS. Trying to get a Linux-developed software library to work on Windows can be challenging. There are many little snags that I ran in to while trying to set up tensorflow-gpu to train an object detection classifier on Windows 10. This Appendix is a list of errors I ran in to, and their resolutions.
298 |
299 | __1. ModuleNotFoundError: No module named 'deployment'__
300 |
301 | This error occurs when you try to run object_detection_tutorial.ipynb or train.py and you don’t have the PATH and PYTHONPATH environment variables set up correctly. Exit the virtual environment
302 | by closing and re-opening the Anaconda Prompt window. Then, issue “activate tensorflow1” to re-enter the environment, and then issue the commands given in Step 2e.
303 | You can use “echo %PATH%” and “echo %PYTHONPATH%” to check the environment variables and make sure they are set up correctly.
304 | Also, make sure you have run these commands from the \models\research directory:
305 |
306 | setup.py build
307 | setup.py install
308 |
309 | __2. ImportError: cannot import name 'preprocessor_pb2'__
310 |
311 | ImportError: cannot import name 'string_int_label_map_pb2'
312 | (or similar errors with other pb2 files)
313 | This occurs when the protobuf files (in this case, preprocessor.proto) have not been compiled. Re-run the protoc command given in Step 2f. Check the \object_detection\protos folder to make sure there is a name_pb2.py file for every name.proto file.
314 |
315 | __3. object_detection/protos/.proto: No such file or directory__
316 |
317 | This occurs when you try to run the
318 | “protoc object_detection/protos/*.proto --python_out=.”
319 | command given on the TensorFlow Object Detection API installation page. Sorry, it doesn’t work on Windows! Copy and paste the full command given in Step 2f instead. There’s probably a more graceful way to do it, but I don’t know what it is.
320 |
321 | __4. Unsuccessful TensorSliceReader constructor:Failed to get "file path" … The filename, directory name, or volume label syntax is incorrect.__
322 |
323 | This error occurs when the filepaths in the training configuration file (faster_rcnn_inception_v2_pets.config or similar) have not been entered with backslashes instead of forward slashes. Open the .config file and make sure all file paths are given in the following format: “C:/path/to/model.file”
324 |
325 |
--------------------------------------------------------------------------------
/generate_tfrecord.py:
--------------------------------------------------------------------------------
1 | """
2 | Usage:
3 | # From tensorflow/models/
4 | # Create train data:
5 | python generate_tfrecord.py --csv_input=images/train_labels.csv --image_dir=images/train --output_path=train.record
6 |
7 | # Create test data:
8 | python generate_tfrecord.py --csv_input=images/test_labels.csv --image_dir=images/test --output_path=test.record
9 | """
10 | from __future__ import division
11 | from __future__ import print_function
12 | from __future__ import absolute_import
13 |
14 | import os
15 | import io
16 | import pandas as pd
17 | import tensorflow as tf
18 |
19 | from PIL import Image
20 | from object_detection.utils import dataset_util
21 | from collections import namedtuple, OrderedDict
22 |
23 | flags = tf.app.flags
24 | flags.DEFINE_string('csv_input', '', 'Path to the CSV input')
25 | flags.DEFINE_string('image_dir', '', 'Path to the image directory')
26 | flags.DEFINE_string('output_path', '', 'Path to output TFRecord')
27 | FLAGS = flags.FLAGS
28 |
29 |
30 | # TO-DO replace this with label map
31 | def class_text_to_int(row_label):
32 | if row_label == 'common guava':
33 | return 1
34 | elif row_label == 'ivy tree':
35 | return 2
36 | elif row_label == 'garden geranium':
37 | return 3
38 | elif row_label == 'painters palette':
39 | return 4
40 | elif row_label == 'ti':
41 | return 5
42 | elif row_label == 'callistemon hybridus':
43 | return 6
44 | elif row_label == 'sago cycad':
45 | return 7
46 | else:
47 | None
48 |
49 |
50 | def split(df, group):
51 | data = namedtuple('data', ['filename', 'object'])
52 | gb = df.groupby(group)
53 | return [data(filename, gb.get_group(x)) for filename, x in zip(gb.groups.keys(), gb.groups)]
54 |
55 |
56 | def create_tf_example(group, path):
57 | with tf.gfile.GFile(os.path.join(path, '{}'.format(group.filename)), 'rb') as fid:
58 | encoded_jpg = fid.read()
59 | encoded_jpg_io = io.BytesIO(encoded_jpg)
60 | image = Image.open(encoded_jpg_io)
61 | width, height = image.size
62 |
63 | filename = group.filename.encode('utf8')
64 | image_format = b'jpg'
65 | xmins = []
66 | xmaxs = []
67 | ymins = []
68 | ymaxs = []
69 | classes_text = []
70 | classes = []
71 |
72 | for index, row in group.object.iterrows():
73 | xmins.append(row['xmin'] / width)
74 | xmaxs.append(row['xmax'] / width)
75 | ymins.append(row['ymin'] / height)
76 | ymaxs.append(row['ymax'] / height)
77 | classes_text.append(row['class'].encode('utf8'))
78 | classes.append(class_text_to_int(row['class']))
79 |
80 | tf_example = tf.train.Example(features=tf.train.Features(feature={
81 | 'image/height': dataset_util.int64_feature(height),
82 | 'image/width': dataset_util.int64_feature(width),
83 | 'image/filename': dataset_util.bytes_feature(filename),
84 | 'image/source_id': dataset_util.bytes_feature(filename),
85 | 'image/encoded': dataset_util.bytes_feature(encoded_jpg),
86 | 'image/format': dataset_util.bytes_feature(image_format),
87 | 'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),
88 | 'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),
89 | 'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),
90 | 'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),
91 | 'image/object/class/text': dataset_util.bytes_list_feature(classes_text),
92 | 'image/object/class/label': dataset_util.int64_list_feature(classes),
93 | }))
94 | return tf_example
95 |
96 |
97 | def main(_):
98 | writer = tf.python_io.TFRecordWriter(FLAGS.output_path)
99 | path = os.path.join(os.getcwd(), FLAGS.image_dir)
100 | examples = pd.read_csv(FLAGS.csv_input)
101 | grouped = split(examples, 'filename')
102 | for group in grouped:
103 | tf_example = create_tf_example(group, path)
104 | writer.write(tf_example.SerializeToString())
105 |
106 | writer.close()
107 | output_path = os.path.join(os.getcwd(), FLAGS.output_path)
108 | print('Successfully created the TFRecords: {}'.format(output_path))
109 |
110 |
111 | if __name__ == '__main__':
112 | tf.app.run()
113 |
--------------------------------------------------------------------------------
/inference_graph/checkpoint:
--------------------------------------------------------------------------------
1 | model_checkpoint_path: "model.ckpt"
2 | all_model_checkpoint_paths: "model.ckpt"
3 |
--------------------------------------------------------------------------------
/inference_graph/frozen_inference_graph.pb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KundanBalse/Plant-Detection-Using-TensorFlow/a4b1d6e0195f4e2f633949facecfbef4faafee29/inference_graph/frozen_inference_graph.pb
--------------------------------------------------------------------------------
/inference_graph/model.ckpt.data-00000-of-00001:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KundanBalse/Plant-Detection-Using-TensorFlow/a4b1d6e0195f4e2f633949facecfbef4faafee29/inference_graph/model.ckpt.data-00000-of-00001
--------------------------------------------------------------------------------
/inference_graph/model.ckpt.index:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KundanBalse/Plant-Detection-Using-TensorFlow/a4b1d6e0195f4e2f633949facecfbef4faafee29/inference_graph/model.ckpt.index
--------------------------------------------------------------------------------
/inference_graph/model.ckpt.meta:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KundanBalse/Plant-Detection-Using-TensorFlow/a4b1d6e0195f4e2f633949facecfbef4faafee29/inference_graph/model.ckpt.meta
--------------------------------------------------------------------------------
/inference_graph/pipeline.config:
--------------------------------------------------------------------------------
1 | model {
2 | ssd {
3 | num_classes: 37
4 | image_resizer {
5 | fixed_shape_resizer {
6 | height: 300
7 | width: 300
8 | }
9 | }
10 | feature_extractor {
11 | type: "ssd_mobilenet_v1"
12 | depth_multiplier: 1.0
13 | min_depth: 16
14 | conv_hyperparams {
15 | regularizer {
16 | l2_regularizer {
17 | weight: 3.9999998989515007e-05
18 | }
19 | }
20 | initializer {
21 | truncated_normal_initializer {
22 | mean: 0.0
23 | stddev: 0.029999999329447746
24 | }
25 | }
26 | activation: RELU_6
27 | batch_norm {
28 | decay: 0.9997000098228455
29 | center: true
30 | scale: true
31 | epsilon: 0.0010000000474974513
32 | train: true
33 | }
34 | }
35 | }
36 | box_coder {
37 | faster_rcnn_box_coder {
38 | y_scale: 10.0
39 | x_scale: 10.0
40 | height_scale: 5.0
41 | width_scale: 5.0
42 | }
43 | }
44 | matcher {
45 | argmax_matcher {
46 | matched_threshold: 0.5
47 | unmatched_threshold: 0.5
48 | ignore_thresholds: false
49 | negatives_lower_than_unmatched: true
50 | force_match_for_each_row: true
51 | }
52 | }
53 | similarity_calculator {
54 | iou_similarity {
55 | }
56 | }
57 | box_predictor {
58 | convolutional_box_predictor {
59 | conv_hyperparams {
60 | regularizer {
61 | l2_regularizer {
62 | weight: 3.9999998989515007e-05
63 | }
64 | }
65 | initializer {
66 | truncated_normal_initializer {
67 | mean: 0.0
68 | stddev: 0.029999999329447746
69 | }
70 | }
71 | activation: RELU_6
72 | batch_norm {
73 | decay: 0.9997000098228455
74 | center: true
75 | scale: true
76 | epsilon: 0.0010000000474974513
77 | train: true
78 | }
79 | }
80 | min_depth: 0
81 | max_depth: 0
82 | num_layers_before_predictor: 0
83 | use_dropout: false
84 | dropout_keep_probability: 0.800000011920929
85 | kernel_size: 1
86 | box_code_size: 4
87 | apply_sigmoid_to_scores: false
88 | }
89 | }
90 | anchor_generator {
91 | ssd_anchor_generator {
92 | num_layers: 6
93 | min_scale: 0.20000000298023224
94 | max_scale: 0.949999988079071
95 | aspect_ratios: 1.0
96 | aspect_ratios: 2.0
97 | aspect_ratios: 0.5
98 | aspect_ratios: 3.0
99 | aspect_ratios: 0.33329999446868896
100 | }
101 | }
102 | post_processing {
103 | batch_non_max_suppression {
104 | score_threshold: 9.99999993922529e-09
105 | iou_threshold: 0.6000000238418579
106 | max_detections_per_class: 100
107 | max_total_detections: 100
108 | }
109 | score_converter: SIGMOID
110 | }
111 | normalize_loss_by_num_matches: true
112 | loss {
113 | localization_loss {
114 | weighted_smooth_l1 {
115 | }
116 | }
117 | classification_loss {
118 | weighted_sigmoid {
119 | }
120 | }
121 | hard_example_miner {
122 | num_hard_examples: 3000
123 | iou_threshold: 0.9900000095367432
124 | loss_type: CLASSIFICATION
125 | max_negatives_per_positive: 3
126 | min_negatives_per_image: 0
127 | }
128 | classification_weight: 1.0
129 | localization_weight: 1.0
130 | }
131 | }
132 | }
133 | train_config {
134 | batch_size: 24
135 | data_augmentation_options {
136 | random_horizontal_flip {
137 | }
138 | }
139 | data_augmentation_options {
140 | ssd_random_crop {
141 | }
142 | }
143 | optimizer {
144 | rms_prop_optimizer {
145 | learning_rate {
146 | exponential_decay_learning_rate {
147 | initial_learning_rate: 0.004000000189989805
148 | decay_steps: 800720
149 | decay_factor: 0.949999988079071
150 | }
151 | }
152 | momentum_optimizer_value: 0.8999999761581421
153 | decay: 0.8999999761581421
154 | epsilon: 1.0
155 | }
156 | }
157 | fine_tune_checkpoint: "C:/tensorflow1/models/research/object_detection/ssd_mobilenet_v1_coco_2017_11_17/model.ckpt"
158 | from_detection_checkpoint: true
159 | num_steps: 200000
160 | }
161 | train_input_reader {
162 | label_map_path: "C:/tensorflow1/models/research/object_detection/training/labelmap.pbtxt"
163 | tf_record_input_reader {
164 | input_path: "C:/tensorflow1/models/research/object_detection/train.record"
165 | }
166 | }
167 | eval_config {
168 | num_examples: 124
169 | max_evals: 10
170 | use_moving_averages: false
171 | }
172 | eval_input_reader {
173 | label_map_path: "C:/tensorflow1/models/research/object_detection/training/labelmap.pbtxt"
174 | shuffle: false
175 | num_readers: 1
176 | tf_record_input_reader {
177 | input_path: "C:/tensorflow1/models/research/object_detection/test.record"
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/inference_graph/saved_model/saved_model.pb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KundanBalse/Plant-Detection-Using-TensorFlow/a4b1d6e0195f4e2f633949facecfbef4faafee29/inference_graph/saved_model/saved_model.pb
--------------------------------------------------------------------------------
/training/labelmap.pbtxt:
--------------------------------------------------------------------------------
1 | item {
2 | id: 1
3 | name: 'common guava'
4 | }
5 |
6 | item {
7 | id: 2
8 | name: 'ivy tree'
9 | }
10 |
11 | item {
12 | id: 3
13 | name: 'garden geranium'
14 | }
15 |
16 | item {
17 | id: 4
18 | name: 'painters palette'
19 | }
20 |
21 | item {
22 | id: 5
23 | name: 'ti'
24 | }
25 |
26 | item {
27 | id: 6
28 | name: 'callistemon hybridus'
29 | }
30 |
31 | item {
32 | id: 7
33 | name: 'sago cycad'
34 | }
35 |
--------------------------------------------------------------------------------
/training/ssd_mobilenet_v1_pets.config:
--------------------------------------------------------------------------------
1 | # SSD with Mobilenet v1, configured for Oxford-IIIT Pets Dataset.
2 | # Users should configure the fine_tune_checkpoint field in the train config as
3 | # well as the label_map_path and input_path fields in the train_input_reader and
4 | # eval_input_reader. Search for "PATH_TO_BE_CONFIGURED" to find the fields that
5 | # should be configured.
6 |
7 | model {
8 | ssd {
9 | num_classes: 37
10 | box_coder {
11 | faster_rcnn_box_coder {
12 | y_scale: 10.0
13 | x_scale: 10.0
14 | height_scale: 5.0
15 | width_scale: 5.0
16 | }
17 | }
18 | matcher {
19 | argmax_matcher {
20 | matched_threshold: 0.5
21 | unmatched_threshold: 0.5
22 | ignore_thresholds: false
23 | negatives_lower_than_unmatched: true
24 | force_match_for_each_row: true
25 | }
26 | }
27 | similarity_calculator {
28 | iou_similarity {
29 | }
30 | }
31 | anchor_generator {
32 | ssd_anchor_generator {
33 | num_layers: 6
34 | min_scale: 0.2
35 | max_scale: 0.95
36 | aspect_ratios: 1.0
37 | aspect_ratios: 2.0
38 | aspect_ratios: 0.5
39 | aspect_ratios: 3.0
40 | aspect_ratios: 0.3333
41 | }
42 | }
43 | image_resizer {
44 | fixed_shape_resizer {
45 | height: 300
46 | width: 300
47 | }
48 | }
49 | box_predictor {
50 | convolutional_box_predictor {
51 | min_depth: 0
52 | max_depth: 0
53 | num_layers_before_predictor: 0
54 | use_dropout: false
55 | dropout_keep_probability: 0.8
56 | kernel_size: 1
57 | box_code_size: 4
58 | apply_sigmoid_to_scores: false
59 | conv_hyperparams {
60 | activation: RELU_6,
61 | regularizer {
62 | l2_regularizer {
63 | weight: 0.00004
64 | }
65 | }
66 | initializer {
67 | truncated_normal_initializer {
68 | stddev: 0.03
69 | mean: 0.0
70 | }
71 | }
72 | batch_norm {
73 | train: true,
74 | scale: true,
75 | center: true,
76 | decay: 0.9997,
77 | epsilon: 0.001,
78 | }
79 | }
80 | }
81 | }
82 | feature_extractor {
83 | type: 'ssd_mobilenet_v1'
84 | min_depth: 16
85 | depth_multiplier: 1.0
86 | conv_hyperparams {
87 | activation: RELU_6,
88 | regularizer {
89 | l2_regularizer {
90 | weight: 0.00004
91 | }
92 | }
93 | initializer {
94 | truncated_normal_initializer {
95 | stddev: 0.03
96 | mean: 0.0
97 | }
98 | }
99 | batch_norm {
100 | train: true,
101 | scale: true,
102 | center: true,
103 | decay: 0.9997,
104 | epsilon: 0.001,
105 | }
106 | }
107 | }
108 | loss {
109 | classification_loss {
110 | weighted_sigmoid {
111 | }
112 | }
113 | localization_loss {
114 | weighted_smooth_l1 {
115 | }
116 | }
117 | hard_example_miner {
118 | num_hard_examples: 3000
119 | iou_threshold: 0.99
120 | loss_type: CLASSIFICATION
121 | max_negatives_per_positive: 3
122 | min_negatives_per_image: 0
123 | }
124 | classification_weight: 1.0
125 | localization_weight: 1.0
126 | }
127 | normalize_loss_by_num_matches: true
128 | post_processing {
129 | batch_non_max_suppression {
130 | score_threshold: 1e-8
131 | iou_threshold: 0.6
132 | max_detections_per_class: 100
133 | max_total_detections: 100
134 | }
135 | score_converter: SIGMOID
136 | }
137 | }
138 | }
139 |
140 | train_config: {
141 | batch_size: 24
142 | optimizer {
143 | rms_prop_optimizer: {
144 | learning_rate: {
145 | exponential_decay_learning_rate {
146 | initial_learning_rate: 0.004
147 | decay_steps: 800720
148 | decay_factor: 0.95
149 | }
150 | }
151 | momentum_optimizer_value: 0.9
152 | decay: 0.9
153 | epsilon: 1.0
154 | }
155 | }
156 | fine_tune_checkpoint: "C:/tensorflow1/models/research/object_detection/ssd_mobilenet_v1_coco_2017_11_17/model.ckpt"
157 | from_detection_checkpoint: true
158 | # Note: The below line limits the training process to 200K steps, which we
159 | # empirically found to be sufficient enough to train the pets dataset. This
160 | # effectively bypasses the learning rate schedule (the learning rate will
161 | # never decay). Remove the below line to train indefinitely.
162 | num_steps: 200000
163 | data_augmentation_options {
164 | random_horizontal_flip {
165 | }
166 | }
167 | data_augmentation_options {
168 | ssd_random_crop {
169 | }
170 | }
171 | }
172 |
173 | train_input_reader: {
174 | tf_record_input_reader {
175 | input_path: "C:/tensorflow1/models/research/object_detection/train.record"
176 | }
177 | label_map_path: "C:/tensorflow1/models/research/object_detection/training/labelmap.pbtxt"
178 | }
179 |
180 | eval_config: {
181 | num_examples: 124
182 | # Note: The below line limits the evaluation process to 10 evaluations.
183 | # Remove the below line to evaluate indefinitely.
184 | max_evals: 10
185 | }
186 |
187 | eval_input_reader: {
188 | tf_record_input_reader {
189 | input_path: "C:/tensorflow1/models/research/object_detection/test.record"
190 | }
191 | label_map_path: "C:/tensorflow1/models/research/object_detection/training/labelmap.pbtxt"
192 | shuffle: false
193 | num_readers: 1
194 | }
195 |
--------------------------------------------------------------------------------
/xml_to_csv.py:
--------------------------------------------------------------------------------
1 | import os
2 | import glob
3 | import pandas as pd
4 | import xml.etree.ElementTree as ET
5 |
6 |
7 | def xml_to_csv(path):
8 | xml_list = []
9 | for xml_file in glob.glob(path + '/*.xml'):
10 | tree = ET.parse(xml_file)
11 | root = tree.getroot()
12 | for member in root.findall('object'):
13 | value = (root.find('filename').text,
14 | int(root.find('size')[0].text),
15 | int(root.find('size')[1].text),
16 | member[0].text,
17 | int(member[4][0].text),
18 | int(member[4][1].text),
19 | int(member[4][2].text),
20 | int(member[4][3].text)
21 | )
22 | xml_list.append(value)
23 | column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
24 | xml_df = pd.DataFrame(xml_list, columns=column_name)
25 | return xml_df
26 |
27 |
28 | def main():
29 | for folder in ['train','test']:
30 | image_path = os.path.join(os.getcwd(), ('images/' + folder))
31 | xml_df = xml_to_csv(image_path)
32 | xml_df.to_csv(('images/' + folder + '_labels.csv'), index=None)
33 | print('Successfully converted xml to csv.')
34 |
35 |
36 | main()
37 |
--------------------------------------------------------------------------------