{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","collapsed":true,"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":false},"cell_type":"code","source":"''' Uncomment the lines if GPU or else run for cpu '''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# This cell can be commented once you checked the current CUDA version\n# CUDA: Let's check that Nvidia CUDA is already pre-installed and which version is it. In some time from now maybe you \n\n# !nvidia-smi (gpu)\n\n# !nvcc -V (gpu)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#upload the cudnn appropriate version and follow the below process to successfully install darknet with GPU\n\n# !tar -xzvf ../input/cuda-driver/cudnn-10.1-linux-x64-v7.6.5.32.tgz -C /usr/local/ (gpu)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# We're unzipping the cuDNN files from your Drive folder directly to the VM CUDA folders\n\n# !chmod a+r /usr/local/cuda/include/cudnn.h (gpu)\n\n# Now we check the version we already installed. Can comment this line on future runs\n\n# !cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2 (gpu)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Leave this code uncommented on the very first run of your notebook or if you ever need to recompile darknet again.\n# Comment this code on the future runs.\n!git clone https://github.com/AlexeyAB/darknet\n    \n''' We then locally copy all the files needed inside the darknet folder for ease of access and we need to write certain text files into the images folder'''\n\n!cp -r \"../input/global-wheat-detection/train\" darknet/train\n\n!cp -r \"../input/global-wheat-detection/test\" darknet/test\n\n!cp -r \"../input/global-wheat-detection/train.csv\" darknet/train.csv\n\n%cd darknet\n\n# Check the folder\n!ls\n\n#uncomment these lines if youre using GPU for training \n\n# !sed -i 's/GPU=0/GPU=1/' Makefile \n# !sed -i 's/CUDNN=0/CUDNN=1/' Makefile\n# !sed -i 's/OPENCV=0/OPENCV=1/' Makefile\n# !sed -i 's!/usr/local/cudnn/!/usr/local/cuda/!' Makefile\n\n#Compile Darknet\n!make\n\n#Copies the Darknet compiled version to Google drive\n# !cp ./darknet /content/drive/My\\ Drive/darknet/\n\n#check whether changes have beem made or not\n# !cat Makefile\n\n# Set execution permissions to Darknet\n!chmod +x ./darknet","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#downloading the pre-trained weights for YOLO\n# !wget https://pjreddie.com/media/files/darknet53.conv.74","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os\nimport glob\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport plotly.graph_objects as go\nfrom plotly.subplots import make_subplots\nimport seaborn as sns\nsns.set()\nimport cv2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# loading our required data\n\ntrain_wheat= pd.read_csv('train.csv') # we are loading the csv file into a dataframe for us to start extracting all the data needed to create a model\n\nprint(train_wheat.head()) #just printing out the first 5 values in our table\nprint(train_wheat.tail()) #just printing out the last 5 values in our table\n\ntrain_wheat= train_wheat.drop(['width', 'height'], axis=1)\n\nsource = train_wheat['source'].unique().tolist()\nprint(source)\nno_of_classes = len(source)\n\ntrain_images_name = train_wheat['image_id'].tolist()\ntrain_images_source = train_wheat['source'].tolist()\nnormalised_values = pd.factorize(train_images_source)[0]\n\nprint(normalised_values)\n\ntrain_images_bbox = train_wheat['bbox'].tolist()\n\nsource_list = train_wheat['source'].value_counts()\n\n\nfig = go.Figure(data=[\n    go.Pie(labels=source_list.index, values=source_list.values)\n])\n\nfig.update_layout(title='Source distribution')\nfig.show()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''making a dictionary to have the image name as key and the bbox as values'''\n\ndc= {}\nfor i, (img,bbox ,name) in enumerate(zip(train_images_name,train_images_bbox, normalised_values)):\n    # print(img, bbox, name)\n    key = img\n    if key not in dc:\n        dc[key] = []\n    dc[key].append(bbox.strip(\"[]\")+\"/\"+\"{}\".format(name))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"''' the given format in the csv file is [x,y,w,h] as we need to convert into yolo formats [centerx, centery, width , height] '''\n\nwidth = 1024\nheight = 1024\n\nfor key, values in dc.items():\n  # print(key,values)\n  for i in values:\n    bbox, obj_id = i.split('/')\n    # print(bbox)\n    x_center = (float(bbox.split(\",\")[0])+(float(bbox.split(\",\")[2])/2))/width\n    y_center = (float(bbox.split(\",\")[1])+(float(bbox.split(\",\")[3])/2))/height\n    wd = float(bbox.split(\",\")[2])/width\n    ht = float(bbox.split(\",\")[3])/height\n#     print(x_center,y_center,wd,ht)\n\n    with open(\"train/{}.txt\".format(key), \"a+\") as f:\n      f.write(f\"{obj_id} {x_center} {y_center} {wd} {ht}\")\n      f.write('\\n')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#preprocessing and data preparation needed for yolo\n\ndef check_images_labels(images, labels):\n    image =[]\n    label=[]\n\n    image_list = glob.glob(images)\n    labels_list = glob.glob(labels)\n\n    for i in image_list:\n        split_img = i.split(\"/\")[-1].split(\".\")[0]\n        image.append(split_img)\n    for i in labels_list:\n        split_label = i.split(\"/\")[-1].split(\".\")[0]\n        label.append(split_label)\n\n    def Diff(li1, li2):\n        return (list(set(li1) - set(li2))) #this is to find out the missing labels for the images that has not been annotated\n\n    diff_list = Diff(image, label)\n\n    print(diff_list)\n    \"\"\" We found out that the images and labels are not equal, by cross checking it, those images are just noise and doesnt need to be included so\n    either we make a empty text file or delete those images having no labels_list or all those images can be used as negative images\"\"\"\n\n    for i in diff_list:\n        with open (\"train/{}.txt\".format(i),\"a+\") as ff: # makes txt files for those negative images\n            ff.close()\n    print(\"made txt files for missing annotated images\")\n\n    # for i in diff_list:\n    #     os.remove(\"train/{}.jpg\".format(i))\n    # print(\"deleted image files for missing annotated images\")\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''Generating the train and text files'''\n\ndef generate_txt():\n    try:\n\n\n        dataset_path =  \"train\"\n\n        # Percentage of images to be used for the test set\n        percentage_test = 20;\n        # Create and/or truncate train.txt and test.txt\n        file_train = open('train.txt', 'w')\n        file_test = open('test.txt', 'w')\n\n        # Populate train.txt and test.txt\n        counter = 1\n        index_test = round(100 / percentage_test)\n        for pathAndFilename in glob.iglob(os.path.join(dataset_path, \"*.jpg\")):\n            title, ext = os.path.splitext(os.path.basename(pathAndFilename))\n\n            if counter == index_test+1:\n                counter = 1\n                file_test.write(dataset_path + \"/\" + title + '.jpg' + \"\\n\")\n            else:\n                file_train.write(dataset_path + \"/\" + title + '.jpg' + \"\\n\")\n                counter = counter + 1\n        print('train and text generated')\n    except Exception as e:\n        print(e)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''Function to generate trainer.data'''\n\ndef gen_trainer(no_of_classes, config):\n\n    try:\n        with open(\"trainer.data\", \"a+\") as f:\n            f.writelines('classes = {}\\n'.format(no_of_classes))\n            f.writelines('train = {}\\n'.format('train.txt'))\n            f.writelines('valid = {}\\n'.format('test.txt'))\n            f.writelines('names = {}\\n'.format('Object' + '/' + 'object.names'))\n            f.writelines('backup = {}'.format('backup/'))\n\n        print('trainer.data generated')\n\n    except Exception as e:\n        print('error while generating trainer.data')\n        print(e)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''Function to generate object.names'''\n\ndef objectnames(class_names):\n    if not os.path.exists('Object' + '/'):\n        os.mkdir('Object' + '/')\n    try:\n        for i in class_names:\n            with open ('Object' + '/'+'object.names', 'a+') as f:\n                f.writelines(i)\n                f.writelines('\\n')\n        print(\"object.names is created\")\n    except Exception as e:\n        print('error while generating Object.names')\n        print(e)\n\n''' creating the new config file needed for yolo to train '''\n\ndef config_change(No_of_Classes, batch, subdivision):\n\n    config_path='cfg/yolov3.cfg'\n\n    classes=int(No_of_Classes)\n    filters=(classes + 5)*3\n\n\n\n    with open(config_path, 'r+') as f:\n        cfg=f.readlines()\n\n    '''Batch'''\n    cfg[2]='#batch=1\\n'\n    cfg[3]='#subdivisions=1\\n'\n    cfg[4]='Training\\n'\n    cfg[5]='batch={}\\n'.format(batch)\n    cfg[6]='subdivisions={}\\n'.format(subdivision)\n\n    '''filters and classes'''\n    cfg[602]='filters={}\\n'.format(filters)\n    cfg[609]='classes={}\\n'.format(classes)\n    cfg[688]='filters={}\\n'.format(filters)\n    cfg[695]='classes={}\\n'.format(classes)\n    cfg[775]='filters={}\\n'.format(filters)\n    cfg[782]='classes={}\\n'.format(classes)\n\n\n    with open('yolov3.cfg', 'w+') as f:\n        f.writelines(cfg)\n    print('full config file changed and saved')\n    return config_path\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size=64\nsubdivisions=16\n\ncheck_images_labels(\"train/*.jpg\", \"train/*.txt\")\n\nobjectnames(source)\n\ngenerate_txt()\n\ncfg_use = config_change(no_of_classes, batch_size, subdivisions)\n\ngen_trainer(no_of_classes, cfg_use)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# !cat trainer.data\n\n# !ls train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''uncomment to start start training'''\n#start the training\n# !./darknet detector train trainer.data yolov3.cfg darknet53.conv.74 -dont_show","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''Uncomment this cell if you have trained the model '''\n# Start training at the point where the last runtime finished\n\n# !./darknet detector train trainer.data yolov3.cfg backup/yolov3_last.weights -dont_show ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''Uncomment this cell if you have trained the model '''\n# in order to check your Model's mAP \n\n# !./darknet detector map trainer.data yolov3.cfg yolov3_last.weights","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''Uncomment this cell if you have trained the model '''\n\n#in order to check your model inference after training with the test images using darknet\n\n\n\n# def imShow(path):\n#   image = cv2.imread(path)\n#   height, width = image.shape[:2]\n#   resized_image = cv2.resize(image,(3*width, 3*height), interpolation = cv2.INTER_CUBIC)\n\n#   fig = plt.gcf()\n#   fig.set_size_inches(18, 10)\n#   plt.axis(\"off\")\n#   plt.imshow(cv2.cvtColor(resized_image, cv2.COLOR_BGR2RGB))\n#   plt.show()\n    \n# import PIL\n# import PIL.Image as Image\n\n# d = 0\n\n# image_list = glob.glob(\"test/*\")\n# for images in image_list:\n#   print(images , d)\n#   commands = './darknet detector test trainer.data yolov3.cfg backup/yolov3_last.weights {} -dont_show'.format(images)\n#   os.system(commands)\n#   predicted_image = Image.open(\"predictions.jpg\")\n#   output = (\"predicted_image{}.jpg\".format(d))\n#   print(output)\n#   predicted_image.save(output)\n#   d+=1\n#   imShow(output)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# check the Mean average precision of our model\n%cd ..\n\n!cp -r \"../input/yolo-weights/yolov3_wheat.weights\" darknet/yolov3.weights #downloading my locally trained weights\n\n%cd darknet","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#over here we need to change the yolo config file for inference type and not training\n\ndef config_change_inference(No_of_Classes, batch, subdivision):\n\n    config_path='cfg/yolov3.cfg'\n\n    classes=int(No_of_Classes)\n    filters=(classes + 5)*3\n\n    filters = str(filters)\n    classes= str(No_of_Classes)\n\n\n\n    with open(config_path, 'r') as f:\n        cfg=f.readlines()\n\n\n    '''Batch'''\n    cfg[2]='# Testing\\n'\n    cfg[2]='# batch=1\\n'\n    cfg[3]='# subdivisions=1\\n'\n    cfg[4]='# Training\\n'\n    cfg[5]='batch={}\\n'.format(batch)\n    cfg[6]='subdivisions={}\\n'.format(subdivision)\n\n    '''filters and classes'''\n    cfg[602]='filters={}\\n'.format(filters)\n    cfg[609]='classes={}\\n'.format(classes)\n    cfg[688]='filters={}\\n'.format(filters)\n    cfg[695]='classes={}\\n'.format(classes)\n    cfg[775]='filters={}\\n'.format(filters)\n    cfg[782]='classes={}\\n'.format(classes)\n\n\n    with open('yolov3_inference.cfg', 'w+') as f:\n        f.writelines(cfg)\n    print('full config file changed and saved')\n    return config_path","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#make a custom inference using opencv readnet\n\nconfig_change_inference(no_of_classes, batch_size, subdivisions)\nprint('created the yolo cfg file for inference')\n\ncfg = \"yolov3_inference.cfg\"\nweights = \"yolov3.weights\"\nnet = cv2.dnn.readNet(weights,cfg)\n\nconf_threshold = 0.3\nnms_threshold = 0.4\n\nclasses = None\nf10=open(\"Object/object.names\", 'r')\nclasses = [line.strip() for line in f10.readlines()]\nf10.close()\nprint(classes)\nCOLORS =  np.random.uniform(0,255, size=(len(classes),3))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_output_layers(net):\n    layer_names = net.getLayerNames()\n    output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]\n    return output_layers\n  \n\ndef imShow(image):\n\n  height, width = image.shape[:2]\n  resized_image = cv2.resize(image,(3*width, 3*height), interpolation = cv2.INTER_CUBIC)\n\n  fig = plt.gcf()\n  fig.set_size_inches(18, 10)\n  plt.axis(\"off\")\n  plt.imshow(cv2.cvtColor(resized_image, cv2.COLOR_BGR2RGB))\n  plt.show()\n    \ndef yolo_detect(image):\n  image = cv2.imread(image)\n  obj_result=[]\n  if image is not None:\n    Width = image.shape[1]\n    Height = image.shape[0]\n    blob = cv2.dnn.blobFromImage(image,0.00392,(608,608), (0,0,0), True, crop=False)\n    net.setInput(blob)\n    outs = net.forward(get_output_layers(net))\n    \n    class_ids = []\n    confidences = []\n    boxes = []\n    \n    for out in outs:\n      for detection in out:\n        scores = detection[5:]\n        class_id = np.argmax(scores)\n        confidence = scores[class_id]\n        if confidence > conf_threshold:\n          center_x = int(detection[0]*Width)\n          center_y = int(detection[1]*Height)\n          w =int(detection[2]*Width)\n          h =int(detection[3] * Height)\n          x = center_x - w // 2\n          y = center_y - h // 2\n          class_ids.append(class_id)\n          confidences.append(float(confidence))\n          boxes.append([x, y, w, h])\n          \n          \n    indices = cv2.dnn.NMSBoxes(boxes, confidences, conf_threshold, nms_threshold)\n    for i in indices:\n      i = i[0]\n      box=boxes[i]\n      x = box[0]\n      y = box[1]\n      w = box[2]\n      h = box[3]\n      cv2.rectangle(image, (x,y), (x+w,y+h), (0,0,255), 2)\n      imShow(image)\n      obj_result.append(\"{} {} {} {} {} {}\".format(class_ids[i], round(confidences[i],2), round(x), round(y), round(w), round(h)))\n      \n  return \" \".join(obj_result)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#saving into sample submission format\n\nfinaldc={}\n\nfor i in glob.glob(\"test/*\"):\n  image_id = i.split(\"/\")[-1].split(\".\")[0]\n  results = yolo_detect(i)\n\n  key = image_id\n  if key not in finaldc:\n    finaldc[key] = []\n    finaldc[key].append(results)\n\ndf = pd.DataFrame(finaldc,columns = ['image_id','Prediction_string'])\n\n\n# df.to_csv(\"wheat_submission.csv\")\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%cd ..\ndf.to_csv(\"submission.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(df)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}