def _make_detection_dataset( img, images_dir, num_samples=4, num_objects_per_sample=3 ): exts = [".jpg", ".png"] samples = [] for idx in range(num_samples): filepath = os.path.join( images_dir, "%06d%s" % (idx, exts[idx % len(exts)]) ) etai.write(img, filepath) detections = [] for _ in range(num_objects_per_sample): label = random.choice(["cat", "dog", "bird", "rabbit"]) bounding_box = [ 0.8 * random.random(), 0.8 * random.random(), 0.2, 0.2, ] detections.append( fo.Detection(label=label, bounding_box=bounding_box) ) samples.append( fo.Sample( filepath=filepath, ground_truth=fo.Detections(detections=detections), ) ) dataset = fo.Dataset() dataset.add_samples(samples) return dataset
def _perform_canny_edge_detection(canny_edge_config): for data in canny_edge_config.data: in_img = etai.read(data.input_image) sobel_horiz = np.load(data.sobel_horizontal_result)["filtered_matrix"] sobel_vert = np.load(data.sobel_vertical_result)["filtered_matrix"] (g_intensity, orientation) = _create_intensity_orientation_matrices( sobel_horiz, sobel_vert) if data.gradient_intensity is not None: etai.write(g_intensity, data.gradient_intensity) if data.gradient_orientation is not None: etai.write(orientation, data.gradient_orientation) np.save('out/gradient_orientation.npy', orientation) etai.write(g_intensity, 'out/g_intensity.jpg') g_suppressed = _non_maximum_suppression(g_intensity, orientation, in_img) etai.write(g_suppressed, 'out/g_suppressed.jpg') g_thresholded = _double_thresholding( g_suppressed, canny_edge_config.parameters.low_threshold, canny_edge_config.parameters.high_threshold) g_strong = _hysteresis(g_thresholded, canny_edge_config.parameters.low_threshold, canny_edge_config.parameters.high_threshold) g_strong = g_strong.astype(int) #sio.savemat('/home/zixu/canny.mat',dict([('in_img',in_img),('sobel_horiz',sobel_horiz),('sobel_vert',sobel_vert),('g_intensity',g_intensity),('orientation',orientation),('g_suppressed',g_suppressed),('g_thresholded',g_thresholded),('g_strong',g_strong)])) etai.write(g_strong, data.image_edges)
def draw_labeled_image(sample, label_fields, outpath, annotation_config=None): """Draws an annotated version of the image sample with its label field(s) overlaid to disk. Args: sample: a :class:`fiftyone.core.sample.Sample` instance label_fields: the list of :class:`fiftyone.core.labels.ImageLabel` fields to render outpath: the path to write the annotated image annotation_config (None): an :class:`AnnotationConfig` specifying how to render the annotations """ if annotation_config is None: annotation_config = _DEFAULT_ANNOTATION_CONFIG image_labels = etai.ImageLabels() for label_field in label_fields: label = sample[label_field] if label is None: continue image_labels.merge_labels(label.to_image_labels(name=label_field)) img = etai.read(sample.filepath) anno_img = etaa.annotate_image(img, image_labels, annotation_config=annotation_config) etai.write(anno_img, outpath)
def download_dataset(): print("Downloading dataset of %d samples to:\n\t%s" % (DATASET_SIZE, DATASET_DIR)) print("and corrupting the data (%d%% duplicates)" % (100 * CORRUPTION_RATE)) # if not empty, delete current contents etau.ensure_empty_dir(DATASET_DIR, cleanup=True) (_, _), (x_test, y_test) = cifar100.load_data(label_mode="fine") dataset_size = min(DATASET_SIZE, 10000) x = x_test[:dataset_size, :] y = y_test[:dataset_size, :] for i in range(x.shape[0]): if random.random() > 0.95: # pick a random sample 5% of the time idx = random.randint(0, x.shape[0]) else: idx = i # get label fine_label = FINE_CLASSES[y[idx, 0]] # read image img = x[idx, :] rel_img_path = os.path.join(fine_label, "%d.jpg" % i) abs_img_path = os.path.join(DATASET_DIR, rel_img_path) etai.write(img, abs_img_path) print("Download successful")
def export_sample(self, image_or_path, classification, metadata=None): is_image_path = self._is_image_path(image_or_path) _label = _parse_classification(classification) if _label is None: _label = "_unlabeled" self._class_counts[_label] += 1 if is_image_path: image_path = image_or_path else: img = image_or_path image_path = self._default_filename_patt % ( self._class_counts[_label]) filename = os.path.basename(image_path) name, ext = os.path.splitext(filename) key = (_label, filename) self._filename_counts[key] += 1 count = self._filename_counts[key] if count > 1: filename = name + ("-%d" % count) + ext out_image_path = os.path.join(self.export_dir, _label, filename) if is_image_path: etau.copy_file(image_path, out_image_path) else: etai.write(img, out_image_path)
def _stitch_images(image_stitching_config): for data in image_stitching_config.data: # Load the corner locations img1_corners = np.load(data.corner_locs_1)["corner_locations"] img2_corners = np.load(data.corner_locs_2)["corner_locations"] # Read in the input images img1 = etai.read(data.image_1) img2 = etai.read(data.image_2) # Compute HOG feature vectors for every detected corner hog_features_1 = _get_HOG_descriptors(img1_corners, img1) hog_features_2 = _get_HOG_descriptors(img2_corners, img2) # Match the feature vectors img_1_pts, img_2_pts = _match_keypoints(hog_features_1, hog_features_2, img1_corners, img2_corners, img1, img2) # Tune this parameter in "requests/image_stitching_request.json" # to specify the number of corresponding points to use when computing # the homography matrix no_correspondence = image_stitching_config.parameters.no_correspondence # Compute the homography matrix that relates image 1 and image 2 H = _get_homography(img_1_pts[1:no_correspondence + 1], img_2_pts[1:no_correspondence + 1]) # Stitching the images by applying the homography matrix to image 2 final_img = _overlap(img1, img2, H) # Write the final stitched image etai.write(final_img, data.stitched_image)
def _make_image_labels_dataset(img, images_dir, num_samples=4, num_objects_per_sample=3): exts = [".jpg", ".png"] samples = [] for idx in range(num_samples): filepath = os.path.join(images_dir, "%06d%s" % (idx, exts[idx % len(exts)])) etai.write(img, filepath) image_labels = etai.ImageLabels() _label = random.choice(["sun", "rain", "snow"]) image_labels.add_attribute(etad.CategoricalAttribute("label", _label)) for _ in range(num_objects_per_sample): _label = random.choice(["cat", "dog", "bird", "rabbit"]) _xtl = 0.8 * random.random() _ytl = 0.8 * random.random() _bounding_box = etag.BoundingBox.from_coords( _xtl, _ytl, _xtl + 0.2, _ytl + 0.2) image_labels.add_object( etao.DetectedObject(label=_label, bounding_box=_bounding_box)) samples.append( fo.Sample( filepath=filepath, ground_truth=fo.ImageLabels(labels=image_labels), )) dataset = fo.Dataset() dataset.add_samples(samples) return dataset
def _make_multilabel_dataset(img, images_dir): image_path = os.path.join(images_dir, "image.jpg") etai.write(img, image_path) sample = fo.Sample.from_dict( { "filepath": image_path, "tags": [], "metadata": { "_cls": "ImageMetadata", "size_bytes": 53219, "mime_type": "image/jpeg", "width": 1280, "height": 720, "num_channels": 3, }, "gt_weather": {"_cls": "Classification", "label": "overcast"}, "gt_scene": {"_cls": "Classification", "label": "city street"}, "gt_timeofday": {"_cls": "Classification", "label": "daytime"}, "gt_objs": { "_cls": "Detections", "detections": [ { "_cls": "Detection", "label": "traffic sign", "bounding_box": [ 0.7817958921875, 0.39165613194444443, 0.031193851562499986, 0.06238770138888894, ], "attributes": { "occluded": { "_cls": "BooleanAttribute", "value": False, }, "truncated": { "_cls": "BooleanAttribute", "value": False, }, "trafficLightColor": { "_cls": "CategoricalAttribute", "value": "none", }, }, } ], }, "uniqueness": 0.5432120379367298, } ) dataset = fo.Dataset() dataset.add_sample(sample) return dataset
def _make_labeled_dataset_with_no_labels(img, images_dir): filepath = os.path.join(images_dir, "test.png") etai.write(img, filepath) dataset = fo.Dataset() dataset.add_sample(fo.Sample(filepath=filepath)) dataset.add_sample_field("ground_truth", fo.EmbeddedDocumentField, embedded_doc_type=fo.Label) dataset.info = { # FiftyOneImageClassificationDataset # FiftyOneImageDetectionDataset "classes": ["cat", "dog"], # COCODetectionDataset "year": "5151", "version": "5151", "description": "Brian's Dataset", "contributor": "Brian Moore", "url": "https://github.com/brimoor", "date_created": "5151-51-51T51:51:51", "licenses": ["license1", "license2"], # CVATImageDataset "task_labels": [ { "name": "cat", "attributes": [{ "name": "fluffy", "categories": ["yes", "no"] }], }, { "name": "dog", "attributes": [{ "name": "awesome", "categories": ["yes", "of course"] }], }, ], } dataset.save() return dataset
def _make_classification_dataset(img, images_dir, num_samples=4): exts = [".jpg", ".png"] samples = [] for idx in range(num_samples): filepath = os.path.join(images_dir, "%06d%s" % (idx, exts[idx % len(exts)])) etai.write(img, filepath) label = random.choice(["sun", "rain", "snow"]) samples.append( fo.Sample(filepath=filepath, ground_truth=fo.Classification(label=label))) dataset = fo.Dataset() dataset.add_samples(samples) return dataset
def _perform_convolution(convolution_config): '''Performs convolution of an input image with a kernel specified by the configuration parameters, and writes the result to the path specified by "filtered_image". Args: convolution_config: the configuration file for the module ''' kernel_type = convolution_config.parameters.kernel_type if kernel_type == "x_derivative": kernel = _create_x_derivative_kernel() elif kernel_type == "y_derivative": kernel = _create_y_derivative_kernel() elif kernel_type == "sobel_vertical": kernel = _create_sobel_vertical_kernel() elif kernel_type == "sobel_horizontal": kernel = _create_sobel_horizontal_kernel() else: # this will be the Gaussian kernel # (make sure to remove this comment!) kernel = _create_gaussian_kernel( convolution_config.parameters.gaussian_sigma) for data in convolution_config.data: in_img = etai.read(data.input_image) if convolution_config.parameters.image_type == "grayscale": in_img = etai.rgb_to_gray(in_img) else: # if the image should be a color image, convert the grayscale # image to color (simply converts the image into a 3-channel # image) if etai.is_gray(in_img): in_img = etai.gray_to_rgb(in_img) if convolution_config.parameters.image_max_range == 1: in_img = (in_img.astype(float)) / 255.0 filtered_image = _convolve(kernel, in_img) if data.filtered_matrix: etau.ensure_basedir(data.filtered_matrix) np.savez(data.filtered_matrix, filtered_matrix=filtered_image) if data.filtered_image: etau.ensure_basedir(data.filtered_image) etai.write(filtered_image, data.filtered_image)
def get_patchsize(image): print("---Finding the best patch size---") img = cv2.imread(image) img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) etai.write(img, 'test/a.png') out_dir = 'test/' diff = [i / 10 for i in range(50, 100, 2)] dom = 200 sigmas = [] for d in diff: if dom <= 0: break sigmas.append(5 / dom) dom -= d filtered = [] for sigma in sigmas: filt = _create_gaussian_kernel(sigma) filtered.append(convolve(img, filt).astype('int')) pott_diff = [] pott = [] last_pott = 0 for i in range(len(filtered) - 1): diff = filtered[i + 1] - filtered[i] pe = _calculate_potts_energy(diff) pott_diff.append(pe - last_pott) last_pott = pe pott.append(pe) #print("Pott energy of {}.jpg(sigma={}) is: {}"\ # .format(i,np.round(sigmas[i],3),np.round(pe,2))) etai.write(diff * 255 / max(1, np.max(diff)), out_dir + '{}.jpg'.format(i)) best_index = np.argmax(np.array(pott_diff)[1:]) + 1 #print("Best sigma is: {} in test/{}.jpg.".format(np.round(sigmas[best_index],3), best_index)) patchsize = (2 * np.prod(img.shape) - np.sum(img.shape)) // pott[best_index] * 2 + 3 patchsize = min(patchsize, 19) print("Best patchsize is {}.".format(patchsize)) return patchsize
def _export_image_or_path(image_or_path, filename_maker): """Exports the image, using the given :class:`fiftyone.core.utils.UniqueFilenameMaker` to generate the output path for the image. Args: image_or_path: an image or the path to the image on disk filename_maker: a :class:`fiftyone.core.utils.UniqueFilenameMaker` to use to generate the output image path Returns: the path to the exported image """ if ExportsImages._is_image_path(image_or_path): image_path = image_or_path out_image_path = filename_maker.get_output_path(image_path) etau.copy_file(image_path, out_image_path) else: img = image_or_path out_image_path = filename_maker.get_output_path() etai.write(img, out_image_path) return out_image_path
def draw_labeled_image(sample, outpath, label_fields=None, annotation_config=None): """Draws an annotated version of the image sample with its label field(s) overlaid to disk. Args: sample: a :class:`fiftyone.core.sample.Sample` instance outpath: the path to write the annotated image label_fields (None): a list of :class:`fiftyone.core.labels.ImageLabel` fields to render. If omitted, all compatiable fields are rendered annotation_config (None): an :class:`AnnotationConfig` specifying how to render the annotations """ if label_fields is None: label_fields = _get_image_label_fields(sample) if annotation_config is None: annotation_config = AnnotationConfig.default() image_labels = etai.ImageLabels() for label_field in label_fields: label = sample[label_field] if label is None: continue image_labels.merge_labels(label.to_image_labels(name=label_field)) img = etai.read(sample.filepath) anno_img = etaa.annotate_image(img, image_labels, annotation_config=annotation_config) etai.write(anno_img, outpath)
def _find_corners(harris_corner_config): for data in harris_corner_config.data: sobel_horiz = np.load(data.sobel_horizontal_result)["filtered_matrix"] sobel_vert = np.load(data.sobel_vertical_result)["filtered_matrix"] corner_response, corner_locations = _get_harris_corner( sobel_horiz, sobel_vert, harris_corner_config.parameters.window_half_size, harris_corner_config.parameters.threshold) corner_locs_after_sup = non_max_suppression( corner_response, harris_corner_config.parameters.non_max_radius) if data.corner_locations: etau.ensure_basedir(data.corner_locations) np.savez(data.corner_locations, corner_locations=corner_locs_after_sup) if data.corners_img_before_sup or data.corners_img_after_sup: in_img = etai.read(data.input_image) if data.corners_img_before_sup: corners_viz_before_sup = _visualize_corners( in_img, corner_locations) etai.write(corners_viz_before_sup, data.corners_img_before_sup) if data.corners_img_after_sup: corners_viz_after_sup = _visualize_corners( in_img, corner_locs_after_sup) etai.write(corners_viz_after_sup, data.corners_img_after_sup)
def _ingest_in_memory_image(self, sample_parser): img = sample_parser.get_image() image_path = self._filename_maker.get_output_path() etai.write(img, image_path) return image_path
def _filter_image(steerable_filter_config): for data in steerable_filter_config.data: sobel_horiz = np.load(data.sobel_horizontal_result)["filtered_matrix"] sobel_vert = np.load(data.sobel_vertical_result)["filtered_matrix"] filtered_image = _apply_steerable_filter(sobel_horiz, sobel_vert) etai.write(filtered_image, data.filtered_image)
def _get_harris_corner(Gx, Gy, window_half_size, threshold): '''Performs Harris corner detection. The output will be a matrix, the same size as Gx and Gy, where every element (pixel) contains the corner strength at that location. The corner strength is defined to be the minimum eigenvalue of the structure tensor at that pixel location. Args: Gx: The x-derivative of the image, which is the output of convolving with the horizontal sobel kernel Gy: the y-derivative of the image, which is the output of convolving with the vertical sobel kernel window_half_size: the half-size of the window to consider when computing the structure tensor threshold: the lower-bound threshold to use when choosing corners Returns: corner_response_matrix: a matrix, the same size as Gx and Gy, where every element (pixel) contains the corner strength at that location. corner_location_matrix: an Nx2 matrix, where every row is the location of a corner whose response is greater than the threshold. The matrix should also be sorted by corner strength, such that the corner with the highest corner strength is put in row 0 and the corner with the lowest corner strength is put in row N-1. ''' h11 = 0 h22 = 0 h_cross = 0 corner_response_matrix = np.zeros(Gx.shape) col_zeros = np.zeros((Gx.shape[0], window_half_size)) # column of zeros row_zeros = np.zeros( (window_half_size, Gx.shape[1] + (window_half_size * 2))) # row of zeros padded_matrix = np.hstack((col_zeros, corner_response_matrix, col_zeros)) padded_matrix = np.vstack((row_zeros, padded_matrix, row_zeros)) # print("col_zeros = ", col_zeros.shape) # print("row_zeros = ", row_zeros.shape) # print("padded matrix size =", padded_matrix.shape) Gx_2 = np.square(Gx) # square Gx and Gy via Gy_2 = np.square(Gy) # element-wise squaring for i in range(0, corner_response_matrix.shape[0]): for j in range(0, corner_response_matrix.shape[1]): temp_X = Gx_2[i - window_half_size:i + window_half_size + 1, j - window_half_size:j + window_half_size + 1] temp_Y = Gy_2[i - window_half_size:i + window_half_size + 1, j - window_half_size:j + window_half_size + 1] h11 = np.sum(temp_X) # sum of squared elements in window of Gx h22 = np.sum(temp_Y) # sum of squared elements in window of Gy h_cross = np.sum(np.multiply( temp_X, temp_Y)) # element-wise multiplication H = np.array([[h11, h_cross], [h_cross, h22]]) # 'H' is structure tensor vals = np.linalg.eigvals(H) if min(vals) > threshold: corner_response_matrix[i, j] = min( vals) # store eigenval if greater than threshold else: corner_response_matrix[i, j] = 0 c = np.where( corner_response_matrix > 0) # returns indices at located corners eigens = corner_response_matrix[ c] # (2xN) matrix - eigenvalues at each index eigens = np.reshape(eigens, (1, np.shape(eigens)[0])) # (1xN) matrix stack_it = np.vstack((eigens, c)) # (3xN) matrix stack_it = np.transpose(stack_it) # (Nx3) matrix sorted_indices = np.sort( stack_it, axis=0)[::-1] # sorts by eigenvalue - [::-1] makes it descending order corner_location_matrix = sorted_indices[:, 1: 3] # location matrix is just (x,y) coords. # print("Size of Gx = ",Gx.shape) # print("Size of Gy = ",Gy.shape) # print("Size of corner response = ",corner_response_matrix.shape) # print("Size of location response = ",corner_location_matrix.shape) etai.write(corner_response_matrix * 255, "Response.png") return corner_response_matrix, corner_location_matrix