def test_load_images(self): "Load document's images" source = TESTDATA / 'shapes.inselect' with temp_directory_with_files(TESTDATA / 'shapes.inselect') as tempdir: doc_temp = tempdir / 'shapes.inselect' with doc_temp.open('w') as outfile, source.open() as infile: outfile.write(infile.read()) # Document load with neither scanned image file nor thumbnail self.assertRaises(InselectError, InselectDocument.load, doc_temp) # Document load with thumbnail but no scanned image file thumbnail_temp = tempdir / 'shapes_thumbnail.jpg' thumbnail_temp.touch() # File only needs to exist doc = InselectDocument.load(doc_temp) self.assertFalse(doc.scanned.available) self.assertTrue(doc.thumbnail.available) # Document load with both scanned and thumbnail files scanned_temp = tempdir / 'shapes.png' scanned_temp.touch() # File only needs to exist actual = InselectDocument.load(doc_temp) self.assertEqual(InselectDocument.load(source).items, actual.items) self.assertTrue(actual.scanned.available) self.assertTrue(actual.thumbnail.available) # Document load with scanned image file but not thumbnail os.unlink(str(thumbnail_temp)) actual = InselectDocument.load(doc_temp) self.assertEqual(InselectDocument.load(source).items, actual.items) self.assertTrue(actual.scanned.available) self.assertFalse(actual.thumbnail.available)
def test_save(self): "Document save writes items" source = TESTDATA / 'test_segment.inselect' temp = tempfile.mkdtemp() with temp_directory_with_files(TESTDATA / 'test_segment.inselect', TESTDATA / 'test_segment.png') as tempdir: items = [ {'fields': {}, 'rect': Rect(0.1, 0.2, 0.5, 0.5) }, ] doc_temp = tempdir / 'test_segment.inselect' d = InselectDocument.load(doc_temp) d.set_items(items) d.save() self.assertEqual(items, InselectDocument.load(doc_temp).items)
def test_export_csv(self): "Export metadata to CSV" with temp_directory_with_files(TESTDATA / 'shapes.inselect', TESTDATA / 'shapes.png') as tempdir: # Create an empty CSV file csv = tempdir / 'shapes.csv' with csv.open('w'): pass main([str(tempdir), '--overwrite']) csv = tempdir / 'shapes.csv' self.assertTrue(csv.is_file()) # Check CSV contents doc = InselectDocument.load(tempdir / 'shapes.inselect') with csv.open('rb') as f: res = unicodecsv.DictReader(f, encoding='utf-8') for index, item, row in zip(count(), doc.items, res): expected = item['fields'] expected.update({ 'ItemNumber': str(1+index), 'Cropped_image_name': '{0:04}.jpg'.format(1+index) }) actual = { k: v for k, v in row.items() if v and k not in BOUNDING_BOX_FIELD_NAMES } self.assertEqual(expected, actual)
def save_crops(dir, overwrite_existing, template): dir = Path(dir) export = DocumentExport(UserTemplate.load(template) if template else DWC) for p in dir.glob('*' + InselectDocument.EXTENSION): try: debug_print('Loading [{0}]'.format(p)) doc = InselectDocument.load(p) validation = export.validation_problems(doc) if validation.any_problems: print( 'Not saving crops for [{0}] because there are validation ' 'problems'.format(p) ) for msg in format_validation_problems(validation): print(msg) elif not overwrite_existing and doc.crops_dir.is_dir(): print('Crops dir [{0}] exists - skipping'.format(doc.crops_dir)) else: print('Will save crops for [{0}] to [{1}]'.format(p, doc.crops_dir)) debug_print('Loading full-resolution scanned image') doc.scanned.array debug_print('Saving crops') export.save_crops(doc) except KeyboardInterrupt: raise except Exception: print('Error saving crops from [{0}]'.format(p)) traceback.print_exc()
def test_load(self): "Load a document from a file" path = TESTDATA / 'shapes.inselect' doc = InselectDocument.load(path) # Properties are as expected self.assertEqual(doc.document_path, path) self.assertEqual(5, len(doc.items)) self.assertEqual(5, doc.n_items) self.assertEqual(doc.scanned.path, path.with_suffix('.png')) self.assertFalse(doc.thumbnail.available) self.assertEqual(TESTDATA / 'shapes_crops', doc.crops_dir) self.assertEqual('Lawrence Hudson', doc.properties['Created by']) self.assertEqual( "2015-03-14T09:19:47", doc.properties['Created on'].strftime('%Y-%m-%dT%H:%M:%S')) self.assertEqual('Lawrence Hudson', doc.properties['Saved by']) self.assertEqual( "2015-03-14T09:19:47", doc.properties['Saved on'].strftime('%Y-%m-%dT%H:%M:%S')) # Check read-only properties with self.assertRaises(AttributeError): doc.document_path = '' with self.assertRaises(AttributeError): doc.items = [] with self.assertRaises(AttributeError): doc.crops_dir = '' with self.assertRaises(AttributeError): doc.n_items = 1
def test_cancel_save_crops(self): "User cancels save crops" with temp_directory_with_files(TESTDATA / 'shapes.inselect', TESTDATA / 'shapes.png') as tempdir: doc = InselectDocument.load(tempdir / 'shapes.inselect') # Create crops dir with some data doc.crops_dir.mkdir() with doc.crops_dir.joinpath('a_file').open('w') as outfile: outfile.write('Some data\n') class CancelExport(Exception): pass def progress(msg): "A progress function that cancels the export" raise CancelExport() self.assertRaises( CancelExport, DocumentExport(self.TEMPLATE).save_crops, doc, progress=progress ) # Nothing should have changed within tempdir self.assertEqual( ['shapes.inselect', 'shapes.png', doc.crops_dir.name], sorted(p.name for p in tempdir.iterdir())) self.assertEqual( ['a_file'], [p.name for p in doc.crops_dir.iterdir()] )
def test_ingest(self): "PNG image is ingested and document is created" inbox_img = self.inbox / 'x.png' docs_img = self.docs / 'x.png' shutil.copy(str(TESTDATA / 'shapes.png'), str(inbox_img)) # Read the image for comparison test original_image = cv2.imread(str(inbox_img)) main([str(self.inbox), str(self.docs)]) # Document, scan and thumbnail should all exists self.assertTrue((self.docs / 'x.inselect').is_file()) self.assertTrue(docs_img.is_file()) self.assertTrue((self.docs / 'x_thumbnail.jpg').is_file()) # Scan should have been removed from inbox self.assertFalse(inbox_img.is_file()) # Scan is as expected? doc = InselectDocument.load(self.docs / 'x.inselect') self.assertTrue(np.all(original_image == doc.scanned.array)) self.assertTrue(doc.thumbnail.available) self.assertEqual(4096, doc.thumbnail.array.shape[1])
def test_segment_document_sort_by_rows(self): "Segment the document with boxes sorted by rows" doc = InselectDocument.load(TESTDATA / 'shapes.inselect') expected = doc.scanned.from_normalised( [i['rect'] for i in doc.items] ) self._segment(doc, False, expected)
def export_csv(dir, overwrite_existing, template): dir = Path(dir) export = DocumentExport(UserTemplate.load(template) if template else DWC) for p in dir.glob('*' + InselectDocument.EXTENSION): try: debug_print('Loading [{0}]'.format(p)) doc = InselectDocument.load(p) validation = export.validation_problems(doc) csv_path = export.csv_path(doc) if validation.any_problems: print( 'Not exporting metadata for [{0}] because there are ' 'validation problems'.format(p) ) for msg in format_validation_problems(validation): print(msg) elif not overwrite_existing and csv_path.is_file(): print('CSV file [{0}] exists - skipping'.format(csv_path)) else: print('Writing CSV for [{0}]'.format(p)) export.export_csv(doc) except KeyboardInterrupt: raise except Exception: print('Error saving CSV from [{0}]'.format(p)) traceback.print_exc()
def test_order_by_columns(self): doc = InselectDocument.load(TESTDATA / 'shapes.inselect') items = sort_document_items(doc.items, by_columns=True) self.assertEqual( ['1', '4', '3', '2', '5'], [item['fields']['catalogNumber'] for item in items] )
def save_crops(dir, overwrite_existing, template): dir = Path(dir) export = DocumentExport(UserTemplate.load(template) if template else DWC) for p in dir.glob('*' + InselectDocument.EXTENSION): try: debug_print('Loading [{0}]'.format(p)) doc = InselectDocument.load(p) validation = export.validation_problems(doc) if validation.any_problems: print( u'Not saving crops for [{0}] because there are validation ' u'problems'.format(p) ) for msg in format_validation_problems(validation): print(msg) elif not overwrite_existing and doc.crops_dir.is_dir(): print(u'Crops dir [{0}] exists - skipping'.format(doc.crops_dir)) else: print(u'Will save crops for [{0}] to [{1}]'.format(p, doc.crops_dir)) debug_print(u'Loading full-resolution scanned image') doc.scanned.array debug_print(u'Saving crops') export.save_crops(doc) except Exception: print(u'Error saving crops from [{0}]'.format(p)) traceback.print_exc()
def test_segment_document_sort_by_columns(self): "Segment the document with boxes sorted by columns" doc = InselectDocument.load(TESTDATA / 'shapes.inselect') items = doc.items expected = doc.scanned.from_normalised( [items[index]['rect'] for index in (0, 3, 2, 1, 4)]) self._segment(doc, True, expected)
def test_cancel_save_crops(self): "User cancels save crops" with temp_directory_with_files(TESTDATA / 'shapes.inselect', TESTDATA / 'shapes.png') as tempdir: doc = InselectDocument.load(tempdir / 'shapes.inselect') # Create crops dir with some data doc.crops_dir.mkdir() with doc.crops_dir.joinpath('a_file').open('w') as outfile: outfile.write('Some data\n') class CancelExport(Exception): pass def progress(msg): "A progress function that cancels the export" raise CancelExport() self.assertRaises(CancelExport, DocumentExport(self.TEMPLATE).save_crops, doc, progress=progress) # Nothing should have changed within tempdir self.assertEqual( ['shapes.inselect', 'shapes.png', doc.crops_dir.name], sorted(p.name for p in tempdir.iterdir())) self.assertEqual(['a_file'], [p.name for p in doc.crops_dir.iterdir()])
def test_load(self): "Load a document from a file" path = TESTDATA / 'test_segment.inselect' doc = InselectDocument.load(path) # Properties are as expected self.assertEqual(doc.document_path, path) self.assertEqual(5, len(doc.items)) self.assertEqual(5, doc.n_items) self.assertEqual(doc.scanned.path, path.with_suffix('.png')) self.assertTrue(doc.thumbnail is None) self.assertEqual(TESTDATA / 'test_segment_crops', doc.crops_dir) self.assertEqual('Lawrence Hudson', doc.properties['Created by']) self.assertEqual("2015-03-14T09:19:47", doc.properties['Created on'].strftime('%Y-%m-%dT%H:%M:%S')) self.assertEqual('Lawrence Hudson', doc.properties['Saved by']) self.assertEqual("2015-03-14T09:19:47", doc.properties['Saved on'].strftime('%Y-%m-%dT%H:%M:%S')) # Check read-only properties with self.assertRaises(AttributeError): doc.document_path = '' with self.assertRaises(AttributeError): doc.items = [] with self.assertRaises(AttributeError): doc.crops_dir = '' with self.assertRaises(AttributeError): doc.n_items = 1
def test_csv_export(self): "CSV data are exported as expected" with temp_directory_with_files(TESTDATA / 'shapes.inselect', TESTDATA / 'shapes.png') as tempdir: doc = InselectDocument.load(tempdir / 'shapes.inselect') csv_path = DocumentExport(self.TEMPLATE).export_csv(doc) self.assertEqual(csv_path, tempdir / 'shapes.csv') # Check CSV contents with csv_path.open('rb') as f: reader = unicodecsv.reader(f, encoding='utf8') headers = [ 'Cropped_image_name', 'ItemNumber', 'NormalisedLeft', 'NormalisedTop', 'NormalisedRight', 'NormalisedBottom', 'ThumbnailLeft', 'ThumbnailTop', 'ThumbnailRight', 'ThumbnailBottom', 'OriginalLeft', 'OriginalTop', 'OriginalRight', 'OriginalBottom', 'catalogNumber', 'Department', 'scientificName', 'scientificName-value' ] self.assertEqual(headers, next(reader)) # Check only the metadata columns and 'original' coordinates # columns, ignoring thumbnail (which doesn't exist) # and normalised (which are floating point) coordinates metadata_cols = itemgetter(0, 1, 10, 11, 12, 13, 14, 15, 16, 17) self.assertEqual( ('01_1.png', '1', '0', '0', '189', '189', '1', 'Entomology', 'A', '1'), metadata_cols(next(reader)) ) self.assertEqual( ('02_2.png', '2', '271', '0', '459', '189', '2', 'Entomology', 'B', '2'), metadata_cols(next(reader)) ) self.assertEqual( ('03_10.png', '3', '194', '196', '257', '232', '3', 'Entomology', 'インセクト', '10'), metadata_cols(next(reader)) ) self.assertEqual( ('04_3.png', '4', '0', '248', '189', '437', '4', 'Entomology', 'Elsinoë', '3'), metadata_cols(next(reader)) ) self.assertEqual( ('05_4.png', '5', '271', '248', '459', '437', '5', 'Entomology', 'D', '4'), metadata_cols(next(reader)) ) self.assertIsNone(next(reader, None))
def test_remove_invalid_rows(self): m = Model() m.from_document(InselectDocument.load(TESTDATA / 'test_segment.inselect')) self.assertEqual(5, m.rowCount()) self.assertRaises(ValueError, m.removeRows, -1, 1) # -ve row self.assertRaises(ValueError, m.removeRows, 6, 1) # row > n existing rows self.assertRaises(ValueError, m.removeRows, 0, -1) # -ve count
def test_remove_rows(self): m = Model() m.from_document(InselectDocument.load(TESTDATA / 'shapes.inselect')) m.removeRows(0, 1) self.assertEqual(4, m.rowCount()) expected = {"catalogNumber": "2", "scientificName": "B"} self.assertEqual(expected, m.data(m.index(0, 0), MetadataRole))
def test_remove_rows(self): m = Model() m.from_document(InselectDocument.load(TESTDATA / 'test_segment.inselect')) m.removeRows(0, 1) self.assertEqual(4, m.rowCount()) expected = {"catalogNumber": "2", "scientificName": "B"} self.assertEqual(expected, m.data(m.index(0, 0), MetadataRole))
def test_segment_document_sort_by_columns(self): "Segment the document with boxes sorted by columns" doc = InselectDocument.load(TESTDATA / 'shapes.inselect') items = doc.items expected = doc.scanned.from_normalised( [items[index]['rect'] for index in (0, 3, 2, 1, 4)] ) self._segment(doc, True, expected)
def test_display_role(self): m = Model() m.from_document(InselectDocument.load(TESTDATA / 'shapes.inselect')) # First four characters only - remainder depend upon current template self.assertEqual('0001', m.data(m.index(0, 0), Qt.DisplayRole)[:4]) self.assertEqual('0003', m.data(m.index(2, 0), Qt.DisplayRole)[:4]) self.assertEqual('0004', m.data(m.index(3, 0), Qt.DisplayRole)[:4])
def test_set_invalid_rotation(self): m = Model() m.from_document(InselectDocument.load(TESTDATA / 'test_segment.inselect')) i = m.index(0, 0) self.assertRaises(ValueError, m.setData, i, 'not an integer', RotationRole) self.assertRaises(ValueError, m.setData, i, -1, RotationRole) self.assertRaises(ValueError, m.setData, i, 2, RotationRole)
def test_display_role(self): m = Model() m.from_document(InselectDocument.load(TESTDATA / 'test_segment.inselect')) # First four characters only - remainder depend upon current template self.assertEqual('0001', m.data(m.index(0, 0), Qt.DisplayRole)[:4]) self.assertEqual('0003', m.data(m.index(2, 0), Qt.DisplayRole)[:4]) self.assertEqual('0004', m.data(m.index(3, 0), Qt.DisplayRole)[:4])
def test_set_same_rotation_does_not_modify(self): "Set box's rotation to the same value as it currently has" m = Model() m.from_document(InselectDocument.load(TESTDATA / 'shapes.inselect')) mock_modified_changed = self._new_mock_modified_changed(m) m.setData(m.index(0, 0), 0, RotationRole) self.assertFalse(mock_modified_changed.called) self.assertFalse(m.is_modified)
def test_set_same_rect_does_not_modify(self): "Set box's rect with the same value as it currently has" m = Model() m.from_document(InselectDocument.load(TESTDATA / 'shapes.inselect')) mock_modified_changed = self._new_mock_modified_changed(m) m.setData(m.index(0, 0), m.data(m.index(0, 0), RectRole), RectRole) self.assertFalse(mock_modified_changed.called) self.assertFalse(m.is_modified)
def test_set_metadata_modifies(self): "Alter box's metadata" m = Model() m.from_document(InselectDocument.load(TESTDATA / 'shapes.inselect')) mock_modified_changed = self._new_mock_modified_changed(m) m.setData(m.index(0, 0), {'catalogNumber': None}, MetadataRole) mock_modified_changed.assert_called_once_with() self.assertTrue(m.is_modified)
def test_set_items(self): "Items are set as expected" # TODO LH Check field validation path = TESTDATA / 'test_segment.inselect' doc = InselectDocument.load(path) items = [{'fields': {}, 'rect': Rect(0, 0, 0.5, 0.5)}] doc.set_items(items) self.assertEqual(items, doc.items)
def test_set_invalid_rotation(self): m = Model() m.from_document(InselectDocument.load(TESTDATA / 'shapes.inselect')) i = m.index(0, 0) self.assertRaises(ValueError, m.setData, i, 'not an integer', RotationRole) self.assertRaises(ValueError, m.setData, i, -1, RotationRole) self.assertRaises(ValueError, m.setData, i, 2, RotationRole)
def test_remove_invalid_rows(self): m = Model() m.from_document(InselectDocument.load(TESTDATA / 'shapes.inselect')) self.assertEqual(5, m.rowCount()) self.assertRaises(ValueError, m.removeRows, -1, 1) # -ve row self.assertRaises(ValueError, m.removeRows, 6, 1) # row > n existing rows self.assertRaises(ValueError, m.removeRows, 0, -1) # -ve count
def test_set_rotation_modifies(self): "Alter box's rotation" m = Model() m.from_document(InselectDocument.load(TESTDATA / 'shapes.inselect')) mock_modified_changed = self._new_mock_modified_changed(m) m.setData(m.index(0, 0), 90, RotationRole) mock_modified_changed.assert_called_once_with() self.assertTrue(m.is_modified)
def test_set_items(self): "Items are set as expected" # TODO LH Check field validation path = TESTDATA / 'shapes.inselect' doc = InselectDocument.load(path) items = [{'fields': {}, 'rect': Rect(0, 0, 0.5, 0.5)}] doc.set_items(items) self.assertEqual(items, doc.items)
def test_set_rect_modifies(self): "Alter box's rect" m = Model() m.from_document(InselectDocument.load(TESTDATA / 'shapes.inselect')) mock_modified_changed = self._new_mock_modified_changed(m) m.setData(m.index(0, 0), QRect(0, 0, 1, 1), RectRole) mock_modified_changed.assert_called_once_with() self.assertTrue(m.is_modified)
def test_set_metadata_modifies(self): "Alter box's metadata" m = Model() m.from_document(InselectDocument.load(TESTDATA / 'test_segment.inselect')) mock_modified_changed = self._new_mock_modified_changed(m) m.setData(m.index(0, 0), {'catalogNumber': None}, MetadataRole) mock_modified_changed.assert_called_once_with() self.assertTrue(m.is_modified)
def test_set_rect_modifies(self): "Alter box's rect" m = Model() m.from_document(InselectDocument.load(TESTDATA / 'test_segment.inselect')) mock_modified_changed = self._new_mock_modified_changed(m) m.setData(m.index(0, 0), QRect(0, 0, 1, 1), RectRole) mock_modified_changed.assert_called_once_with() self.assertTrue(m.is_modified)
def test_set_same_rect_does_not_modify(self): "Set box's rect with the same value as it currently has" m = Model() m.from_document(InselectDocument.load(TESTDATA / 'test_segment.inselect')) mock_modified_changed = self._new_mock_modified_changed(m) m.setData(m.index(0, 0), m.data(m.index(0, 0), RectRole), RectRole) self.assertFalse(mock_modified_changed.called) self.assertFalse(m.is_modified)
def test_ensure_thumbnail_silly_size(self): "Can't create thumbnail with a silly size" source_doc = TESTDATA / 'test_segment.inselect' source_img = TESTDATA / 'test_segment.png' with temp_directory_with_files(source_doc, source_img) as tempdir: doc = InselectDocument.load(tempdir / 'test_segment.inselect') self.assertRaises(InselectError, doc.ensure_thumbnail, -1) self.assertRaises(InselectError, doc.ensure_thumbnail, 50) self.assertRaises(InselectError, doc.ensure_thumbnail, 20000)
def test_ensure_thumbnail(self): "Thumbnail is created" source_doc = TESTDATA / 'test_segment.inselect' source_img = TESTDATA / 'test_segment.png' with temp_directory_with_files(source_doc, source_img) as tempdir: # Document load with no scanned image file doc = InselectDocument.load(tempdir / 'test_segment.inselect') self.assertTrue(doc.thumbnail is None) doc.ensure_thumbnail(width=2048) self.assertEqual(2048, doc.thumbnail.array.shape[1])
def process_dir(self, dir): # TODO LH Read image from crops dir, if it exists? for p in dir.glob('*' + InselectDocument.EXTENSION): # TODO LH Do not overwrite existing specimen numbers, or whatever # field it is that barcodes are written to print(p) try: self.read_barcodes_in_document(InselectDocument.load(p)) except Exception: print('Error reading barcodes in [{0}]'.format(p)) traceback.print_exc()
def test_read_barcodes(self): "Read barcodes" with temp_directory_with_files(TESTDATA / 'barcodes.inselect', TESTDATA / 'barcodes.jpg') as tempdir: doc_path = tempdir.joinpath('barcodes.inselect') # Doc should not have any catalog numbers doc = InselectDocument.load(doc_path) self.assertFalse( any( v.get('fields', {}).get('catalogNumber') for v in doc.items)) main([str(tempdir), 'libdmtx']) # Doc should not have expected catalog numbers doc = InselectDocument.load(doc_path) self.assertEqual(['1681107', '1681110', '1681112'], sorted(v['fields']['catalogNumber'] for v in doc.items))
def process_dir(self, dir): # TODO LH Read image from crops dir, if it exists? for p in Path(dir).glob('*' + InselectDocument.EXTENSION): # TODO LH Do not overwrite existing object numbers, or whatever # field it is that barcodes are written to print(p) try: self.read_barcodes_in_document(InselectDocument.load(p)) except Exception: print(u'Error reading barcodes in [{0}]'.format(p)) traceback.print_exc()
def test_save(self): "Save document" with temp_directory_with_files(TESTDATA / 'test_segment.inselect', TESTDATA / 'test_segment.png') as tempdir: items = [{ 'fields': {'type': u'インセクト'}, 'rect': Rect(0.1, 0.2, 0.5, 0.5), }] doc_temp = tempdir / 'test_segment.inselect' d = InselectDocument.load(doc_temp) d.set_items(items) d.save() self.assertEqual(items, InselectDocument.load(doc_temp).items) # Saved on time should be within last 2 seconds now = datetime.now(pytz.timezone("UTC")) saved_on = d.properties['Saved on'] self.assertLessEqual((now - saved_on).seconds, 2)
def test_read_barcodes(self): "Read barcodes" with temp_directory_with_files(TESTDATA / 'barcodes.inselect', TESTDATA / 'barcodes.jpg') as tempdir: doc_path = tempdir.joinpath('barcodes.inselect') # Doc should not have any catalog numbers doc = InselectDocument.load(doc_path) self.assertFalse( any(v.get('fields', {}).get('catalogNumber') for v in doc.items) ) main([str(tempdir), 'libdmtx']) # Doc should not have expected catalog numbers doc = InselectDocument.load(doc_path) self.assertEqual( ['1681107', '1681110', '1681112'], sorted(v['fields']['catalogNumber'] for v in doc.items) )
def test_crops(self): "Cropped object images are as expected" path = TESTDATA / 'test_segment.inselect' doc = InselectDocument.load(path) self.assertEqual(5, len(doc.items)) # Check the contents of each crop boxes = doc.scanned.from_normalised([i['rect'] for i in doc.items]) for box, crop in izip(boxes, doc.crops): x0, y0, x1, y1 = box.coordinates self.assertTrue(np.all(doc.scanned.array[y0:y1, x0:x1] == crop))
def test_crops(self): "Cropped object images are as expected" path = TESTDATA / 'shapes.inselect' doc = InselectDocument.load(path) self.assertEqual(5, len(doc.items)) # Check the contents of each crop boxes = doc.scanned.from_normalised([i['rect'] for i in doc.items]) for box, crop in zip(boxes, doc.crops): x0, y0, x1, y1 = box.coordinates self.assertTrue(np.all(doc.scanned.array[y0:y1, x0:x1] == crop))
def test_cookie_cutter(self): "Ingested image with cookie cutter applied" shutil.copy(unicode(TESTDATA / 'test_segment.png'), unicode(self.inbox / 'x.png')) main([ '--cookie-cutter={0}'.format(TESTDATA / '2x2.inselect_cookie_cutter'), unicode(self.inbox), unicode(self.docs) ]) doc = InselectDocument.load(self.docs / 'x.inselect') self.assertEqual(4, len(doc.items))
def test_cookie_cutter(self): "Ingested image with cookie cutter applied" shutil.copy(str(TESTDATA / 'shapes.png'), str(self.inbox / 'x.png')) main([ '--cookie-cutter={0}'.format(TESTDATA / '2x2.inselect_cookie_cutter'), str(self.inbox), str(self.docs) ]) doc = InselectDocument.load(self.docs / 'x.inselect') self.assertEqual(4, len(doc.items))
def test_set_rect(self): "Alter box's rect" m = Model() m.from_document(InselectDocument.load(TESTDATA / 'shapes.inselect')) i = m.index(0, 0) r = QRect(0, 0, 1, 1) m.setData(i, r, RectRole) self.assertEqual(r, m.data(i, RectRole)) r = QRect(5, 5, 5, 5) m.setData(i, r, RectRole) self.assertEqual(r, m.data(i, RectRole))
def test_save(self): "Save document" with temp_directory_with_files(TESTDATA / 'shapes.inselect', TESTDATA / 'shapes.png') as tempdir: items = [{ 'fields': { 'type': 'インセクト' }, 'rect': Rect(0.1, 0.2, 0.5, 0.5), }] doc_temp = tempdir / 'shapes.inselect' d = InselectDocument.load(doc_temp) d.set_items(items) d.save() self.assertEqual(items, InselectDocument.load(doc_temp).items) # Saved on time should be within last 2 seconds now = datetime.now(pytz.timezone("UTC")) saved_on = d.properties['Saved on'] self.assertLessEqual((now - saved_on).seconds, 2)
def test_insert_row(self): m = Model() m.from_document(InselectDocument.load(TESTDATA / 'test_segment.inselect')) self.assertEqual(5, m.rowCount()) m.insertRow(5) self.assertEqual(6, m.rowCount()) i = m.index(5, 0) self.assertEqual({}, m.data(i, MetadataRole)) self.assertEqual(0, m.data(i, RotationRole)) self.assertEqual(QRect(0, 0, 0, 0), m.data(i, RectRole))
def test_set_items(self): "Items are set as expected" # TODO LH Check field validation path = TESTDATA / 'test_segment.inselect' doc = InselectDocument.load(path) items = [ {'fields': {}, 'rect': Rect(0, 0, 0.5, 0.5)}, ] doc.set_items(items) self.assertEqual(items, doc.items) # Not normalised items = [ {'fields': {}, 'rect': Rect(0, 0, 1, 2)}, ] self.assertRaises(InselectError, doc.set_items, items)
def test_segment(self): "Segment an existing document" with temp_directory_with_files(TESTDATA / 'test_segment.png') as tempdir: # Create a new document ingest_image(tempdir / 'test_segment.png', tempdir) main([unicode(tempdir)]) doc_path = tempdir / 'test_segment.inselect' self.assertTrue(doc_path.is_file()) doc = InselectDocument.load(doc_path) self.assertEqual(5, len(doc.items))
def test_set_rect(self): "Alter box's rect" m = Model() m.from_document(InselectDocument.load(TESTDATA / 'test_segment.inselect')) i = m.index(0, 0) r = QRect(0, 0, 1, 1) m.setData(i, r, RectRole) self.assertEqual(r, m.data(i, RectRole)) r = QRect(5, 5, 5, 5) m.setData(i, r, RectRole) self.assertEqual(r, m.data(i, RectRole))
def test_shapes(self): "Segment an existing document" with temp_directory_with_files(TESTDATA / 'shapes.png') as tempdir: # Create a new document ingest_image(tempdir / 'shapes.png', tempdir) main([str(tempdir)]) doc_path = tempdir / 'shapes.inselect' self.assertTrue(doc_path.is_file()) doc = InselectDocument.load(doc_path) self.assertEqual(5, len(doc.items))
def test_insert_row(self): m = Model() m.from_document(InselectDocument.load(TESTDATA / 'shapes.inselect')) self.assertEqual(5, m.rowCount()) m.insertRow(5) self.assertEqual(6, m.rowCount()) i = m.index(5, 0) self.assertEqual({}, m.data(i, MetadataRole)) self.assertEqual(0, m.data(i, RotationRole)) self.assertEqual(QRect(0, 0, 0, 0), m.data(i, RectRole))
def test_open_non_ascii(self): "Open an inselect document with non-ascii characters in the filename" with temp_directory_with_files() as tempdir: stem = 'åland' path = tempdir.joinpath('{0}.inselect'.format(stem)) shutil.copy(str(TESTDATA.joinpath('shapes.inselect')), str(path)) shutil.copy(str(TESTDATA.joinpath('shapes.png')), str(tempdir.joinpath('{0}.png'.format(stem)))) doc = InselectDocument.load(path) # Properties are as expected self.assertEqual(doc.document_path, path)
def test_set_rotation(self): "Alter box's rotation" m = Model() m.from_document(InselectDocument.load(TESTDATA / 'shapes.inselect')) i = m.index(0, 0) self.assertEqual(0, m.data(i, RotationRole)) m.setData(i, 180, RotationRole) self.assertEqual(180, m.data(i, RotationRole)) # Rotation stored 0 <= v < 360 m.setData(i, -90, RotationRole) self.assertEqual(270, m.data(i, RotationRole))
def test_set_rotation(self): "Alter box's rotation" m = Model() m.from_document(InselectDocument.load(TESTDATA / 'test_segment.inselect')) i = m.index(0, 0) self.assertEqual(0, m.data(i, RotationRole)) m.setData(i, 180, RotationRole) self.assertEqual(180, m.data(i, RotationRole)) # Rotation stored 0 <= v < 360 m.setData(i, -90, RotationRole) self.assertEqual(270, m.data(i, RotationRole))