def show_label_images(input_yaml, wait_ms=10, output_folder=None): """ Shows and draws pictures with labeled traffic lights. Can save pictures. :param input_yaml: Path to yaml file :param wait_ms: wait time in milliseconds before OpenCV shows next image :param output_folder: If None, do not save picture. Else enter path to folder """ images = get_all_labels(input_yaml) if output_folder is not None: if not os.path.exists(output_folder): os.makedirs(output_folder) for i, image_dict in enumerate(images): image = cv2.imread(image_dict['path']) if image is None: raise IOError('Could not open image path', image_dict['path']) for box in image_dict['boxes']: cv2.rectangle(image, (ir(box['x_min']), ir(box['y_min'])), (ir(box['x_max']), ir(box['y_max'])), (0, 255, 0)) cv2.imshow('labeled_image', image) #cv2.waitKey(10) cv2.waitKey(wait_ms) if output_folder is not None: cv2.imwrite( os.path.join( output_folder, str(i).zfill(10) + '_' + os.path.basename(image_dict['path'])), image)
def quick_stats(input_yaml): """ Prints statistic data for the traffic light yaml files. :param input_yaml: Path to yaml file of published traffic light set """ LABEL_DICT = { "horizontal": 1, "vertical": 2, "horizontalbus": 6, "verticalbus": 7 } LABEL_DICT_R = {v: k for k, v in LABEL_DICT.items()} images = get_all_labels(input_yaml) appearances = { "horizontal": 0, "vertical": 0, "horizontalbus": 0, "verticalbus": 0 } for image in images: for box in image['objects']: class_str = str(box['class_id'])[2] appearances[LABEL_DICT_R[int(class_str)]] += 1 print('Labels:') for key, label in appearances.items(): print('\t{}: {}'.format(key, label))
def try_ext(input_yaml , output_folder_image , output_folder_gt): images = get_all_labels(input_yaml) desired_dim = (1280,720) k = 1 for i, image_dict in enumerate(images): print(k) image = cv2.imread(image_dict['path']) image = cv2.resize(image, desired_dim, interpolation=cv2.INTER_LINEAR) imgfilePath = output_folder_image+'/'+str(k)+'.png' cv2.imwrite(imgfilePath,image) filePath = output_folder_gt+'/'+str(k)+'.txt' out_file = open(filePath, 'w') for box in image_dict['boxes']: x0 = float(box['x_min']) y0 = float(box['y_min']) x1 = float(box['x_max']) y1 = float(box['y_max']) out_file.write("traffic_light " + str(x0) + " "+ str(y0) + " " + str(x1) + " " + str(y1) + "\n") k = k + 1
def main(): fileCount = 0 # number of files saved (for filename) trafficCount = 0 # number of traffic lights saved otherCount = 0 # number of non traffic light patches saved skipCount = 0 # number of traffic lights skipped if not createFolders(): print("please delete the existing image folders first") return #testData = get_all_labels(DATA_DIR + "/rgb_test/test.yaml") trainData = get_all_labels(DATA_DIR + "/rgb_train/train.yaml") print("trainData length: " + str(len(trainData))) # shuffle and sample first n images in training indices = [i for i in range(len(trainData))] random.shuffle(indices) #indices = indices[:1000] # TODO: number of images to sample #fds = [] # all features (need to include ones that are not traffic lights as well) # extract patches from images and save them to labeled folders for i in indices: info = trainData[i] image = cv2.imread(DATA_DIR + "/rgb_train/train/" + info['path'], cv2.IMREAD_GRAYSCALE) if fileCount % 1500 == 0: print("file count: " + str(fileCount)) # sample some places in this image that aren't traffic lights for _ in range(30): # number of random samples per image rect = getRandRect(image) if isALight(rect, info['boxes']): # make sure it's not a traffic light continue #cv2.rectangle(imageCopy, (int(rect.xmin),int(rect.ymin)+1), (int(rect.xmax),int(rect.ymax)+1), [255,255,255], 2) img = getRegion(image, rect) saveImage(img, None, fileCount) otherCount += 1 fileCount += 1 for box in info['boxes']: rect = Rectangle(box['y_min'], box['y_max'], box['x_min'], box['x_max']) if not validCord(rect, image): #print("skipping image with shape: " + str(int(box['y_max']-box['y_min'])) + "x" + str(int(box['x_max']-box['x_min'])) ) skipCount += 1 continue # get 24x48 image patch corresponding to this box img = getRegion(image, rect) saveImage(img, box, fileCount) trafficCount += 1 fileCount += 1 print("***Completed calculating features from training images***") print("lights skipped: " + str(skipCount)) print("lights saved: " + str(skipCount)) print("others saved: " + str(otherCount)) print("TOTAL patches saved: " + str(fileCount))
def getTestSample(num, requireLights=0): res = [] testData = get_all_labels(DATA_DIR + "/rgb_test/test.yaml") indices = [i for i in range(len(testData))] random.shuffle(indices) for i in indices: info = testData[i] if requireLights <= 0: res.append(info) elif len(info['boxes']) > 0: res.append(info) requireLights -= 1 if len(res) == num: # we have enough images return res
def save_tl_images(input_yaml, output_folder): """ Extracts labelled pictures of traffic lights. Saves them as separate files in specified output_folder. :param input_yaml: Path to yaml file :param output_folder: path to folder. created if does not exist """ images = get_all_labels(input_yaml) assert output_folder is not None if not os.path.exists(output_folder): os.makedirs(output_folder) j = 1 for i, image_dict in enumerate(images): image = cv2.imread(image_dict['path']) if image is None: raise IOError('Could not open image path', image_dict['path']) for idx, box in enumerate(image_dict['boxes']): ''' print type(image) print image.shape cv2.rectangle(image, (ir(box['x_min']), ir(box['y_min'])), (ir(box['x_max']), ir(box['y_max'])), (0, 255, 0)) print box print image_dict['path'] sys.exit() ''' y1, y2, x1, x2 = ir(box['y_min']), ir(box['y_max']), ir( box['x_min']), ir(box['x_max']) y1 = min(max(0, y1), 720) y2 = min(max(0, y2), 720) x1 = min(max(0, x1), 1280) x2 = min(max(0, x2), 1280) if y2 > y1 and x2 > x1: img = image[y1:y2, x1:x2, :] cv2.imwrite( os.path.join( output_folder, str(i).zfill(10) + '_' + str(idx) + '_' + box['label'] + '_' + os.path.basename(image_dict['path'])), img)
def crop_label_images(input_yaml, output_folder=None): """ Shows and draws pictures with labeled traffic lights. Can save pictures. :param input_yaml: Path to yaml file :param output_folder: If None, do not save picture. Else enter path to folder """ images = get_all_labels(input_yaml) if not os.path.exists(output_folder): os.makedirs(output_folder) for i, image_dict in enumerate(images): image = cv2.imread(image_dict['path']) if image is None: raise IOError('Could not open image path', image_dict['path']) for idx, box in enumerate(image_dict['boxes']): ''' print type(image) print image.shape cv2.rectangle(image, (ir(box['x_min']), ir(box['y_min'])), (ir(box['x_max']), ir(box['y_max'])), (0, 255, 0)) print box print image_dict['path'] sys.exit() ''' y1, y2, x1, x2 = ir(box['y_min']), ir(box['y_max']), ir( box['x_min']), ir(box['x_max']) y1 = min(max(0, y1), 720) y2 = min(max(0, y2), 720) x1 = min(max(0, x1), 1280) x2 = min(max(0, x2), 1280) if y2 > y1 and x2 > x1: img = image[y1:y2, x1:x2, :] cv2.imwrite( os.path.join( output_folder, str(i).zfill(10) + '_' + str(idx) + '_' + box['label'] + '_' + os.path.basename(image_dict['path'])), img)
def save_tl_images(input_yaml, output_folder): """ Extracts labelled pictures of traffic lights. Saves them as separate files in specified output_folder. :param input_yaml: Path to yaml file :param output_folder: path to folder. created if does not exist """ images = get_all_labels(input_yaml) assert output_folder is not None if not os.path.exists(output_folder): os.makedirs(output_folder) j = 1 for i, image_dict in enumerate(images): image = cv2.imread(image_dict['path']) if image is None: raise IOError('Could not open image path', image_dict['path']) for box in image_dict['boxes']: xmin = ir(box['x_min']) ymin = ir(box['y_min']) xmax = ir(box['x_max']) ymax = ir(box['y_max']) if xmax - xmin <= 0 or ymax - ymin <= 0: continue label = box['label'] roi = image[ymin:(ymax + 1), xmin:(xmax + 1)] filename = os.path.join( output_folder, str(j).zfill(6) + '_' + label.lower() + '.png') #print("{}: {}".format(i, filename)) cv2.imwrite(filename, roi) if os.stat(filename).st_size == 0: os.remove(filename) print("saved file is zero size, deleting: {} {}".format( i, filename)) j += 1
def quick_stats(input_yaml): """ Prints statistic data for the traffic light yaml files. :param input_yaml: Path to yaml file of published traffic light set """ LABEL_DICT = {"Off": 0, "Red": 1, "Yellow": 2, "Red-yellow": 3, "Green": 4} LABEL_DICT_R = {v: k for k, v in LABEL_DICT.items()} LABEL_DICT_P = { "Circle": 0, "Straight": 1, "Left": 2, "StraightLeft": 3, "Right": 4, "Pedestrian": 8, "Bike": 9 } # classes are saved as in bstld LABEL_DICT_P_R = {v: k for k, v in LABEL_DICT_P.items()} images = get_all_labels(input_yaml) widths = [] heights = [] sizes = [] num_images = len(images) num_lights = 0 appearances = { "Off": 0, "Red": 0, "Yellow": 0, "Red-yellow": 0, "Green": 0 } appearances_P = { "Circle": 0, "Straight": 0, "Left": 0, "StraightLeft": 0, "Right": 0, "Pedestrian": 0, "Bike": 0 } large = 0 medium = 0 small = 0 counter = 0 for image in tqdm(images): num_lights += len(image['objects']) for box in image['objects']: if box['width'] <= width_limit: continue widths.append(box['width']) heights.append(box['height']) class_str = str(box['class_id'])[-2] # class_str_P=str(box['class_id'])[-1] appearances[LABEL_DICT_R[int(class_str)]] += 1 # appearances_P[LABEL_DICT_P_R[int(class_str_P)]]+=1 size = box['width'] * box['height'] sizes.append(size) if size <= (32 * 32): small += 1 elif size > (96 * 96): large += 1 else: medium += 1 # avg_width = sum(widths) / float(len(widths)) # avg_height = sum(heights) / float(len(heights)) # avg_size = sum(sizes) / float(len(sizes)) # median_width = sorted(widths)[len(widths) // 2] # median_height = sorted(heights)[len(heights) // 2] # median_size = sorted(sizes)[len(sizes) // 2] # print('Number of images:', num_images) print('Number of traffic lights:', num_lights, '\n') print('Small images:', small) print('Medium images:', medium) print('Large images:', large, '\n') # print('Minimum width:', min(widths)) # print('Average width:', avg_width) # print('median width:', median_width) # print('maximum width:', max(widths), '\n') # print('Minimum height:', min(heights)) # print('Average height:', avg_height) # print('median height:', median_height) # print('maximum height:', max(heights), '\n') # print('Minimum size:', min(sizes)) # print('Average size:', avg_size) # print('median size:', median_size) # print('maximum size:', max(sizes), '\n') print('Labels:') for key, label in appearances.items(): print('\t{}: {}'.format(key, label)) print()
def main(): createFolder() trainData = get_all_labels(DATA_DIR + "/rgb_train/train.yaml") print("trainData length: " + str(len(trainData))) # don't shuffle for this (so we can easily run multiple programs at the same time) indices = [i for i in range(len(trainData))] #indices = indices[1500:2000] # did this for each process in batches of 500 random.shuffle(indices) print("LOOKING FOR FALSE POSITIVES") #indices = indices[:1000] # TODO: number of images to sample fileCount = 0 imageCount = 0 ##################################### # Read the image min_wdw_sz = (24, 48) step_size = (5, 5) downscale = 1.25 # Load the classifier # TODO: update to desired model # model4 is from run2 (all images, and 15ish "other" per image, but train was limited to 20,000 from "other") clf = joblib.load("../myData/traffic.model5") ##################################### #fds = [] # all features (need to include ones that are not traffic lights as well) # extract patches from images and save them to labeled folders for i in indices: i = 137 curCount = 0 # number of patches from this image so far loc = i imageCount += 1 info = trainData[i] im = cv2.imread(DATA_DIR + "/rgb_train/train/" + info['path'], cv2.IMREAD_GRAYSCALE) if fileCount % 100 == 0: print("patches saved so far: " + str(fileCount)) print("images so far: " + str(imageCount)) imageCopy = cv2.cvtColor(im.copy(),cv2.COLOR_GRAY2RGB) # copy to draw rectangles on ##################################### for im_scaled in pyramid_gaussian(im, downscale=downscale): # This list contains detections at the current scale cd = [] # If the width or height of the scaled image is less than # the width or height of the window, then end the iterations. if im_scaled.shape[0] < min_wdw_sz[1] or im_scaled.shape[1] < min_wdw_sz[0]: break for (x, y, im_window) in sliding_window(im_scaled, min_wdw_sz, step_size): if im_window.shape[0] != min_wdw_sz[1] or im_window.shape[1] != min_wdw_sz[0]: continue # Calculate the HOG features # TODO!!!: is it a problem that im_window is grayscale floats? will that mess with my SVM which was trained with grayscale images from 0-255? fd = hog(im_window, orientations, pixels_per_cell, cells_per_block, block_norm="L1", visualise=False, transform_sqrt=True, feature_vector=True) fd = [fd] # clf wants a list of samples # TODO: it's faster to pass all the samples to clf at once to predict on #pred = clf.predict(fd) probs = list(clf.predict_proba(fd)[0]) #print(pred) pred = probs.index(max(probs)) # index of max if pred != 0 and probs[pred] > 0.95: # check if this is a false positive (need to find its rect) # calculate (approximate) rect for this region (24x48) scaleF = im.shape[0] / im_scaled.shape[0] scaleF2 = im.shape[1] / im_scaled.shape[1] if scaleF2 > scaleF: # take the bigger one scaleF = scaleF2 # TODO: fix problem where some correct traffic lights are ending up in the falsePositives (I'm pretty sure of this but it's a little hard to tell with some of them) rect = Rectangle(y, y+int(48/scaleF), x, x+int(25/scaleF)) print("\n" + str(loc) + ": " + str(rect)) #test = getRegion(im, rect) # TODO: does this function not work??? (see above problem TODO) if not isALight(rect, info['boxes']): isLight = "NOT LIGHT" cv2.rectangle(imageCopy, (int(rect.xmin),int(rect.ymin)+1), (int(rect.xmax),int(rect.ymax)+1), [255,0,0], 2) saveImage(im_window, None, "fp-" + str(loc) + "-" + str(curCount), "falsePositives", convert=True) # im_window is float (values from 0 to 1) so convert: else: isLight = "LIGHT" cv2.rectangle(imageCopy, (int(rect.xmin),int(rect.ymin)+1), (int(rect.xmax),int(rect.ymax)+1), [0,255,0], 2) # store positive matches as well for reference: saveImage(im_window, None, "p-" + str(loc) + "-" + str(curCount), "positives", convert=True) fileCount += 1 curCount += 1 # TODO: there is a definite bug here where some patches are incorrectly believed to # be a light or not a light (might be a problem with how rect is created) # once instance of the problem is apprent in image 137, patch 11 saveImage(imageCopy, None, "typ-summary-" + str(loc) + "summaries", "summaries") if curCount == 11: print("" + str(curCount) + ": " + str(rect)) plt.imshow(im_window) plt.title(isLight) plt.show() copy2 = cv2.cvtColor(im.copy(),cv2.COLOR_GRAY2RGB) # copy to draw rectangles on cv2.rectangle(copy2, (int(rect.xmin),int(rect.ymin)+1), (int(rect.xmax),int(rect.ymax)+1), [255,0,0], 2) plt.imshow(copy2) plt.title(isLight) plt.show() ##################################### saveImage(imageCopy, None, "summary-" + str(loc) + "summaries", "summaries") return print("*** Completed looking for false positiives ***") print("TOTAL patches saved: " + str(fileCount))
images[i]['path'] = images[i]['path'].replace('.png', '.pgm') images[i]['path'] = images[i]['path'].replace( 'rgb/train', 'riib/train') images[i]['path'] = images[i]['path'].replace( 'rgb/test', 'riib/test') for box in images[i]['boxes']: box['y_max'] = box['y_max'] + 8 box['y_min'] = box['y_min'] + 8 return images ''' Crops each image to show only the traffic light while annotating the original image. Stores the annotations and cropped images in separate folders by label. ''' images = get_all_labels( '/home/felix/Downloads/Computer Vision Project/test.yaml') for image in images: image_path = image['path'] image_id = image_path.split('/')[-1] img = cv2.imread( '/home/felix/Downlaods/Computer Vision Project/rgb/test/' + image_id, 1) for box in image['boxes']: y1 = int(box['y_min']) x1 = int(box['x_min']) y2 = int(box['y_max']) x2 = int(box['x_max']) if (y2 - y1 > 10) and (x2 - x1 > 5):
def show_label_images(input_yaml, wait_ms=10): """ Shows and draws pictures with labeled traffic lights. Can save pictures. :param input_yaml: Path to yaml file :param wait_ms: wait time in milliseconds before OpenCV shows next image """ label_list = {'off': 0, 'green': 1, 'yellow': 2, 'red': 3} # load the model tlc = TLClassifierCNN() model_dir = 'model' tlc.load_model(model_dir) # Shows and draws pictures with labeled traffic lights images = get_all_labels(input_yaml) for i, image_dict in enumerate(images): image = cv2.imread(image_dict['path']) if image is None: raise IOError('Could not open image path', image_dict['path']) break for box in image_dict['boxes']: xmin = ir(box['x_min']) ymin = ir(box['y_min']) xmax = ir(box['x_max']) ymax = ir(box['y_max']) if xmax - xmin <= 0 or ymax - ymin <= 0: continue label = box['label'] label = label.lower() roi = image[ymin:(ymax + 1), xmin:(xmax + 1)] resized_roi = cv2.resize(roi, (32, 32), interpolation=cv2.INTER_LINEAR) prd_labels, prd_probabilities = tlc.predict(np.array([resized_roi ]), batch_size=1) prd_prob = prd_probabilities[0][label_list[prd_labels[0]]] * 100 if label == prd_labels[0]: cv2.rectangle(image, (xmin, ymin), (xmax, ymax), (0, 255, 0)) label_str = '%s(%.2f)' % (prd_labels[0], prd_prob) image = cv2.putText(image, label_str, (xmin, ymax + 20), 0, 0.4, (0, 255, 0), 1, cv2.LINE_AA) # text green else: cv2.rectangle(image, (xmin, ymin), (xmax, ymax), (0, 0, 255)) # color red label_str = '%s: %s(%.2f)' % (label, prd_labels[0], prd_prob) image = cv2.putText(image, label_str, (xmin, ymax + 20), 0, 0.4, (0, 0, 255), 1, cv2.LINE_AA) cv2.imshow('labeled_image', image) #cv2.waitKey(10) if cv2.waitKey(wait_ms) == 27: cv2.destroyAllWindows() break
def quick_stats(input_yaml): """ Prints statistic data for the traffic light yaml files. :param input_yaml: Path to yaml file of published traffic light set """ images = get_all_labels(input_yaml) widths = [] heights = [] sizes = [] num_images = len(images) num_lights = 0 appearances = {'Green': 0, 'occluded': 0} for image in images: num_lights += len(image['boxes']) for box in image['boxes']: try: appearances[box['label']] += 1 except KeyError: appearances[box['label']] = 1 if box['occluded']: appearances['occluded'] += 1 if box['x_max'] < box['x_min']: box['x_max'], box['x_min'] = box['x_min'], box['x_max'] if box['y_max'] < box['y_min']: box['y_max'], box['y_min'] = box['y_min'], box['y_max'] width = box['x_max'] - box['x_min'] height = box['y_max'] - box['y_min'] if width < 0: logging.warning('Box width smaller than one at ' + image) widths.append(width) heights.append(height) sizes.append(width * height) avg_width = sum(widths) / float(len(widths)) avg_height = sum(heights) / float(len(heights)) avg_size = sum(sizes) / float(len(sizes)) median_width = sorted(widths)[len(widths) // 2] median_height = sorted(heights)[len(heights) // 2] median_size = sorted(sizes)[len(sizes) // 2] print('Number of images:', num_images) print('Number of traffic lights:', num_lights, '\n') print('Minimum width:', min(widths)) print('Average width:', avg_width) print('median width:', median_width) print('maximum width:', max(widths), '\n') print('Minimum height:', min(heights)) print('Average height:', avg_height) print('median height:', median_height) print('maximum height:', max(heights), '\n') print('Minimum size:', min(sizes)) print('Average size:', avg_size) print('median size:', median_size) print('maximum size:', max(sizes), '\n') print('Labels:') for key, label in appearances.items(): print('\t{}: {}'.format(key, label))
def try_ext(input_yaml, output_folder): w = int(448) h = int(448) images = get_all_labels(input_yaml) desired_dim = (1280, 720) k = 1 for i, image_dict in enumerate(images): print(k) if not image_dict['boxes']: continue image = cv2.imread(image_dict['path']) image = cv2.resize(image, desired_dim, interpolation=cv2.INTER_LINEAR) pil_img = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) cropped_img1 = pil_img.crop(area1) cropped_img2 = pil_img.crop(area2) cropped_img3 = pil_img.crop(area3) p1 = [] p2 = [] p3 = [] for box in image_dict['boxes']: x0 = float(box['x_min']) y0 = float(box['y_min']) x1 = float(box['x_max']) y1 = float(box['y_max']) if x1 - x0 <= 0 or y1 - y0 <= 0: continue if ((x0 >= 0 and x1 <= 448) and (y0 >= 0 and y1 <= 448)): b = (float(x0), float(x1), float(y0), float(y1)) bb = convert((w, h), b) p1.append(bb) if ((x0 >= 416 and x1 <= 864) and (y0 >= 0 and y1 <= 448)): b = (float(x0 - 416), float(x1 - 416), float(y0), float(y1)) bb = convert((w, h), b) p2.append(bb) if ((x0 >= 832 and x1 <= 1280) and (y0 >= 0 and y1 <= 448)): b = (float(x0 - 832), float(x1 - 832), float(y0), float(y1)) bb = convert((w, h), b) p3.append(bb) if p1: filepath = output_folder + '/' + str(k) + '.txt' out_file = open(filepath, 'w') for bb in p1: out_file.write( str(0) + " " + " ".join([str(a) for a in bb]) + '\n') imagefilepath = output_folder + '/' + str(k) + '.png' cropped_img1.save(imagefilepath, 'PNG') k = k + 1 if p2: filepath = output_folder + '/' + str(k) + '.txt' out_file = open(filepath, 'w') for bb in p2: out_file.write( str(0) + " " + " ".join([str(a) for a in bb]) + '\n') imagefilepath = output_folder + '/' + str(k) + '.png' cropped_img2.save(imagefilepath, 'PNG') k = k + 1 if p3: filepath = output_folder + '/' + str(k) + '.txt' out_file = open(filepath, 'w') for bb in p3: out_file.write( str(0) + " " + " ".join([str(a) for a in bb]) + '\n') imagefilepath = output_folder + '/' + str(k) + '.png' cropped_img3.save(imagefilepath, 'PNG') k = k + 1 if not p1: filepath = output_folder + '/' + str(k) + '.txt' out_file = open(filepath, 'w') imagefilepath = output_folder + '/' + str(k) + '.png' cropped_img1.save(imagefilepath, 'PNG') k = k + 1 if not p2: filepath = output_folder + '/' + str(k) + '.txt' out_file = open(filepath, 'w') imagefilepath = output_folder + '/' + str(k) + '.png' cropped_img2.save(imagefilepath, 'PNG') k = k + 1 if not p3: filepath = output_folder + '/' + str(k) + '.txt' out_file = open(filepath, 'w') imagefilepath = output_folder + '/' + str(k) + '.png' cropped_img3.save(imagefilepath, 'PNG') k = k + 1