def test_deep_same(self): finder = DeepFinder() # pattern matching is not perfect finder.params["find"]["similarity"].value = 0.95 matches = finder.find(Pattern('cat'), Image('coco_cat')) # verify match accuracy self.assertEqual(len(matches), 1) self.assertAlmostEqual(matches[0].x, 90, delta=5) self.assertAlmostEqual(matches[0].y, 345, delta=5) self.assertAlmostEqual(matches[0].width, 515, delta=5) self.assertAlmostEqual(matches[0].height, 805, delta=5) # verify dumped files count and names dumps = self._verify_and_get_dumps(6) self._verify_dumped_images('cat', 'coco_cat', dumps, "deep") hotmaps = sorted(self._get_matches_in('.*hotmap.*', dumps)) self.assertEqual(len(hotmaps), 3) for i, hotmap in enumerate(hotmaps): if i == 0: self.assertIn('3hotmap', hotmap) # report achieved similarity in the end of the filename self.assertRegex(hotmap, ".*-\d\.\d+.*") else: self.assertIn('%sf' % i, hotmap) self.assertTrue(os.path.isfile(os.path.join(self.logpath, hotmap))) finder.configure_backend("tensorflow", "deep") with self.assertRaises(ImportError): finder.synchronize_backend() with self.assertRaises(NotImplementedError): finder.find(Pattern('cat'), Image('coco_cat'))
def test_cascade_viewport(self): finder = CascadeFinder() matches = finder.find(Pattern('n_ibs.xml'), Image('h_ibs_viewport')) self.assertEqual(len(matches), 1) # the original needle image was 150x150 with larger white margins self.assertAlmostEqual(matches[0].x, 20, delta=5) self.assertAlmostEqual(matches[0].y, 20, delta=5) # near square shape is due to the positive images used for training self.assertAlmostEqual(matches[0].width, 250, delta=10) self.assertAlmostEqual(matches[0].height, 250, delta=10)
def test_cascade_nomatch(self): finder = CascadeFinder() # no similarty parameter is supported - this is a binary match case finder.params["find"]["similarity"].value = 0.0 matches = finder.find(Pattern('n_ibs.xml'), Image('all_shapes')) # verify match accuracy self.assertEqual(len(matches), 0) # verify dumped files count and names dumps = self._verify_and_get_dumps(4) self._verify_dumped_images('n_ibs', 'all_shapes', dumps, "cascade") self._verify_single_hotmap(dumps, "cascade")
def test_deep_cache(self): finder = DeepFinder(synchronize=False) finder.params["deep"]["arch"].value = "fasterrcnn_resnet50_fpn" finder.synchronize_backend() matches = finder.find(Pattern('cat'), Image('coco_cat')) self.assertEqual(len(matches), 1) self.assertEqual(len(finder._cache.keys()), 1) self.assertEqual(finder._cache[finder.params["deep"]["arch"].value], finder.net) matches = finder.find(Pattern('cat'), Image('coco_cat')) self.assertEqual(len(matches), 1) self.assertEqual(len(finder._cache.keys()), 1) self.assertEqual(finder._cache[finder.params["deep"]["arch"].value], finder.net) finder.params["deep"]["arch"].value = "maskrcnn_resnet50_fpn" finder.synchronize_backend() matches = finder.find(Pattern('cat'), Image('coco_cat')) self.assertEqual(len(matches), 1) self.assertEqual(len(finder._cache.keys()), 2) self.assertEqual(finder._cache[finder.params["deep"]["arch"].value], finder.net)
def test_cascade_same(self): finder = CascadeFinder() # no similarty parameter is supported - this is a binary match case finder.params["find"]["similarity"].value = 0.0 matches = finder.find(Pattern('shape_blue_circle.xml'), Image('all_shapes')) # verify match accuracy self.assertEqual(len(matches), 1) self.assertAlmostEqual(matches[0].x, 104, delta=5) self.assertAlmostEqual(matches[0].y, 10, delta=5) self.assertAlmostEqual(matches[0].width, 165, delta=10) self.assertAlmostEqual(matches[0].height, 151, delta=10) # verify dumped files count and names dumps = self._verify_and_get_dumps(4) self._verify_dumped_images('shape_blue_circle', 'all_shapes', dumps, "cascade") self._verify_single_hotmap(dumps, "cascade")
def test_deep_nomatch(self): finder = DeepFinder() finder.params["find"]["similarity"].value = 0.25 matches = finder.find(Pattern('cat'), Image('all_shapes')) # verify match accuracy self.assertEqual(len(matches), 0) # verify dumped files count and names dumps = self._verify_and_get_dumps(6) self._verify_dumped_images('cat', 'all_shapes', dumps, "deep") hotmaps = sorted(self._get_matches_in('.*hotmap.*', dumps)) self.assertEqual(len(hotmaps), 3) for i, hotmap in enumerate(hotmaps): if i == 0: self.assertIn('3hotmap', hotmap) # report achieved similarity in the end of the filename self.assertRegex(hotmap, ".*-\d\.\d+.*") else: self.assertIn('%sf' % i, hotmap) self.assertTrue(os.path.isfile(os.path.join(self.logpath, hotmap)))
finder.net = FasterRCNN(backbone, num_classes=len(dataset.classes)) elif "mask" in finder.params["deep"]["arch"].value: from torchvision.models.detection.mask_rcnn import MaskRCNN finder.net = MaskRCNN(backbone, num_classes=len(dataset.classes)) # TODO: eventually support keypoint R-CNN if it shows to be promising #elif "keypoint" in finder.params["deep"]["arch"].value: # from torchvision.models.detection.keypoint_rcnn import KeypointRCNN # finder.net = KeypointRCNN(backbone, num_classes=len(dataset.classes)) else: raise ValueError( f'Invalid choice of architecture: {finder.params["deep"]["arch"].value}' ) finder.net.to(device) # Train and test the network for epoch in range(1, hyperparams["epochs"] + 1): train(epoch, finder.net, train_loader, device, hyperparams) test(epoch, finder.net, test_loader, device, hyperparams) # Evaluate the trained network on a single test sample with image logging NEEDLE = Pattern("1") HAYSTACK = Image('some_buttons') matches = finder.find(NEEDLE, HAYSTACK) # Final cleanup steps if REMOVE_LOGPATH: shutil.rmtree(LOGPATH) GlobalConfig.image_logging_level = logging.ERROR GlobalConfig.image_logging_destination = "./imglog" GlobalConfig.image_logging_step_width = 3
def test_cascade_rotation(self): finder = CascadeFinder() matches = finder.find(Pattern('n_ibs.xml'), Image('h_ibs_rotated'))