{"cells":[{"metadata":{},"cell_type":"markdown","source":"This is trained using https://github.com/ultralytics/yolov3 ","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport time\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        #print(os.path.join(dirname, filename))\n        pass\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fileTrain = 'train.txt'\nfileValid = 'valid.txt'\nwith open('kg_wheat.names','w') as fp:\n    fp.write('wheat')\n    fp.write('\\n')\nwith open('kg_wheat.data','w') as fp:\n    fp.write('classes=1')\n    fp.write('\\n')\n    fp.write(f'train=../{fileTrain}')\n    fp.write('\\n')\n    fp.write(f'valid=../{fileValid}')\n    fp.write('\\n')\n    fp.write('names=../kg_wheat.names')\n    fp.write('\\n')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nONNX_EXPORT = False\nimport torch.nn.functional as F\nimport time\nhelp_url = 'https://github.com/ultralytics/yolov3/wiki/Train-Custom-Data'\nimg_formats = ['.bmp', '.jpg', '.jpeg', '.png', '.tif', '.dng']\nvid_formats = ['.mov', '.avi', '.mp4']\nimport glob\nimport math\nimport os\nimport random\nimport pandas as pd\nimport shutil\nimport subprocess\nfrom pathlib import Path\nimport cv2\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport torch\nimport torch.nn as nn\nimport torchvision\nfrom tqdm import tqdm\n\n\n\n# # Set printoptions\ntorch.set_printoptions(linewidth=320, precision=5, profile='long')\nnp.set_printoptions(linewidth=320, formatter={'float_kind': '{:11.5g}'.format})  # format short g, %precision=5\nmatplotlib.rc('font', **{'size': 11})\n\n# Prevent OpenCV from multithreading (to use PyTorch DataLoader)\ncv2.setNumThreads(0)\n\ndef box_iou(box1, box2):\n    # https://github.com/pytorch/vision/blob/master/torchvision/ops/boxes.py\n    \"\"\"\n    Return intersection-over-union (Jaccard index) of boxes.\n    Both sets of boxes are expected to be in (x1, y1, x2, y2) format.\n    Arguments:\n        box1 (Tensor[N, 4])\n        box2 (Tensor[M, 4])\n    Returns:\n        iou (Tensor[N, M]): the NxM matrix containing the pairwise\n            IoU values for every element in boxes1 and boxes2\n    \"\"\"\n\n    def box_area(box):\n        # box = 4xn\n        return (box[2] - box[0]) * (box[3] - box[1])\n\n    area1 = box_area(box1.t())\n    area2 = box_area(box2.t())\n\n    # inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2)\n    inter = (torch.min(box1[:, None, 2:], box2[:, 2:]) - torch.max(box1[:, None, :2], box2[:, :2])).clamp(0).prod(2)\n    return inter / (area1[:, None] + area2 - inter)  # iou = inter / (area1 + area2 - inter)\n\n\ndef wh_iou(wh1, wh2):\n    # Returns the nxm IoU matrix. wh1 is nx2, wh2 is mx2\n    wh1 = wh1[:, None]  # [N,1,2]\n    wh2 = wh2[None]  # [1,M,2]\n    inter = torch.min(wh1, wh2).prod(2)  # [N,M]\n    return inter / (wh1.prod(2) + wh2.prod(2) - inter)  # iou = inter / (area1 + area2 - inter)\n\ndef load_classes(path):\n    # Loads *.names file at 'path'\n    with open(path, 'r') as f:\n        names = f.read().split('\\n')\n    return list(filter(None, names))  # filter removes empty strings (such as last line)\n\n\ndef xyxy2xywh(x):\n    # Transform box coordinates from [x1, y1, x2, y2] (where xy1=top-left, xy2=bottom-right) to [x, y, w, h]\n    y = torch.zeros_like(x) if isinstance(x, torch.Tensor) else np.zeros_like(x)\n    y[:, 0] = (x[:, 0] + x[:, 2]) / 2  # x center\n    y[:, 1] = (x[:, 1] + x[:, 3]) / 2  # y center\n    y[:, 2] = x[:, 2] - x[:, 0]  # width\n    y[:, 3] = x[:, 3] - x[:, 1]  # height\n    return y\n\n\ndef xywh2xyxy(x):\n    # Transform box coordinates from [x, y, w, h] to [x1, y1, x2, y2] (where xy1=top-left, xy2=bottom-right)\n    y = torch.zeros_like(x) if isinstance(x, torch.Tensor) else np.zeros_like(x)\n    y[:, 0] = x[:, 0] - x[:, 2] / 2  # top left x\n    y[:, 1] = x[:, 1] - x[:, 3] / 2  # top left y\n    y[:, 2] = x[:, 0] + x[:, 2] / 2  # bottom right x\n    y[:, 3] = x[:, 1] + x[:, 3] / 2  # bottom right y\n    return y\n\n\n\ndef scale_coords(img1_shape, coords, img0_shape, ratio_pad=None):\n    # Rescale coords (xyxy) from img1_shape to img0_shape\n    if ratio_pad is None:  # calculate from img0_shape\n        gain = max(img1_shape) / max(img0_shape)  # gain  = old / new\n        pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2  # wh padding\n    else:\n        gain = ratio_pad[0][0]\n        pad = ratio_pad[1]\n\n    coords[:, [0, 2]] -= pad[0]  # x padding\n    coords[:, [1, 3]] -= pad[1]  # y padding\n    coords[:, :4] /= gain\n    clip_coords(coords, img0_shape)\n    return coords\n\n\ndef clip_coords(boxes, img_shape):\n    # Clip bounding xyxy bounding boxes to image shape (height, width)\n    boxes[:, 0].clamp_(0, img_shape[1])  # x1\n    boxes[:, 1].clamp_(0, img_shape[0])  # y1\n    boxes[:, 2].clamp_(0, img_shape[1])  # x2\n    boxes[:, 3].clamp_(0, img_shape[0])  # y2\n\ndef non_max_suppression(prediction, conf_thres=0.1, iou_thres=0.6, multi_label=True, classes=None, agnostic=False):\n    \"\"\"\n    Performs  Non-Maximum Suppression on inference results\n    Returns detections with shape:\n        nx6 (x1, y1, x2, y2, conf, cls)\n    \"\"\"\n\n    # Box constraints\n    min_wh, max_wh = 2, 4096  # (pixels) minimum and maximum box width and height\n\n    method = 'merge'\n    nc = prediction[0].shape[1] - 5  # number of classes\n    multi_label &= nc > 1  # multiple labels per box\n    output = [None] * len(prediction)\n\n    for xi, x in enumerate(prediction):  # image index, image inference\n        # Apply conf constraint\n        x = x[x[:, 4] > conf_thres]\n\n        # Apply width-height constraint\n        x = x[((x[:, 2:4] > min_wh) & (x[:, 2:4] < max_wh)).all(1)]\n\n        # If none remain process next image\n        if not x.shape[0]:\n            continue\n\n        # Compute conf\n        x[..., 5:] *= x[..., 4:5]  # conf = obj_conf * cls_conf\n\n        # Box (center x, center y, width, height) to (x1, y1, x2, y2)\n        box = xywh2xyxy(x[:, :4])\n\n        # Detections matrix nx6 (xyxy, conf, cls)\n        if multi_label:\n            i, j = (x[:, 5:] > conf_thres).nonzero().t()\n            x = torch.cat((box[i], x[i, j + 5].unsqueeze(1), j.float().unsqueeze(1)), 1)\n        else:  # best class only\n            conf, j = x[:, 5:].max(1)\n            x = torch.cat((box, conf.unsqueeze(1), j.float().unsqueeze(1)), 1)\n\n        # Filter by class\n        if classes:\n            x = x[(j.view(-1, 1) == torch.tensor(classes, device=j.device)).any(1)]\n\n        # Apply finite constraint\n        if not torch.isfinite(x).all():\n            x = x[torch.isfinite(x).all(1)]\n\n        # If none remain process next image\n        n = x.shape[0]  # number of boxes\n        if not n:\n            continue\n\n        # Sort by confidence\n        # if method == 'fast_batch':\n        #    x = x[x[:, 4].argsort(descending=True)]\n\n        # Batched NMS\n        c = x[:, 5] * 0 if agnostic else x[:, 5]  # classes\n        boxes, scores = x[:, :4].clone() + c.view(-1, 1) * max_wh, x[:, 4]  # boxes (offset by class), scores\n        if method == 'merge':  # Merge NMS (boxes merged using weighted mean)\n            i = torchvision.ops.boxes.nms(boxes, scores, iou_thres)\n            if 1 < n < 3E3:  # update boxes as boxes(i,4) = weights(i,n) * boxes(n,4)\n                try:\n                    # weights = (box_iou(boxes, boxes).tril_() > iou_thres) * scores.view(-1, 1)  # box weights\n                    # weights /= weights.sum(0)  # normalize\n                    # x[:, :4] = torch.mm(weights.T, x[:, :4])\n                    weights = (box_iou(boxes[i], boxes) > iou_thres) * scores[None]  # box weights\n                    x[i, :4] = torch.mm(weights / weights.sum(1, keepdim=True), x[:, :4]).float()  # merged boxes\n                except:  # possible CUDA error https://github.com/ultralytics/yolov3/issues/1139\n                    pass\n        elif method == 'vision':\n            i = torchvision.ops.boxes.nms(boxes, scores, iou_thres)\n        elif method == 'fast':  # FastNMS from https://github.com/dbolya/yolact\n            iou = box_iou(boxes, boxes).triu_(diagonal=1)  # upper triangular iou matrix\n            i = iou.max(0)[0] < iou_thres\n\n        output[xi] = x[i]\n    return output\n\n\ndef get_yolo_layers(model):\n    bool_vec = [x['type'] == 'yolo' for x in model.module_defs]\n    return [i for i, x in enumerate(bool_vec) if x]  # [82, 94, 106] for yolov3\n\ndef plot_one_box(x, img, color=None, label=None, line_thickness=None):\n    # Plots one bounding box on image img\n    tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1  # line/font thickness\n    color = color or [random.randint(0, 255) for _ in range(3)]\n    c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))\n    cv2.rectangle(img, c1, c2, color, thickness=tl)\n    if label:\n        tf = max(tl - 1, 1)  # font thickness\n        t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]\n        c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3\n        cv2.rectangle(img, c1, c2, color, -1)  # filled\n        cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)\n\nclass LoadImages:  # for inference\n    def __init__(self, path,imgList=None, img_size=416):\n\n        if imgList is None:\n            path = str(Path(path))  # os-agnostic\n            files = []\n            if os.path.isdir(path):\n                files = sorted(glob.glob(os.path.join(path, '*.*')))\n            elif os.path.isfile(path):\n                files = [path]\n\n            images = [x for x in files if os.path.splitext(x)[-1].lower() in img_formats]\n            videos = [x for x in files if os.path.splitext(x)[-1].lower() in vid_formats]\n            nI, nV = len(images), len(videos)\n            self.files = images + videos\n        else:\n            self.files = imgList\n            nI = len(self.files)\n            nV = 0\n\n        self.img_size = img_size\n        self.nF = nI + nV  # number of files\n        self.video_flag = [False] * nI + [True] * nV\n        self.mode = 'images'\n\n        self.cap = None\n        assert self.nF > 0, 'No images or videos found in ' + path\n\n    def __iter__(self):\n        self.count = 0\n        return self\n\n    def __next__(self):\n        if self.count == self.nF:\n            raise StopIteration\n        path = self.files[self.count]\n\n        if False:#self.video_flag[self.count]:\n            # Read video\n            self.mode = 'video'\n            ret_val, img0 = self.cap.read()\n            if not ret_val:\n                self.count += 1\n                self.cap.release()\n                if self.count == self.nF:  # last video\n                    raise StopIteration\n                else:\n                    path = self.files[self.count]\n                    self.new_video(path)\n                    ret_val, img0 = self.cap.read()\n\n            self.frame += 1\n            print('video %g/%g (%g/%g) %s: ' % (self.count + 1, self.nF, self.frame, self.nframes, path), end='')\n\n        else:\n            # Read image\n            self.count += 1\n            img0 = cv2.imread(path)  # BGR\n            assert img0 is not None, 'Image Not Found ' + path\n            print('image %g/%g %s: ' % (self.count, self.nF, path), end='')\n\n        # Padded resize\n        img = letterbox(img0, new_shape=self.img_size)[0]\n\n        # Convert\n        img = img[:, :, ::-1].transpose(2, 0, 1)  # BGR to RGB, to 3x416x416\n        img = np.ascontiguousarray(img)\n\n        # cv2.imwrite(path + '.letterbox.jpg', 255 * img.transpose((1, 2, 0))[:, :, ::-1])  # save letterbox image\n        return path, img, img0, self.cap\n\n    def new_video(self, path):\n        self.frame = 0\n        self.cap = cv2.VideoCapture(path)\n        self.nframes = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT))\n\n    def __len__(self):\n        return self.nF  # number of files\n\ndef letterbox(img, new_shape=(416, 416), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True):\n    # Resize image to a 32-pixel-multiple rectangle https://github.com/ultralytics/yolov3/issues/232\n    shape = img.shape[:2]  # current shape [height, width]\n    if isinstance(new_shape, int):\n        new_shape = (new_shape, new_shape)\n\n    # Scale ratio (new / old)\n    r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])\n    if not scaleup:  # only scale down, do not scale up (for better test mAP)\n        r = min(r, 1.0)\n\n    # Compute padding\n    ratio = r, r  # width, height ratios\n    new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))\n    dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding\n    if auto:  # minimum rectangle\n        dw, dh = np.mod(dw, 64), np.mod(dh, 64)  # wh padding\n    elif scaleFill:  # stretch\n        dw, dh = 0.0, 0.0\n        new_unpad = new_shape\n        ratio = new_shape[0] / shape[1], new_shape[1] / shape[0]  # width, height ratios\n\n    dw /= 2  # divide padding into 2 sides\n    dh /= 2\n\n    if shape[::-1] != new_unpad:  # resize\n        img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)\n    top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))\n    left, right = int(round(dw - 0.1)), int(round(dw + 0.1))\n    img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add border\n    return img, ratio, (dw, dh)\n\nclass FeatureConcat(nn.Module):\n    def __init__(self, layers):\n        super(FeatureConcat, self).__init__()\n        self.layers = layers  # layer indices\n        self.multiple = len(layers) > 1  # multiple layers flag\n\n    def forward(self, x, outputs):\n        return torch.cat([outputs[i] for i in self.layers], 1) if self.multiple else outputs[self.layers[0]]\n\n\nclass WeightedFeatureFusion(nn.Module):  # weighted sum of 2 or more layers https://arxiv.org/abs/1911.09070\n    def __init__(self, layers, weight=False):\n        super(WeightedFeatureFusion, self).__init__()\n        self.layers = layers  # layer indices\n        self.weight = weight  # apply weights boolean\n        self.n = len(layers) + 1  # number of layers\n        if weight:\n            self.w = nn.Parameter(torch.zeros(self.n), requires_grad=True)  # layer weights\n\n    def forward(self, x, outputs):\n        # Weights\n        if self.weight:\n            w = torch.sigmoid(self.w) * (2 / self.n)  # sigmoid weights (0-1)\n            x = x * w[0]\n\n        # Fusion\n        nx = x.shape[1]  # input channels\n        for i in range(self.n - 1):\n            a = outputs[self.layers[i]] * w[i + 1] if self.weight else outputs[self.layers[i]]  # feature to add\n            na = a.shape[1]  # feature channels\n\n            # Adjust channels\n            if nx == na:  # same shape\n                x = x + a\n            elif nx > na:  # slice input\n                x[:, :na] = x[:, :na] + a  # or a = nn.ZeroPad2d((0, 0, 0, 0, 0, dc))(a); x = x + a\n            else:  # slice feature\n                x = x + a[:, :nx]\n\n        return x\n\n\ndef select_device(device='', apex=False, batch_size=None):\n    # device = 'cpu' or '0' or '0,1,2,3'\n    cpu_request = device.lower() == 'cpu'\n    if device and not cpu_request:  # if device requested other than 'cpu'\n        os.environ['CUDA_VISIBLE_DEVICES'] = device  # set environment variable\n        assert torch.cuda.is_available(), 'CUDA unavailable, invalid device %s requested' % device  # check availablity\n\n    cuda = False if cpu_request else torch.cuda.is_available()\n    if cuda:\n        c = 1024 ** 2  # bytes to MB\n        ng = torch.cuda.device_count()\n        if ng > 1 and batch_size:  # check that batch_size is compatible with device_count\n            assert batch_size % ng == 0, 'batch-size %g not multiple of GPU count %g' % (batch_size, ng)\n        x = [torch.cuda.get_device_properties(i) for i in range(ng)]\n        s = 'Using CUDA ' + ('Apex ' if apex else '')  # apex for mixed precision https://github.com/NVIDIA/apex\n        for i in range(0, ng):\n            if i == 1:\n                s = ' ' * len(s)\n            print(\"%sdevice%g _CudaDeviceProperties(name='%s', total_memory=%dMB)\" %\n                  (s, i, x[i].name, x[i].total_memory / c))\n    else:\n        print('Using CPU')\n\n    print('')  # skip a line\n    return torch.device('cuda:0' if cuda else 'cpu')\n\n\ndef time_synchronized():\n    torch.cuda.synchronize() if torch.cuda.is_available() else None\n    return time.time()\n\n\n\ndef model_info(model, verbose=False):\n    # Plots a line-by-line description of a PyTorch model\n    n_p = sum(x.numel() for x in model.parameters())  # number parameters\n    n_g = sum(x.numel() for x in model.parameters() if x.requires_grad)  # number gradients\n    if verbose:\n        print('%5s %40s %9s %12s %20s %10s %10s' % ('layer', 'name', 'gradient', 'parameters', 'shape', 'mu', 'sigma'))\n        for i, (name, p) in enumerate(model.named_parameters()):\n            name = name.replace('module_list.', '')\n            print('%5g %40s %9s %12g %20s %10.3g %10.3g' %\n                  (i, name, p.requires_grad, p.numel(), list(p.shape), p.mean(), p.std()))\n\n    try:  # FLOPS\n        from thop import profile\n        macs, _ = profile(model, inputs=(torch.zeros(1, 3, 480, 640),), verbose=False)\n        fs = ', %.1f GFLOPS' % (macs / 1E9 * 2)\n    except:\n        fs = ''\n\n    print('Model Summary: %g layers, %g parameters, %g gradients%s' % (len(list(model.parameters())), n_p, n_g, fs))\n\ndef parse_model_cfg(path):\n    # Parse the yolo *.cfg file and return module definitions path may be 'cfg/yolov3.cfg', 'yolov3.cfg', or 'yolov3'\n    if not path.endswith('.cfg'):  # add .cfg suffix if omitted\n        path += '.cfg'\n    if not os.path.exists(path) and os.path.exists('cfg' + os.sep + path):  # add cfg/ prefix if omitted\n        path = 'cfg' + os.sep + path\n\n    with open(path, 'r') as f:\n        lines = f.read().split('\\n')\n    lines = [x for x in lines if x and not x.startswith('#')]\n    lines = [x.rstrip().lstrip() for x in lines]  # get rid of fringe whitespaces\n    mdefs = []  # module definitions\n    for line in lines:\n        if line.startswith('['):  # This marks the start of a new block\n            mdefs.append({})\n            mdefs[-1]['type'] = line[1:-1].rstrip()\n            if mdefs[-1]['type'] == 'convolutional':\n                mdefs[-1]['batch_normalize'] = 0  # pre-populate with zeros (may be overwritten later)\n        else:\n            key, val = line.split(\"=\")\n            key = key.rstrip()\n\n            if key == 'anchors':  # return nparray\n                mdefs[-1][key] = np.array([float(x) for x in val.split(',')]).reshape((-1, 2))  # np anchors\n            elif (key in ['from', 'layers', 'mask']) or (key == 'size' and ',' in val):  # return array\n                mdefs[-1][key] = [int(x) for x in val.split(',')]\n            else:\n                val = val.strip()\n                if val.isnumeric():  # return int or float\n                    mdefs[-1][key] = int(val) if (int(val) - float(val)) == 0 else float(val)\n                else:\n                    mdefs[-1][key] = val  # return string\n\n    # Check all fields are supported\n    supported = ['type', 'batch_normalize', 'filters', 'size', 'stride', 'pad', 'activation', 'layers', 'groups',\n                 'from', 'mask', 'anchors', 'classes', 'num', 'jitter', 'ignore_thresh', 'truth_thresh', 'random',\n                 'stride_x', 'stride_y', 'weights_type', 'weights_normalization', 'scale_x_y', 'beta_nms', 'nms_kind',\n                 'iou_loss', 'iou_normalizer', 'cls_normalizer', 'iou_thresh']\n\n    f = []  # fields\n    for x in mdefs[1:]:\n        [f.append(k) for k in x if k not in f]\n    u = [x for x in f if x not in supported]  # unsupported fields\n    assert not any(u), \"Unsupported fields %s in %s. See https://github.com/ultralytics/yolov3/issues/631\" % (u, path)\n\n    return mdefs\n\ndef create_modules(module_defs, img_size, cfg):\n    # Constructs module list of layer blocks from module configuration in module_defs\n\n    img_size = [img_size] * 2 if isinstance(img_size, int) else img_size  # expand if necessary\n    _ = module_defs.pop(0)  # cfg training hyperparams (unused)\n    output_filters = [3]  # input channels\n    module_list = nn.ModuleList()\n    routs = []  # list of layers which rout to deeper layers\n    yolo_index = -1\n\n    for i, mdef in enumerate(module_defs):\n        modules = nn.Sequential()\n\n        if mdef['type'] == 'convolutional':\n            bn = mdef['batch_normalize']\n            filters = mdef['filters']\n            k = mdef['size']  # kernel size\n            stride = mdef['stride'] if 'stride' in mdef else (mdef['stride_y'], mdef['stride_x'])\n            if isinstance(k, int):  # single-size conv\n                modules.add_module('Conv2d', nn.Conv2d(in_channels=output_filters[-1],\n                                                       out_channels=filters,\n                                                       kernel_size=k,\n                                                       stride=stride,\n                                                       padding=k // 2 if mdef['pad'] else 0,\n                                                       groups=mdef['groups'] if 'groups' in mdef else 1,\n                                                       bias=not bn))\n            else:  # multiple-size conv\n                modules.add_module('MixConv2d', MixConv2d(in_ch=output_filters[-1],\n                                                          out_ch=filters,\n                                                          k=k,\n                                                          stride=stride,\n                                                          bias=not bn))\n\n            if bn:\n                modules.add_module('BatchNorm2d', nn.BatchNorm2d(filters, momentum=0.03, eps=1E-4))\n            else:\n                routs.append(i)  # detection output (goes into yolo layer)\n\n            if mdef['activation'] == 'leaky':  # activation study https://github.com/ultralytics/yolov3/issues/441\n                modules.add_module('activation', nn.LeakyReLU(0.1, inplace=True))\n            elif mdef['activation'] == 'swish':\n                modules.add_module('activation', Swish())\n            elif mdef['activation'] == 'mish':\n                modules.add_module('activation', Mish())\n\n        elif mdef['type'] == 'BatchNorm2d':\n            filters = output_filters[-1]\n            modules = nn.BatchNorm2d(filters, momentum=0.03, eps=1E-4)\n            if i == 0 and filters == 3:  # normalize RGB image\n                # imagenet mean and var https://pytorch.org/docs/stable/torchvision/models.html#classification\n                modules.running_mean = torch.tensor([0.485, 0.456, 0.406])\n                modules.running_var = torch.tensor([0.0524, 0.0502, 0.0506])\n\n        elif mdef['type'] == 'maxpool':\n            k = mdef['size']  # kernel size\n            stride = mdef['stride']\n            maxpool = nn.MaxPool2d(kernel_size=k, stride=stride, padding=(k - 1) // 2)\n            if k == 2 and stride == 1:  # yolov3-tiny\n                modules.add_module('ZeroPad2d', nn.ZeroPad2d((0, 1, 0, 1)))\n                modules.add_module('MaxPool2d', maxpool)\n            else:\n                modules = maxpool\n\n        elif mdef['type'] == 'upsample':\n            if ONNX_EXPORT:  # explicitly state size, avoid scale_factor\n                g = (yolo_index + 1) * 2 / 32  # gain\n                modules = nn.Upsample(size=tuple(int(x * g) for x in img_size))  # img_size = (320, 192)\n            else:\n                modules = nn.Upsample(scale_factor=mdef['stride'])\n\n        elif mdef['type'] == 'route':  # nn.Sequential() placeholder for 'route' layer\n            layers = mdef['layers']\n            filters = sum([output_filters[l + 1 if l > 0 else l] for l in layers])\n            routs.extend([i + l if l < 0 else l for l in layers])\n            modules = FeatureConcat(layers=layers)\n\n        elif mdef['type'] == 'shortcut':  # nn.Sequential() placeholder for 'shortcut' layer\n            layers = mdef['from']\n            filters = output_filters[-1]\n            routs.extend([i + l if l < 0 else l for l in layers])\n            modules = WeightedFeatureFusion(layers=layers, weight='weights_type' in mdef)\n\n        elif mdef['type'] == 'reorg3d':  # yolov3-spp-pan-scale\n            pass\n\n        elif mdef['type'] == 'yolo':\n            yolo_index += 1\n            stride = [32, 16, 8]  # P5, P4, P3 strides\n            if 'panet' in cfg or 'yolov4' in cfg:  # stride order reversed\n                stride = list(reversed(stride))\n            layers = mdef['from'] if 'from' in mdef else []\n            modules = YOLOLayer(anchors=mdef['anchors'][mdef['mask']],  # anchor list\n                                nc=mdef['classes'],  # number of classes\n                                img_size=img_size,  # (416, 416)\n                                yolo_index=yolo_index,  # 0, 1, 2...\n                                layers=layers,  # output layers\n                                stride=stride[yolo_index])\n\n            # Initialize preceding Conv2d() bias (https://arxiv.org/pdf/1708.02002.pdf section 3.3)\n            try:\n                j = layers[yolo_index] if 'from' in mdef else -1\n                bias_ = module_list[j][0].bias  # shape(255,)\n                bias = bias_[:modules.no * modules.na].view(modules.na, -1)  # shape(3,85)\n                bias[:, 4] += -4.5  # obj\n                bias[:, 5:] += math.log(0.6 / (modules.nc - 0.99))  # cls (sigmoid(p) = 1/nc)\n                module_list[j][0].bias = torch.nn.Parameter(bias_, requires_grad=bias_.requires_grad)\n            except:\n                print('WARNING: smart bias initialization failure.')\n\n        else:\n            print('Warning: Unrecognized Layer Type: ' + mdef['type'])\n\n        # Register module list and number of output filters\n        module_list.append(modules)\n        output_filters.append(filters)\n\n    routs_binary = [False] * (i + 1)\n    for i in routs:\n        routs_binary[i] = True\n    return module_list, routs_binary\n\n\nclass YOLOLayer(nn.Module):\n    def __init__(self, anchors, nc, img_size, yolo_index, layers, stride):\n        super(YOLOLayer, self).__init__()\n        self.anchors = torch.Tensor(anchors)\n        self.index = yolo_index  # index of this layer in layers\n        self.layers = layers  # model output layer indices\n        self.stride = stride  # layer stride\n        self.nl = len(layers)  # number of output layers (3)\n        self.na = len(anchors)  # number of anchors (3)\n        self.nc = nc  # number of classes (80)\n        self.no = nc + 5  # number of outputs (85)\n        self.nx, self.ny, self.ng = 0, 0, 0  # initialize number of x, y gridpoints\n        self.anchor_vec = self.anchors / self.stride\n        self.anchor_wh = self.anchor_vec.view(1, self.na, 1, 1, 2)\n\n        if ONNX_EXPORT:\n            self.training = False\n            self.create_grids((img_size[1] // stride, img_size[0] // stride))  # number x, y grid points\n\n    def create_grids(self, ng=(13, 13), device='cpu'):\n        self.nx, self.ny = ng  # x and y grid size\n        self.ng = torch.tensor(ng, dtype=torch.float)\n\n        # build xy offsets\n        if not self.training:\n            yv, xv = torch.meshgrid([torch.arange(self.ny, device=device), torch.arange(self.nx, device=device)])\n            self.grid = torch.stack((xv, yv), 2).view((1, 1, self.ny, self.nx, 2)).float()\n\n        if self.anchor_vec.device != device:\n            self.anchor_vec = self.anchor_vec.to(device)\n            self.anchor_wh = self.anchor_wh.to(device)\n\n    def forward(self, p, out):\n        ASFF = False  # https://arxiv.org/abs/1911.09516\n        if ASFF:\n            i, n = self.index, self.nl  # index in layers, number of layers\n            p = out[self.layers[i]]\n            bs, _, ny, nx = p.shape  # bs, 255, 13, 13\n            if (self.nx, self.ny) != (nx, ny):\n                self.create_grids((nx, ny), p.device)\n\n            # outputs and weights\n            # w = F.softmax(p[:, -n:], 1)  # normalized weights\n            w = torch.sigmoid(p[:, -n:]) * (2 / n)  # sigmoid weights (faster)\n            # w = w / w.sum(1).unsqueeze(1)  # normalize across layer dimension\n\n            # weighted ASFF sum\n            p = out[self.layers[i]][:, :-n] * w[:, i:i + 1]\n            for j in range(n):\n                if j != i:\n                    p += w[:, j:j + 1] * \\\n                         F.interpolate(out[self.layers[j]][:, :-n], size=[ny, nx], mode='bilinear', align_corners=False)\n\n        elif ONNX_EXPORT:\n            bs = 1  # batch size\n        else:\n            bs, _, ny, nx = p.shape  # bs, 255, 13, 13\n            if (self.nx, self.ny) != (nx, ny):\n                self.create_grids((nx, ny), p.device)\n\n        # p.view(bs, 255, 13, 13) -- > (bs, 3, 13, 13, 85)  # (bs, anchors, grid, grid, classes + xywh)\n        p = p.view(bs, self.na, self.no, self.ny, self.nx).permute(0, 1, 3, 4, 2).contiguous()  # prediction\n\n        if self.training:\n            return p\n\n        elif ONNX_EXPORT:\n            # Avoid broadcasting for ANE operations\n            m = self.na * self.nx * self.ny\n            ng = 1. / self.ng.repeat(m, 1)\n            grid = self.grid.repeat(1, self.na, 1, 1, 1).view(m, 2)\n            anchor_wh = self.anchor_wh.repeat(1, 1, self.nx, self.ny, 1).view(m, 2) * ng\n\n            p = p.view(m, self.no)\n            xy = torch.sigmoid(p[:, 0:2]) + grid  # x, y\n            wh = torch.exp(p[:, 2:4]) * anchor_wh  # width, height\n            p_cls = torch.sigmoid(p[:, 4:5]) if self.nc == 1 else \\\n                torch.sigmoid(p[:, 5:self.no]) * torch.sigmoid(p[:, 4:5])  # conf\n            return p_cls, xy * ng, wh\n\n        else:  # inference\n            io = p.clone()  # inference output\n            io[..., :2] = torch.sigmoid(io[..., :2]) + self.grid  # xy\n            io[..., 2:4] = torch.exp(io[..., 2:4]) * self.anchor_wh  # wh yolo method\n            io[..., :4] *= self.stride\n            torch.sigmoid_(io[..., 4:])\n            return io.view(bs, -1, self.no), p  # view [1, 3, 13, 13, 85] as [1, 507, 85]\n\nclass Darknet(nn.Module):\n    # YOLOv3 object detection model\n\n    def __init__(self, cfg, img_size=(416, 416), verbose=False):\n        super(Darknet, self).__init__()\n\n        self.module_defs = parse_model_cfg(cfg)\n        self.module_list, self.routs = create_modules(self.module_defs, img_size, cfg)\n        self.yolo_layers = get_yolo_layers(self)\n        # torch_utils.initialize_weights(self)\n\n        # Darknet Header https://github.com/AlexeyAB/darknet/issues/2914#issuecomment-496675346\n        self.version = np.array([0, 2, 5], dtype=np.int32)  # (int32) version info: major, minor, revision\n        self.seen = np.array([0], dtype=np.int64)  # (int64) number of images seen during training\n        self.info(verbose) if not ONNX_EXPORT else None  # print model description\n\n    def forward(self, x, augment=False, verbose=False):\n\n        if not augment:\n            return self.forward_once(x)\n        else:  # Augment images (inference and test only) https://github.com/ultralytics/yolov3/issues/931\n            img_size = x.shape[-2:]  # height, width\n            s = [0.83, 0.67]  # scales\n            y = []\n            for i, xi in enumerate((x,\n                                    scale_img(x.flip(3), s[0], same_shape=False),  # flip-lr and scale\n                                    scale_img(x, s[1], same_shape=False),  # scale\n                                    )):\n                # cv2.imwrite('img%g.jpg' % i, 255 * xi[0].numpy().transpose((1, 2, 0))[:, :, ::-1])\n                y.append(self.forward_once(xi)[0])\n\n            y[1][..., :4] /= s[0]  # scale\n            y[1][..., 0] = img_size[1] - y[1][..., 0]  # flip lr\n            y[2][..., :4] /= s[1]  # scale\n\n            # for i, yi in enumerate(y):  # coco small, medium, large = < 32**2 < 96**2 <\n            #     area = yi[..., 2:4].prod(2)[:, :, None]\n            #     if i == 1:\n            #         yi *= (area < 96. ** 2).float()\n            #     elif i == 2:\n            #         yi *= (area > 32. ** 2).float()\n            #     y[i] = yi\n\n            y = torch.cat(y, 1)\n            return y, None\n\n    def forward_once(self, x, augment=False, verbose=False):\n        img_size = x.shape[-2:]  # height, width\n        yolo_out, out = [], []\n        if verbose:\n            print('0', x.shape)\n            str = ''\n\n        # Augment images (inference and test only)\n        if augment:  # https://github.com/ultralytics/yolov3/issues/931\n            nb = x.shape[0]  # batch size\n            s = [0.83, 0.67]  # scales\n            x = torch.cat((x,\n                           torch_utils.scale_img(x.flip(3), s[0]),  # flip-lr and scale\n                           torch_utils.scale_img(x, s[1]),  # scale\n                           ), 0)\n\n        for i, module in enumerate(self.module_list):\n            name = module.__class__.__name__\n            if name in ['WeightedFeatureFusion', 'FeatureConcat']:  # sum, concat\n                if verbose:\n                    l = [i - 1] + module.layers  # layers\n                    sh = [list(x.shape)] + [list(out[i].shape) for i in module.layers]  # shapes\n                    str = ' >> ' + ' + '.join(['layer %g %s' % x for x in zip(l, sh)])\n                x = module(x, out)  # WeightedFeatureFusion(), FeatureConcat()\n            elif name == 'YOLOLayer':\n                yolo_out.append(module(x, out))\n            else:  # run module directly, i.e. mtype = 'convolutional', 'upsample', 'maxpool', 'batchnorm2d' etc.\n                x = module(x)\n\n            out.append(x if self.routs[i] else [])\n            if verbose:\n                print('%g/%g %s -' % (i, len(self.module_list), name), list(x.shape), str)\n                str = ''\n\n        if self.training:  # train\n            return yolo_out\n        elif ONNX_EXPORT:  # export\n            x = [torch.cat(x, 0) for x in zip(*yolo_out)]\n            return x[0], torch.cat(x[1:3], 1)  # scores, boxes: 3780x80, 3780x4\n        else:  # inference or test\n            x, p = zip(*yolo_out)  # inference output, training output\n            x = torch.cat(x, 1)  # cat yolo outputs\n            if augment:  # de-augment results\n                x = torch.split(x, nb, dim=0)\n                x[1][..., :4] /= s[0]  # scale\n                x[1][..., 0] = img_size[1] - x[1][..., 0]  # flip lr\n                x[2][..., :4] /= s[1]  # scale\n                x = torch.cat(x, 1)\n            return x, p\n\n    def fuse(self):\n        # Fuse Conv2d + BatchNorm2d layers throughout model\n        print('Fusing layers...')\n        fused_list = nn.ModuleList()\n        for a in list(self.children())[0]:\n            if isinstance(a, nn.Sequential):\n                for i, b in enumerate(a):\n                    if isinstance(b, nn.modules.batchnorm.BatchNorm2d):\n                        # fuse this bn layer with the previous conv2d layer\n                        conv = a[i - 1]\n                        fused = torch_utils.fuse_conv_and_bn(conv, b)\n                        a = nn.Sequential(fused, *list(a.children())[i + 1:])\n                        break\n            fused_list.append(a)\n        self.module_list = fused_list\n        self.info() if not ONNX_EXPORT else None  # yolov3-spp reduced from 225 to 152 layers\n\n    def info(self, verbose=False):\n        model_info(self, verbose)\n\ndef bboxFormat(bbox):\n    '''\n    xy1xy2  cls, conf\n    input box is in top-left and bottom-right\n    convert it into - top left, width height\n    x,y,w,h\n    '''\n    parts = bbox\n    x = int(parts[0])\n    y = int(parts[1])\n    x2 = int(parts[2])\n    y2 = int(parts[3])\n    conf = float(parts[4])\n    cls = int(parts[5])\n    return conf, x, y, x2 - x, y2 - y\n\n\ndef format_prediction_string(bboxList):\n    pred_strings = []\n    for item in bboxList:\n        conf, x0, y0, w0, h0 = bboxFormat(item)\n        pred_strings.append(\"{0:.4f} {1} {2} {3} {4}\".format(conf, x0, y0, w0, h0))\n\n    return \" \".join(pred_strings)\n\ndef detect(opt,model,device,imgList,save_img=False):\n    img_size = opt.img_size  # (320, 192) or (416, 256) or (608, 352) for (height, width)\n    out, weights,  = opt.output,  opt.weights\n\n    save_img = False\n    save_txt = False\n    view_img = False\n    fig, axs = plt.subplots(10, 1, figsize=(160,80))\n    count = 0\n    results_info = []\n    # Eval mode\n    model.eval()\n    half = False\n    # Set Dataloader\n    dataset = LoadImages(path=None,imgList=imgList, img_size=img_size)\n\n    # Get names and colors\n    names = load_classes(opt.names)\n    colors = [[random.randint(0, 255) for _ in range(3)] for _ in range(len(names))]\n\n    # Run inference\n    t0 = time.time()\n    img = torch.zeros((1, 3, img_size, img_size), device=device)  # init img\n    for path, img, im0s, vid_cap in dataset:\n        img = torch.from_numpy(img).to(device)\n        img = img.float()  # uint8 to fp16/32\n        img /= 255.0  # 0 - 255 to 0.0 - 1.0\n        if img.ndimension() == 3:\n            img = img.unsqueeze(0)\n        # Inference\n        t1 = time_synchronized()\n        pred = model(img, augment=opt.augment)[0]\n        t2 = time_synchronized()\n\n        opt.agnostic_nms = True\n        opt.classes = 0\n        # Apply NMS\n        pred = non_max_suppression(pred, opt.conf_thres, opt.iou_thres,\n                                   multi_label=False, classes=opt.classes, agnostic=opt.agnostic_nms)\n\n\n        # Process detections\n        imgres = []\n        for i, det in enumerate(pred):  # detections per image\n            p, s, im0 = path, '', im0s\n            save_path = str(Path(out) / Path(p).name)\n            s += '%gx%g ' % img.shape[2:]  # print string\n            if det is not None and len(det):\n                # Rescale boxes from img_size to im0 size\n                det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()\n\n                # Print results\n                for c in det[:, -1].unique():\n                    n = (det[:, -1] == c).sum()  # detections per class\n                    s += '%g %ss, ' % (n, names[int(c)])  # add to string\n\n                # Write results\n                for *xyxy, conf, cls in det.cpu().numpy():\n                    x1,y1,x2,y2  = xyxy\n                    imgres.append([x1, y1, x2, y2, conf, cls])\n                    if count<10:\n                        cv2.rectangle(im0, (int(x1), int(y1)),(int(x2),int(y2)), (220, 0, 0), 3)\n                        cv2.putText(im0, str('%.2f'%(conf)), (int(x1)+10, int(y1)+10), cv2.FONT_HERSHEY_SIMPLEX ,  \n                               0.5, (255,255,255), 2, cv2.LINE_AA) \n                    if save_txt:  # Write to file\n                        with open(save_path + '.txt', 'a') as file:\n                            file.write(('%g ' * 6 + '\\n') % (*xyxy, cls, conf))\n\n                    if save_img or view_img:  # Add bbox to image\n                        label = '%s %.2f' % (names[int(cls)], conf)\n                        plot_one_box(xyxy, im0, label=label, color=colors[int(cls)])\n                if count<10:  \n                    axs[count].imshow(im0)\n                    count+=1\n\n            # Print time (inference + NMS)\n            print('%sDone. (%.3fs)' % (s, t2 - t1))\n\n            # Stream results\n            if view_img:\n                cv2.imshow(p, im0)\n                if cv2.waitKey(1) == ord('q'):  # q to quit\n                    raise StopIteration\n\n            # Save results (image with detections)\n            if save_img:\n                if dataset.mode == 'images':\n                    cv2.imwrite(save_path, im0)\n\n        imgBaseName = os.path.basename(path)\n        image_id = imgBaseName.split('.')[0]\n        if len(imgres)>0:\n            pred_string = format_prediction_string(imgres)\n        else:\n            pred_string = ''\n\n        result = {\n            'image_id': image_id,\n            'PredictionString': pred_string}\n\n        results_info.append(result)\n\n    if save_txt or save_img:\n        print('Results saved to %s' % os.getcwd() + os.sep + out)\n    print('Done. (%.3fs)' % (time.time() - t0))\n    return results_info\n\ndef load_yolov3_model(opt):\n    device = select_device(device='cpu' if ONNX_EXPORT else opt.device)\n    # Initialize model\n    model = Darknet(opt.cfg, opt.img_size)\n    # Load weights\n    # attempt_download(weights)\n    if opt.weights.endswith('.pt'):  # pytorch format\n        model.load_state_dict(torch.load(opt.weights, map_location=device)['model'])\n\n    model = model.to(device)\n    return model ,device\n\n\n\n   ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from pathlib import Path\nDIR_INPUT = '/kaggle/input/global-wheat-detection'\nDIR_TRAIN = f'{DIR_INPUT}/train'\nDIR_TEST = f'{DIR_INPUT}/test'\ndata_dir = '/kaggle/input/global-wheat-detection/test'\nsubmission = pd.read_csv(f'{DIR_INPUT}/sample_submission.csv')\nroot_image = \"/kaggle//input/global-wheat-detection/test\"\ntest_images = [os.path.join(root_image, f\"{img}.jpg\") for img in submission.image_id]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_images","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if True:\n    class params:\n        pass\n\n\n    opt = params()\n    opt.cfg = r'/kaggle/input/yolov3files/yolov3-spp-1cls.cfg'\n    opt.names = r'/kaggle/working/kg_wheat.names'\n    opt.weights = r'/kaggle/input/yolov3-wheat-weights/last_1cls_spp_hpy_12epoch.pt'\n    opt.conf_thres = 0.2\n    opt.iou_thres = 0.5\n    opt.img_size = 608\n# best setting\n#     opt.conf_thres = 0.2 \n#     opt.iou_thres = 0.5\n#     opt.img_size = 608\n    opt.output = r'/kaggle/working/'\n    opt.device = 'cpu' #'0'\n    opt.augment = False\n\n    model,device = load_yolov3_model(opt)\n    #print(model)\n    print(opt)\n    imgList = test_images\n    with torch.no_grad():\n        results = detect(opt,model,device,imgList)\n\n   ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\ntest_df.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!rm -rf myyolov3","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#os.makedirs('myyolov3')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!cp -R /kaggle/input/yolov3files myyolov3","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#%cd myyolov3/yolov3files","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!sed -i 's/from utils./from /g' detect.py","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!sed -i 's/from utils./from /g' models.py","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!sed -i 's/from utils./from /g' layers.py","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!sed -i 's/from . import/import /g' utils.py","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!sed -i 's/from utils./from /g' datasets.py","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!head -20 datasets.py","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_img_folder = '/kaggle/input/global-wheat-detection/test'\nout = '/kaggle/working/yolov3/testOut'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def bboxFormat(bbox):\n    ''' \n    xy1xy2  cls, conf\n    input box is in top-left and bottom-right\n    convert it into - top left, width height\n    x,y,w,h\n    '''\n    parts = bbox.split(' ')\n    x = int(parts[0])\n    y = int(parts[1])\n    x2 = int(parts[2])\n    y2 = int(parts[3])\n    cls = int(parts[4])\n    conf = float(parts[5])\n    return conf,x,y,x2-x,y2-y\n    \ndef format_prediction_string(bboxList):\n    pred_strings = []\n    for item in bboxList:\n        conf,x0,y0,w0,h0 = bboxFormat(item)\n        pred_strings.append(\"{0:.4f} {1} {2} {3} {4}\".format(conf, x0,y0,w0,h0))\n\n    return \" \".join(pred_strings)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# from tqdm import tqdm\n# from pathlib import Path\n# DIR_INPUT = '/kaggle/input/global-wheat-detection'\n# DIR_TRAIN = f'{DIR_INPUT}/train'\n# DIR_TEST = f'{DIR_INPUT}/test'\n# data_dir = '/kaggle/input/global-wheat-detection/test'\n# submission = pd.read_csv(f'{DIR_INPUT}/sample_submission.csv')\n# root_image = Path(\"/kaggle//input/global-wheat-detection/test\")\n# test_images = [root_image / f\"{img}.jpg\" for img in submission.image_id]\n# submission = []\n# results = []\n# outpath = '/kaggle/working/testOut'\n# for image in tqdm(test_images):\n#     #print(image)\n#     command = f'python3 detect.py --weights /kaggle/input/yolov3weights/last_1cls.pt --names ../../kg_wheat.names --img-size 768 --cfg ./yolov3-1cls.cfg --conf-thres 0.2 --output {outpath} --save-txt  --source {image}'\n#     os.system(command)\n#     time.sleep(0.200)\n#     img_base_name = os.path.basename(image)\n#     #print(img_base_name)\n#     result_txt_path = os.path.join(outpath,f'{img_base_name}.txt')\n#     with open(result_txt_path,'r') as fp:\n#         data = fp.readlines()\n#         score_bbox_xy1xy2=[]\n#         if len(data) > 0:\n#             for ele in data:\n#                 score_bbox_xy1xy2.append(ele)\n        \n#             pred_string = format_prediction_string(score_bbox_xy1xy2)\n#         else:\n#             pred_string= ''\n#         image_id = img_base_name.split('.')[0] \n#         result = {\n#         'image_id': image_id,\n#         'PredictionString': pred_string}\n\n        \n#         results.append(result)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\n# test_df.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# test_df.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!python3 detect.py --weights /kaggle/input/yolov3weights/last_1cls.pt --names ../../kg_wheat.names --img-size 768 --cfg ./yolov3-1cls.cfg --conf-thres 0.2 --output '/kaggle/working/testOut' --save-txt  --source '/kaggle/input/global-wheat-detection/test' ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Submission**\n\n","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Submission File\nThe submission format requires a space delimited set of bounding boxes. For example:\n\nce4833752,0.5 0 0 100 100\n\nindicates that image ce4833752 has a bounding box with a confidence of 0.5, at x == 0 and y == 0, with a width and height of 100.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# import glob\n# img_formats = ['.bmp', '.jpg', '.jpeg', '.png', '.tif', '.dng']\n# test_img_folder = '/kaggle/input/global-wheat-detection/test'\n# if os.path.isdir(test_img_folder):\n#     files = sorted(glob.glob(os.path.join(test_img_folder, '*.*')))\n# elif os.path.isfile(test_img_folder):\n#     files = [test_img_folder]\n#     images = [x for x in files if os.path.splitext(x)[-1].lower() in img_formats]\n#     files = images\n# print(files)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# resultFolder = '/kaggle/working/testOut'\n# results = []\n# for imgpath in list(set(files)):\n#     img_name = os.path.basename(imgpath)\n#     result_txt_path = os.path.join(resultFolder,f'{img_name}.txt')\n#     with open(result_txt_path,'r') as fp:\n#         data = fp.readlines()\n#         score_bbox_xy1xy2=[]\n#         if len(data) > 0:\n#             for ele in data:\n#                 score_bbox_xy1xy2.append(ele)\n        \n#             pred_string = format_prediction_string(score_bbox_xy1xy2)\n#         else:\n#             pred_string= ''\n#         image_id = img_name.split('.')[0] \n#         result = {\n#         'image_id': image_id,\n#         'PredictionString': pred_string}\n\n        \n#         results.append(result)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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":1}