def process_image(args, path): global bin_mask, intersects, rotation, img, img_src, center img = cv2.imread(path) if img == None or img.size == 0: logging.info("Failed to read %s" % path) return logging.info("Processing %s..." % path) # Scale the image down if its perimeter exceeds the maximum (if set). img = common.scale_max_perimeter(img, args.max_size) img_src = img.copy() # Perform segmentation logging.info("- Segmenting...") mask = common.grabcut(img, args.iters, None, args.margin) bin_mask = np.where((mask == cv2.GC_FGD) + (mask == cv2.GC_PR_FGD), 255, 0).astype('uint8') # Obtain contours (all points) from the mask. contour = ft.get_largest_contour(bin_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # Fit an ellipse on the contour to get the rotation angle. box = cv2.fitEllipse(contour) rotation = int(box[2]) # Get the shape360 feature. logging.info("- Obtaining shape...") intersects, center = ft.shape_360(contour, rotation) logging.info("- Done") draw_axis()
def split_image(path, args): img = cv2.imread(path) if img == None or img.size == 0: sys.stderr.write("Failed to read %s. Skipping.\n" % path) return -1 logging.info("Processing %s ..." % path) # Scale the image down if its perimeter exceeds the maximum (if set). img = common.scale_max_perimeter(img, args.max_size) logging.info("Segmenting...") # Perform segmentation. mask = common.grabcut(img, args.iters, None, args.margin) # Create a binary mask. Foreground is made white, background black. bin_mask = np.where((mask==cv2.GC_FGD) + (mask==cv2.GC_PR_FGD), 255, 0).astype('uint8') # Split the image into segments. segments = ft.split_by_mask(img, bin_mask) logging.info("Exporting segments...") for i, im in enumerate(segments): if sum(im.shape[:2]) < args.min_size_out: continue name = os.path.basename(path) name = os.path.splitext(name) out_path = "%s_%d%s" % (name[0], i, name[1]) out_path = os.path.join(args.output, out_path) logging.info("\t%s" % out_path) cv2.imwrite(out_path, im) return 0
def process_image(args, path): global img, img_src, outline, box img = cv2.imread(path) if img == None or img.size == 0: logging.error("Failed to read %s" % path) exit(1) logging.info("Processing %s..." % path) # Scale the image down if its perimeter exceeds the maximum (if set). img = common.scale_max_perimeter(img, args.max_size) img_src = img.copy() # Perform segmentation. logging.info("- Segmenting...") mask = common.grabcut(img, args.iters, None, args.margin) bin_mask = np.where((mask == cv2.GC_FGD) + (mask == cv2.GC_PR_FGD), 255, 0).astype('uint8') # Obtain contours (all points) from the mask. contour = ft.get_largest_contour(bin_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # Get bounding rectange of the largest contour. box = cv2.boundingRect(contour) # Get the outline. logging.info("- Obtaining shape...") outline = ft.shape_outline(contour, args.k) # And draw it. logging.info("- Done") draw_outline(0, outline, args.k)
def process_image(args, path): global intersects, rotation, img, img_src, center img = cv2.imread(path) if img == None or img.size == 0: logging.info("Failed to read %s" % path) return logging.info("Processing %s..." % path) # Scale the image down if its perimeter exceeds the maximum (if set). img = common.scale_max_perimeter(img, args.max_size) img_src = img.copy() # Perform segmentation logging.info("- Segmenting...") mask = common.grabcut(img, args.iters, None, args.margin) bin_mask = np.where((mask == cv2.GC_FGD) + (mask == cv2.GC_PR_FGD), 255, 0).astype("uint8") # Obtain contours (all points) from the mask. contour = ft.get_largest_contour(bin_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # Fit an ellipse on the contour to get the rotation angle. box = cv2.fitEllipse(contour) rotation = int(box[2]) # Get the shape360 feature. logging.info("- Obtaining shape...") intersects, center = ft.shape_360(contour, rotation) logging.info("- Done") draw_axis()
def process_image(args, path): global img, img_src img = cv2.imread(path) if img == None or img.size == 0: logging.error("Failed to read %s" % path) exit(1) logging.info("Processing %s..." % path) # Scale the image down if its perimeter exceeds the maximum (if set). img = common.scale_max_perimeter(img, args.max_size) img_src = img.copy() # Perform segmentation logging.info("- Segmenting...") mask = common.grabcut(img, args.iters, None, args.margin) bin_mask = np.where((mask==cv2.GC_FGD) + (mask==cv2.GC_PR_FGD), 255, 0).astype('uint8') contours, hierarchy = cv2.findContours(bin_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Calculate contour properties. logging.info("- Computing contour properties...") props = ft.contour_properties(contours, 'all') # Print properties. pprint.pprint(props) # Draw some properties. draw_props(props)
def process_image(args, path): global img, img_src, outline, box, bin_mask img = cv2.imread(path) if img == None or img.size == 0: logging.error("Failed to read %s" % path) exit(1) logging.info("Processing %s..." % path) # Scale the image down if its perimeter exceeds the maximum (if set). img = common.scale_max_perimeter(img, args.max_size) img_src = img.copy() # Perform segmentation. logging.info("- Segmenting...") mask = common.grabcut(img, args.iters, None, args.margin) bin_mask = np.where((mask==cv2.GC_FGD) + (mask==cv2.GC_PR_FGD), 255, 0).astype('uint8') # Obtain contours (all points) from the mask. contour = ft.get_largest_contour(bin_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # Get bounding rectange of the largest contour. props = ft.contour_properties([contour], 'BoundingRect') box = props[0]['BoundingRect'] # And draw it. logging.info("- Done") draw_sections(0, args.bins)
def _preprocess(self): if self.img == None: raise ValueError("No image loaded") if 'preprocess' not in self.params: return # Scale the image down if its perimeter exceeds the maximum (if set). perim = sum(self.img.shape[:2]) max_perim = getattr(self.params.preprocess, 'maximum_perimeter', None) if max_perim and perim > max_perim: logging.info("Scaling down...") rf = float(max_perim) / perim self.img = cv2.resize(self.img, None, fx=rf, fy=rf) # Perform color enhancement. color_enhancement = getattr(self.params.preprocess, 'color_enhancement', None) if color_enhancement: for method, args in vars(color_enhancement).iteritems(): if method == 'naik_murthy_linear': logging.info("Color enhancement...") self.img = ft.naik_murthy_linear(self.img) else: raise ValueError("Unknown color enhancement method '%s'" % method) # Perform segmentation. segmentation = getattr(self.params.preprocess, 'segmentation', None) if segmentation: logging.info("Segmenting...") iterations = getattr(segmentation, 'iterations', 5) margin = getattr(segmentation, 'margin', 1) output_folder = getattr(segmentation, 'output_folder', None) # Create a binary mask for the largest contour. self.mask = common.grabcut(self.img, iterations, None, margin) self.bin_mask = np.where((self.mask==cv2.GC_FGD) + (self.mask==cv2.GC_PR_FGD), 255, 0).astype('uint8') contour = ft.get_largest_contour(self.bin_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if contour == None: raise ValueError("No contour found for binary image") self.bin_mask = np.zeros(self.img.shape[:2], dtype=np.uint8) cv2.drawContours(self.bin_mask, [contour], 0, 255, -1) # Save the masked image to the output folder. if output_folder and os.path.isdir(output_folder): img_masked = cv2.bitwise_and(self.img, self.img, mask=self.bin_mask) fname = os.path.basename(self.path) out_path = os.path.join(output_folder, fname) cv2.imwrite(out_path, img_masked)
def split_image(path, args): img = cv2.imread(path) if img == None or img.size == 0: sys.stderr.write("Failed to read %s. Skipping.\n" % path) return -1 logging.info("Processing %s ..." % path) # Scale the image down if its perimeter exceeds the maximum (if set). img = common.scale_max_perimeter(img, args.max_size) logging.info("Segmenting...") # Perform segmentation. mask = common.grabcut(img, args.iters, None, args.margin) # Create a binary mask. Foreground is made white, background black. bin_mask = np.where((mask == cv2.GC_FGD) + (mask == cv2.GC_PR_FGD), 255, 0).astype('uint8') # Split the image into segments. segments = ft.split_by_mask(img, bin_mask) logging.info("Exporting segments...") for i, im in enumerate(segments): if sum(im.shape[:2]) < args.min_size_out: continue name = os.path.basename(path) name = os.path.splitext(name) out_path = "%s_%d%s" % (name[0], i, name[1]) out_path = os.path.join(args.output, out_path) logging.info("\t%s" % out_path) cv2.imwrite(out_path, im) return 0
def main(): print __doc__ parser = argparse.ArgumentParser(description='Test image segmentation') parser.add_argument('image', metavar='FILE', help='Input image') parser.add_argument('--iters', metavar='N', type=int, default=5, help="The number of grabCut iterations. Default is 5.") parser.add_argument( '--margin', metavar='N', type=int, default=1, help= "The margin of the foreground rectangle from the edges. Default is 1.") parser.add_argument( '--max-size', metavar='N', type=float, help= "Scale the input image down if its perimeter exceeds N. Default is no scaling." ) parser.add_argument( '--algo', metavar='simple|grabcut', type=str, choices=['simple', 'grabcut'], default='grabcut', help="The segmentation algorithm to use, either 'simple' or 'grabcut'." ) parser.add_argument( '--roi', metavar='x,y,w,h', type=str, help="Region Of Interest, expressed as X,Y,Width,Height in pixel units." ) args = parser.parse_args() img = cv2.imread(args.image) if img == None or img.size == 0: sys.stderr.write("Failed to read %s\n" % args.image) return -1 sys.stderr.write("Processing %s...\n" % args.image) # Scale the image down if its perimeter exceeds the maximum (if set). img = common.scale_max_perimeter(img, args.max_size) # Process region of interest argument roi = None if args.roi != None: roi = args.roi.split(',') roi[0] = int(roi[0]) roi[1] = int(roi[1]) roi[2] = int(roi[2]) roi[3] = int(roi[3]) # Perform segmentation. if args.algo == 'grabcut': mask = common.grabcut(img, args.iters, roi, args.margin) else: mask = common.simple(img, roi) # Create a binary mask. Foreground is made white, background black. bin_mask = np.where((mask == cv2.GC_FGD) + (mask == cv2.GC_PR_FGD), 255, 0).astype('uint8') # Create a binary mask for the largest contour. contour = ft.get_largest_contour(bin_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) mask_contour = np.zeros(bin_mask.shape, dtype=np.uint8) cv2.drawContours(mask_contour, [contour], 0, 255, -1) cv2.drawContours(img, [contour], 0, common.COLOR['green'], 1) # Merge the binary mask with the image. img_masked = cv2.bitwise_and(img, img, mask=bin_mask) img_masked_contour = cv2.bitwise_and(img, img, mask=mask_contour) # Display the image in a window. cv2.namedWindow('image') cv2.imshow('image', img_masked) while True: k = cv2.waitKey(0) & 0xFF if k == ord('o'): cv2.imshow('image', img) elif k == ord('s'): cv2.imshow('image', img_masked) elif k == ord('l'): cv2.imshow('image', img_masked_contour) elif k == ord('q'): break cv2.destroyAllWindows() return 0
def main(): print __doc__ parser = argparse.ArgumentParser(description='Test image segmentation') parser.add_argument('image', metavar='FILE', help='Input image') parser.add_argument('--iters', metavar='N', type=int, default=5, help="The number of grabCut iterations. Default is 5.") parser.add_argument('--margin', metavar='N', type=int, default=1, help="The margin of the foreground rectangle from the edges. Default is 1.") parser.add_argument('--max-size', metavar='N', type=float, help="Scale the input image down if its perimeter exceeds N. Default is no scaling.") parser.add_argument('--algo', metavar='simple|grabcut', type=str, choices=['simple', 'grabcut'], default='grabcut', help="The segmentation algorithm to use, either 'simple' or 'grabcut'.") parser.add_argument('--roi', metavar='x,y,w,h', type=str, help="Region Of Interest, expressed as X,Y,Width,Height in pixel units.") args = parser.parse_args() img = cv2.imread(args.image) if img == None or img.size == 0: sys.stderr.write("Failed to read %s\n" % args.image) return -1 sys.stderr.write("Processing %s...\n" % args.image) # Scale the image down if its perimeter exceeds the maximum (if set). img = common.scale_max_perimeter(img, args.max_size) # Process region of interest argument roi = None if args.roi != None: roi = args.roi.split(',') roi[0] = int(roi[0]) roi[1] = int(roi[1]) roi[2] = int(roi[2]) roi[3] = int(roi[3]) # Perform segmentation. if args.algo == 'grabcut': mask = common.grabcut(img, args.iters, roi, args.margin) else: mask = common.simple(img, roi) # Create a binary mask. Foreground is made white, background black. bin_mask = np.where((mask==cv2.GC_FGD) + (mask==cv2.GC_PR_FGD), 255, 0).astype('uint8') # Create a binary mask for the largest contour. contour = ft.get_largest_contour(bin_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) mask_contour = np.zeros(bin_mask.shape, dtype=np.uint8) cv2.drawContours(mask_contour, [contour], 0, 255, -1) cv2.drawContours(img, [contour], 0, common.COLOR['green'], 1) # Merge the binary mask with the image. img_masked = cv2.bitwise_and(img, img, mask=bin_mask) img_masked_contour = cv2.bitwise_and(img, img, mask=mask_contour) # Display the image in a window. cv2.namedWindow('image') cv2.imshow('image', img_masked) while True: k = cv2.waitKey(0) & 0xFF if k == ord('o'): cv2.imshow('image', img) elif k == ord('s'): cv2.imshow('image', img_masked) elif k == ord('l'): cv2.imshow('image', img_masked_contour) elif k == ord('q'): break cv2.destroyAllWindows() return 0