title: Saving bounding box coordinates and images based on the class type into a different folder
body: <p>I'm using OpenCV + Python to apply a deep learning model and classify objects in 8 categories (animal types) namely, cat, dog, horse, deer, bear, lizard, monkey, no object detected (when the is no object detected in the image). </p>
  
  <p>I have a folder that has images of all types of animals in it. I read all the images in one folder and then I apply the deep learning model to extract bounding box coordinates of each object in each image.</p>
  
  <p>I want to first categorize each image by putting each type of animal image in the related folder. second, save the coordinate of the bounding box of that image in the same folder. For example if the network detected cat, I want to save that image and corresponding coordinates(as a text file .text) in the cat folder and if it did not find any of those objects in the image just put it in the no object detected folder.</p>
  
  <p>My question is how can I save the original image and the bounding box coordinates of that object inside the 8 category folder?</p>
  
  <p>here is my code: </p>
  
  <pre><code>import cv2
  import numpy as np
  import os
  import glob
  import argparse
  import time
  
  img_dir="/path/imgt/"
  data_path=os.path.join(img_dir,'*g')
  files=glob.glob(data_path)
  data=[]
  
  i = 0
  for f1 in files:
       image=cv2.imread(f1)
       data.append(image)
  
       # construct the argument parse and parse the arguments
       ap = argparse.ArgumentParser()
       ap.add_argument("-i", "--image", required=True,
                       help="path to input image")
       ap.add_argument("-y", "--yolo", required=True,
                       help="base path to YOLO directory")
       ap.add_argument("-c", "--confidence", type=float, default=0.5,
                       help="minimum probability to filter weak detections")
       ap.add_argument("-t", "--threshold", type=float, default=0.3,
                       help="threshold when applyong non-maxima suppression")
       args = vars(ap.parse_args())
  
       # load the COCO class labels our YOLO model was trained on
       labelsPath = os.path.sep.join([args["yolo"], "obj.names"])
       LABELS = open(labelsPath).read().strip().split("\n")
  
       # initialize a list of colors to represent each possible class label
       np.random.seed(42)
       COLORS = np.random.randint(0, 255, size=(len(LABELS), 3),
                                  dtype="uint8")
  
       # derive the paths to the YOLO weights and model configuration
       weightsPath = os.path.sep.join([args["yolo"], "yolo-obj_last.weights"])
       configPath = os.path.sep.join([args["yolo"], "yolo-obj.cfg"])
  
       # load our YOLO object detector trained on COCO dataset (80 classes)
       print("[INFO] loading YOLO from disk...")
       net = cv2.dnn.readNetFromDarknet(configPath, weightsPath)
  
       # load our input image and grab its spatial dimensions
      # image = cv2.imread(args["image"])
       (H, W) = image.shape[:2]
  
       # determine only the *output* layer names that we need from YOLO
       ln = net.getLayerNames()
       ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]
  
       # construct a blob from the input image and then perform a forward
       # pass of the YOLO object detector, giving us our bounding boxes and
       # associated probabilities
       blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416),
                                    swapRB=True, crop=False)
       net.setInput(blob)
       start = time.time()
       layerOutputs = net.forward(ln)
       end = time.time()
  
       # show timing information on YOLO
       print("[INFO] YOLO took {:.6f} seconds".format(end - start))
  
       # initialize our lists of detected bounding boxes, confidences, and
       # class IDs, respectively
       boxes = []
       confidences = []
       classIDs = []
  
       # loop over each of the layer outputs
       for output in layerOutputs:
            # loop over each of the detections
            for detection in output:
                 # extract the class ID and confidence (i.e., probability) of
                 # the current object detection
                 scores = detection[5:]
                 classID = np.argmax(scores)
                 confidence = scores[classID]
  
                 # filter out weak predictions by ensuring the detected
                 # probability is greater than the minimum probability
                 if confidence &gt; args["confidence"]:
                      # scale the bounding box coordinates back relative to the
                      # size of the image, keeping in mind that YOLO actually
                      # returns the center (x, y)-coordinates of the bounding
                      # box followed by the boxes' width and height
                      box = detection[0:4] * np.array([W, H, W, H])
                      (centerX, centerY, width, height) = box.astype("int")
  
                      # use the center (x, y)-coordinates to derive the top and
                      # and left corner of the bounding box
                      x = int(centerX - (width / 2))
                      y = int(centerY - (height / 2))
  
                      # update our list of bounding box coordinates, confidences,
                      # and class IDs
                      boxes.append([x, y, int(width), int(height)])
                      confidences.append(float(confidence))
                      classIDs.append(classID)
  
       # apply non-maxima suppression to suppress weak, overlapping bounding
       # boxes
       idxs = cv2.dnn.NMSBoxes(boxes, confidences, args["confidence"],
                               args["threshold"])
  
       # ensure at least one detection exists
       if len(idxs) &gt; 0:
            # loop over the indexes we are keeping
            for i in idxs.flatten():
                 # extract the bounding box coordinates
                 (x, y) = (boxes[i][0], boxes[i][1])
                 (w, h) = (boxes[i][2], boxes[i][3])
  
                 # draw a bounding box rectangle and label on the image
                 color = [int(c) for c in COLORS[classIDs[i]]]
                 cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
                 text = "{}: {:.4f}".format(LABELS[classIDs[i]], confidences[i])
                 cv2.putText(image, text, (x, y - 7), cv2.FONT_HERSHEY_SIMPLEX,0.6, color, 2)
                 path = '/path/imgr/' + LABELS[classIDs[i]] + '/'
                 cv2.imwrite(os.path.join(path, 'image' + str(i) + '.jpg'), image)
                 with open(os.path.join(path, 'image' + str(i) + '.txt'), 'a+') as f:
                   f.write(str(classIDs[i]) + ' ' + str(x) + ' ' + str(y) + ' ' + str(w) + ' ' + str(h))
  </code></pre>
  
  <p><strong>how does the text file look like?</strong></p>
  
  <p><code>.txt</code> -file for each <code>.jpg</code>-image-file - in the same directory and with the same name, but with <code>.txt</code>-extension, and put to file: object number and object coordinates on this image, for each object in new line: <code>&lt;object-class&gt; &lt;x&gt; &lt;y&gt; &lt;width&gt; &lt;height&gt;</code>
  Where:
  <code>&lt;object-class&gt;</code> - integer number of object from <code>0</code> to <code>(classes-1)</code>
  <code>&lt;x&gt; &lt;y&gt; &lt;width&gt; &lt;height&gt;</code> - float values relative to width and height of image, it can be equal from <code>(0.0 to 1.0]</code>
  for example: <code>&lt;x&gt; = &lt;absolute_x&gt; / &lt;image_width&gt; or &lt;height&gt; = &lt;absolute_height&gt; / &lt;image_height&gt;</code>
  atention: <code>&lt;x&gt; &lt;y&gt;</code> - are center of rectangle (are not top-left corner)
  For example for <code>img1.jpg</code> you will be created <code>img1.txt</code> containing:</p>
  
  <pre><code>1 0.716797 0.395833 0.216406 0.147222
  0 0.687109 0.379167 0.255469 0.158333
  1 0.420312 0.395833 0.140625 0.166667
  </code></pre>