# Using Tensorflow

## Step 1: Set Up Your Environment

    Install Python: Ensure you have Python installed on your system. You can download it from the official Python website.

    Create a Virtual Environment:

    bash
    ```
    python -m venv myenv
    source myenv/bin/activate  # On Windows use `myenv\Scripts\activate`
    ```
    Install Necessary Libraries:

    bash
    ```
        pip install tensorflow opencv-python-headless matplotlib
    ```    

## Step 2: Prepare Your Dataset

    Collect Images: Gather images for training. Ensure you have a diverse set of images for each object you want to detect.

    Install LabelImg:

    bash
    ```
    pip install labelImg
    ```
    Annotate Images:

        Run LabelImg:

        bash

            labelImg

            Open your image directory in LabelImg.
            Annotate each image by drawing bounding boxes around objects and label them appropriately.
            Save the annotations in Pascal VOC format (XML files).

## Step 3: Organize Your Dataset

    Directory Structure:

    markdown

    dataset/
        images/
            img1.jpg
            img2.jpg
            ...
        annotations/
            img1.xml
            img2.xml
            ...

## Step 4: Convert Annotations to TFRecord Format

    Clone TensorFlow Models Repository:

    bash

git clone https://github.com/tensorflow/models.git
cd models/research

Install the Object Detection API:

bash

pip install .

Prepare the Scripts for Conversion:

    Create a script to generate TFRecord files from the XML annotations. Here's an example script (generate_tfrecord.py):

    python
    ```
        import os
        import glob
        import pandas as pd
        import tensorflow as tf
        from object_detection.utils import dataset_util
        from collections import namedtuple, OrderedDict
        from PIL import Image
        import io
        import xml.etree.ElementTree as ET

        def xml_to_csv(path):
            xml_list = []
            for xml_file in glob.glob(path + '/*.xml'):
                tree = ET.parse(xml_file)
                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)
                            )
                    xml_list.append(value)
            column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
            xml_df = pd.DataFrame(xml_list, columns=column_name)
            return xml_df

        def class_text_to_int(row_label):
            if row_label == 'object':  # Change this line to match your labels
                return 1
            else:
                None

        def split(df, group):
            data = namedtuple('data', ['filename', 'object'])
            gb = df.groupby(group)
            return [data(filename, gb.get_group(x)) for filename, x in zip(gb.groups.keys(), gb.groups)]

        def create_tf_example(group, path):
            with tf.io.gfile.GFile(os.path.join(path, '{}'.format(group.filename)), 'rb') as fid:
                encoded_jpg = fid.read()
            encoded_jpg_io = io.BytesIO(encoded_jpg)
            image = Image.open(encoded_jpg_io)
            width, height = image.size

            filename = group.filename.encode('utf8')
            image_format = b'jpg'
            xmins = []
            xmaxs = []
            ymins = []
            ymaxs = []
            classes_text = []
            classes = []

            for index, row in group.object.iterrows():
                xmins.append(row['xmin'] / width)
                xmaxs.append(row['xmax'] / width)
                ymins.append(row['ymin'] / height)
                ymaxs.append(row['ymax'] / height)
                classes_text.append(row['class'].encode('utf8'))
                classes.append(class_text_to_int(row['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),
                'image/source_id': dataset_util.bytes_feature(filename),
                '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(xmins),
                'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),
                'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),
                'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),
                'image/object/class/text': dataset_util.bytes_list_feature(classes_text),
                'image/object/class/label': dataset_util.int64_list_feature(classes),
            }))
            return tf_example

        def main(_):
            for directory in ['train', 'test']:
                image_path = os.path.join(os.getcwd(), 'images/{}'.format(directory))
                xml_df = xml_to_csv(image_path)
                xml_df.to_csv('annotations/{}_labels.csv'.format(directory), index=None)
                print('Successfully converted xml to csv.')

                writer = tf.io.TFRecordWriter('annotations/{}_record.record'.format(directory))
                path = os.path.join(os.getcwd(), 'images/{}'.format(directory))
                examples = xml_df
                grouped = split(examples, 'filename')
                for group in grouped:
                    tf_example = create_tf_example(group, path)
                    writer.write(tf_example.SerializeToString())

                writer.close()
                output_path = os.path.join(os.getcwd(), 'annotations/{}_record.record'.format(directory))
                print('Successfully created the TFRecord file: {}'.format(output_path))

        if __name__ == '__main__':
            tf.compat.v1.app.run()
    ```

Run the script to generate TFRecord files:

bash

        python generate_tfrecord.py

Step 5: Configure the Model

    Download a Pre-trained Model: Use a pre-trained model from the TensorFlow Model Zoo, such as SSD, YOLO, or Faster R-CNN.

    Edit the Configuration File:
        Modify the pipeline.config file to point to your dataset and adjust the parameters as needed.

Step 6: Train the Model

    Train the Model:

    bash

    python models/research/object_detection/model_main_tf2.py \
      --pipeline_config_path=path/to/pipeline.config \
      --model_dir=path/to/output_dir \
      --num_train_steps=200000 \
      --sample_1_of_n_eval_examples=1 \
      --alsologtostderr

Step 7: Export the Trained Model

    Export the Model:

    bash

    python models/research/object_detection/exporter_main_v2.py \
      --input_type=image_tensor \
      --pipeline_config_path=path/to/pipeline.config \
      --trained_checkpoint_dir=path/to/checkpoint \
      --output_directory=path/to/exported_model

Step 8: Perform Object Detection

    Load the Model and Perform Detection:

    python

    import tensorflow as tf
    import numpy as np
    import cv2

    def load_model(model_dir):
        model = tf.saved_model.load(model_dir)
        return model

    def run_inference(model, image):
        input_tensor = tf.convert_to_tensor(np.expand_dims(image, 0), dtype=tf.float32)
        detections = model(input_tensor)
        return detections

    model_dir = 'path/to/exported_model/saved_model'
    model = load_model(model_dir)

    image = cv2.imread('path/to/image.jpg')
    detections = run_inference(model, image)

    for i in range(int(detections.pop('num_detections'))):
        class_id = int(detections['detection_classes'][0][i])
        score = float(detections['detection_scores'][0][i])
        bbox = detections['detection_boxes'][0][i]
        if score > 0.5:
            h, w, _ = image.shape
            y_min, x_min, y_max, x_max = bbox
            start_point = (int(x_min * w), int(y_min * h))
            end_point = (int(x_max * w), int(y_max * h))
            cv2.rectangle(image, start_point, end_point, (0, 255, 0), 2)

    cv2.imshow('Detected Image', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Step 9: Fine-Tuning and Evaluation

    Fine-Tuning: Adjust your training parameters and dataset as needed for better accuracy.
    Evaluate: Use metrics like mAP (mean Average Precision) to evaluate your model's performance.