def test_detect_format(self): self.assertTrue( ImageSlide.detect_format(file_path('__missing_file')) is None) self.assertTrue( ImageSlide.detect_format(file_path('../setup.py')) is None) self.assertEqual( ImageSlide.detect_format(file_path('boxes.png')), 'PNG')
def test_detect_format(self): self.assertTrue( ImageSlide.detect_format(file_path('__missing_file')) is None) self.assertTrue( ImageSlide.detect_format(file_path('../setup.py')) is None) self.assertEqual(ImageSlide.detect_format(file_path('boxes.png')), 'PNG')
def test_operations_on_closed_handle(self): with image_open(file_path("boxes.png")) as img: osr = ImageSlide(img) osr.close() self.assertRaises(AttributeError, lambda: osr.read_region((0, 0), 0, (100, 100))) # If an Image is passed to the constructor, ImageSlide.close() # shouldn't close it self.assertEqual(img.getpixel((0, 0)), 3)
def test_operations_on_closed_handle(self): with image_open(file_path('boxes.png')) as img: osr = ImageSlide(img) osr.close() self.assertRaises(AttributeError, lambda: osr.read_region( (0, 0), 0, (100, 100))) # If an Image is passed to the constructor, ImageSlide.close() # shouldn't close it self.assertEqual(img.getpixel((0, 0)), 3)
def _get_dz(self, associated=None): if associated is not None: image = ImageSlide(self._slide.associated_images[associated]) else: image = self._slide return DeepZoomGenerator(image, self._tile_size, self._overlap, limit_bounds=self._limit_bounds)
def index_wsi(file_path): config_map = { 'DEEPZOOM_TILE_SIZE': 'tile_size', 'DEEPZOOM_OVERLAP': 'overlap', 'DEEPZOOM_LIMIT_BOUNDS': 'limit_bounds', } opts = dict((v, app.config[k]) for k, v in config_map.items()) slide = open_slide('static/wsi/' + file_path) app.slides = { SLIDE_NAME: DeepZoomGenerator(slide, **opts) } app.associated_images = [] app.slide_properties = slide.properties for name, image in slide.associated_images.items(): app.associated_images.append(name) slug = slugify(name) app.slides[slug] = DeepZoomGenerator(ImageSlide(image), **opts) try: mpp_x = slide.properties[openslide.PROPERTY_NAME_MPP_X] mpp_y = slide.properties[openslide.PROPERTY_NAME_MPP_Y] slide_mpp = (float(mpp_x) + float(mpp_y)) / 2 except (KeyError, ValueError): slide_mpp = 0 slide_url = url_for('dzi', slug=SLIDE_NAME) return render_template('as_viewer.html', slide_url=slide_url, slide_mpp=slide_mpp, file_name=file_path, dictionary=getDictionary(file_path))
def __init__(self, slidepath, basename, format, tile_size, overlap, limit_bounds, quality, workers, with_viewer, is_PIL_Image_obj=False): if with_viewer: # Check extra dependency before doing a bunch of work import jinja2 self._slide = (ImageSlide(slidepath) if is_PIL_Image_obj else open_slide(slidepath)) self._basename = basename self._format = format self._tile_size = tile_size self._overlap = overlap self._limit_bounds = limit_bounds self._queue = JoinableQueue(2 * workers) self._workers = workers self._with_viewer = with_viewer self._dzi_data = {} for _i in range(workers): TileWorker(self._queue, slidepath, tile_size, overlap, limit_bounds, quality, is_PIL_Image_obj).start()
def load_slide(slidefile, tile_size): print("there is an image") slide = open_slide(slidefile) slides = { "slide": DeepZoomGenerator(slide, tile_size=tile_size, overlap=1, limit_bounds=True) } associated_images = [] slide_properties = slide.properties for name, image in slide.associated_images.items(): associated_images.append(name) slug = slugify(name) slides[slug] = DeepZoomGenerator(ImageSlide(image), tile_size=tile_size, overlap=1, limit_bounds=True) try: mpp_x = slide.properties[openslide.PROPERTY_NAME_MPP_X] mpp_y = slide.properties[openslide.PROPERTY_NAME_MPP_Y] slide_mpp = (float(mpp_x) + float(mpp_y)) / 2 except (KeyError, ValueError): slide_mpp = 0 return slides, associated_images, slide_properties, slide_mpp
def load_slide(): slidefile = app.config['DEEPZOOM_SLIDE'] if slidefile is None: raise ValueError('No slide file specified') config_map = { 'DEEPZOOM_TILE_SIZE': 'tile_size', 'DEEPZOOM_OVERLAP': 'overlap', 'DEEPZOOM_LIMIT_BOUNDS': 'limit_bounds', } opts = dict((v, app.config[k]) for k, v in config_map.items()) slide = open_slide(slidefile) app.slides = { SLIDE_NAME: DeepZoomGenerator(slide, **opts) } app.associated_images = [] app.slide_properties = slide.properties for name, image in slide.associated_images.items(): app.associated_images.append(name) slug = slugify(name) app.slides[slug] = DeepZoomGenerator(ImageSlide(image), **opts) try: mpp_x = slide.properties[openslide.PROPERTY_NAME_MPP_X] mpp_y = slide.properties[openslide.PROPERTY_NAME_MPP_Y] app.slide_mpp = (float(mpp_x) + float(mpp_y)) / 2 except (KeyError, ValueError): app.slide_mpp = 0
def run_image(self, associated=None): """ Run a single image from self.slide. """ if associated is None: image = self.slide if self.with_viewer: basename = os.path.join(self.basename, VIEWER_SLIDE_NAME) else: basename = self.basename else: image = ImageSlide(self.slide.associated_images[associated]) basename = os.path.join(self.basename, self.slugify(associated)) dz = DeepZoomGenerator(image, self.tile_size, self.overlap, limit_bounds=self.limit_bounds) tiler = DeepZoomImageTiler(dz, basename, self.format, associated, self.queue, self.slide, self.basename_jpg, self.xml_file, self.mask_type, self.xml_label, self.roi_percentage, self.img_extension, self.save_masks, self.magnification) tiler.run() self.dzi_data[self.url_for(associated)] = tiler.get_dzi()
def _run_image(self, associated=None): """Run a single image from self._slide.""" if associated is None: image = self._slide if self._with_viewer: basename = os.path.join(self._basename, VIEWER_SLIDE_NAME) else: basename = self._basename else: image = ImageSlide(self._slide.associated_images[associated]) basename = os.path.join(self._basename, self._slugify(associated)) print("enter DeepZoomGenerator") dz = DeepZoomGenerator(image, self._tile_size, self._overlap, limit_bounds=self._limit_bounds) print("enter DeepZoomImageTiler") tiler = DeepZoomImageTiler(dz, basename, self._format, associated, self._queue, self._slide, self._basenameJPG, self._xmlfile, self._mask_type, self._xmlLabel, self._ROIpc, self._ImgExtension, self._SaveMasks, self._Mag) tiler.run() self._dzi_data[self._url_for(associated)] = tiler.get_dzi()
def dzi_asso(path, associated_name): slide = _get_slide(path) associated_image = slide.osr.associated_images[associated_name] dzg = DeepZoomGenerator(ImageSlide(associated_image)) format = app.config['DEEPZOOM_FORMAT'] resp = make_response(dzg.get_dzi(format)) resp.mimetype = 'application/xml' return resp
def get_dz(self, slide_path, associated=None): if slide_path != self._slide_path: generator = lambda slide: DeepZoomGenerator( slide, TILE_SIZE, OVERLAP, limit_bounds=LIMIT_BOUNDS) slide = OpenSlide(slide_path) self._slide_path = slide_path self._generators = {None: generator(slide)} for name, image in slide.associated_images.iteritems(): self._generators[name] = generator(ImageSlide(image)) return self._generators[associated]
def get(self, path): with self._lock: if path in self._cache: # Move to end of LRU slide = self._cache.pop(path) self._cache[path] = slide return slide try: osr = OpenSlide(path) except: osr = ImageSlide(path) #Fix for 16 bits tiff files if osr._image.getextrema()[1] > 256: osr._image = osr._image.point(lambda i: i * (1. / 256)).convert('L') slide = DeepZoomGenerator(osr, **self.dz_opts) slide.osr = osr slide.associated_images = {} for name, image in slide.osr.associated_images.items(): slide.associated_images[name] = DeepZoomGenerator( ImageSlide(image)) try: mpp_x = osr.properties[openslide.PROPERTY_NAME_MPP_X] mpp_y = osr.properties[openslide.PROPERTY_NAME_MPP_Y] slide.properties = osr.properties slide.mpp = (float(mpp_x) + float(mpp_y)) / 2 except (KeyError, ValueError): slide.mpp = 0 try: slide.properties = slide.properties except: slide.properties = osr.properties slide.tileLock = Lock() with self._lock: if path not in self._cache: while len(self._cache) >= self.cache_size: self._cache.popitem(last=False) self._cache[path] = slide return slide
def dirTreating(): try: mkdir(PTCH_DIR) print("creating the 'patches' folder") except FileExistsError: print("the " + PTCH_DIR + " folder already exists") fileNameList = listdir(IMG_DIR) f = [] for name in fileNameList: if name[-4:] == "ndpi": img = ImageSlide(IMG_DIR + name) f += cutPatches(img, name) np.save("./patchesArray", f)
def _run_image(self, associated=None): """Run a single image from self._slide.""" if associated is None: image = self._slide OutputDir = self._OutputDir else: image = ImageSlide(self._slide.associated_images[associated]) OutputDir = os.path.join(self._OutputDir, self._slugify(associated)) dz = DeepZoomGenerator(image, self._tile_size, self._overlap, limit_bounds=self._limit_bounds) tiler = DeepZoomImageTiler(dz, OutputDir, self._format, associated, self._queue) tiler.run()
def _run_image(self, associated=None): if associated is None: image = self._slide basename = self._basename else: image = ImageSlide(self._slide.associated_images[associated]) basename = os.path.join(self._basename, self._slugify(associated)) dz = DeepZoomGenerator(image, self._tile_size, self._overlap, limit_bounds=self._limit_bounds) tiler = DeepZoomImageTiler(dz, basename, self._format, associated, self._queue) tiler.run()
class TestImage(unittest.TestCase): def setUp(self): self.osr = ImageSlide(file_path('boxes.png')) def tearDown(self): self.osr.close() def test_repr(self): self.assertEqual(repr(self.osr), 'ImageSlide(%r)' % file_path('boxes.png')) def test_metadata(self): self.assertEqual(self.osr.level_count, 1) self.assertEqual(self.osr.level_dimensions, ((300, 250),)) self.assertEqual(self.osr.dimensions, (300, 250)) self.assertEqual(self.osr.level_downsamples, (1.0,)) self.assertEqual(self.osr.get_best_level_for_downsample(0.5), 0) self.assertEqual(self.osr.get_best_level_for_downsample(3), 0) self.assertEqual(self.osr.properties, {}) self.assertEqual(self.osr.associated_images, {}) def test_read_region(self): self.assertEqual(self.osr.read_region((-10, -10), 0, (400, 400)).size, (400, 400)) @skip_if(image_dimensions_cannot_be_zero, 'Pillow issue #2259') def test_read_region_size_dimension_zero(self): self.assertEqual(self.osr.read_region((0, 0), 0, (400, 0)).size, (400, 0)) def test_read_region_bad_level(self): self.assertRaises(OpenSlideError, lambda: self.osr.read_region((0, 0), 1, (100, 100))) def test_read_region_bad_size(self): self.assertRaises(OpenSlideError, lambda: self.osr.read_region((0, 0), 0, (400, -5))) def test_thumbnail(self): self.assertEqual(self.osr.get_thumbnail((100, 100)).size, (100, 83))
class TestImage(unittest.TestCase): def setUp(self): self.osr = ImageSlide(file_path('boxes.png')) def tearDown(self): self.osr.close() def test_repr(self): self.assertEqual(repr(self.osr), 'ImageSlide(%r)' % file_path('boxes.png')) def test_metadata(self): self.assertEqual(self.osr.level_count, 1) self.assertEqual(self.osr.level_dimensions, ((300, 250), )) self.assertEqual(self.osr.dimensions, (300, 250)) self.assertEqual(self.osr.level_downsamples, (1.0, )) self.assertEqual(self.osr.get_best_level_for_downsample(0.5), 0) self.assertEqual(self.osr.get_best_level_for_downsample(3), 0) self.assertEqual(self.osr.properties, {}) self.assertEqual(self.osr.associated_images, {}) def test_read_region(self): self.assertEqual( self.osr.read_region((-10, -10), 0, (400, 400)).size, (400, 400)) @unittest.skipIf(image_dimensions_cannot_be_zero, 'Pillow issue #2259') def test_read_region_size_dimension_zero(self): self.assertEqual( self.osr.read_region((0, 0), 0, (400, 0)).size, (400, 0)) def test_read_region_bad_level(self): self.assertRaises(OpenSlideError, lambda: self.osr.read_region( (0, 0), 1, (100, 100))) def test_read_region_bad_size(self): self.assertRaises(OpenSlideError, lambda: self.osr.read_region( (0, 0), 0, (400, -5))) def test_thumbnail(self): self.assertEqual(self.osr.get_thumbnail((100, 100)).size, (100, 83))
def _run_image(self, associated=None): """Run a single image from self._slide.""" if associated is None: image = self._slide if self._with_viewer: basename = os.path.join(self._basename, VIEWER_SLIDE_NAME) else: basename = self._basename else: image = ImageSlide(self._slide.associated_images[associated]) basename = os.path.join(self._basename, self._slugify(associated)) dz = DeepZoomGenerator(image, self._tile_size, self._overlap) tiler = DeepZoomImageTiler(dz, basename, self._format, associated, self._queue) tiler.run() self._dzi_data[self._url_for(associated)] = tiler.get_dzi()
def get_osr(path): def get_hp(): ROOT = app.config['HP_DIR'] slide_name = path.split('/')[-1].split('.')[0] ''' slide_type, slide_id = slide_name.strip().split('_') slide_id = int(slide_id) hp_path = "" if slide_type == 'Tumor': if slide_id in range(1, 60+1) or slide_id in range(71, 100+1): hp_path = '%s/tr/%s.png'%(ROOT, slide_name) else: hp_path = '%s/te/%s.png'%(ROOT, slide_name) elif slide_type == 'Normal': if slide_id in range(1, 90+1) or slide_id in range(101, 150+1): hp_path = '%s/tr/%s.png'%(ROOT, slide_name) else: hp_path = '%s/te/%s.png'%(ROOT, slide_name) elif slide_type == 'Test': hp_path = '%s/re/%s.png'%(ROOT, slide_name) ''' try: hp_path = '%s/%s.png' % (ROOT, slide_name) hp = cv2.imread(hp_path, cv2.IMREAD_GRAYSCALE) return hp, hp_path except Exception as e: print e return None, None ## print "Loading image ori: ", path img_ori = cv2.imread(path) ## hp, hp_name = get_hp() if hp is None or hp_name is None: img = img_ori else: print "Loading mask image: ", hp_name hp_jet = cv2.applyColorMap(hp, cv2.COLORMAP_JET) alpha = 0.5 img = cv2.addWeighted(img_ori, alpha, hp_jet, 1 - alpha, 1) img = img[:, :, (2, 1, 0)] # b,g,r -> r,g,b img_output = Image.fromarray(img) osr = ImageSlide(img_output) return osr
def _run_image(self, associated=None): """Run a single image from self._slide.""" if associated is None: image = self._slide outpath = self._outpath else: image = ImageSlide(self._slide.associated_images[associated]) outpath = os.path.join(self._outpath, self._slugify(associated)) dz = DeepZoomGenerator(image, self._tile_size, self._overlap, self._limit_bounds) tiler = SingleImageTiler(dz, outpath, self._img_format, associated, self._queue, self._only_last) tiler.run() self._dzi_data[self._url_for(associated)] = tiler.get_dzi()
def run(self): self._slide = (ImageSlide(self._slidepath) if self.is_PIL_Image_obj else open_slide(self._slidepath)) last_associated = None dz = self._get_dz() while True: data = self._queue.get() if data is None: self._queue.task_done() break associated, level, address, outfile = data if last_associated != associated: dz = self._get_dz(associated) last_associated = associated tile = dz.get_tile(level, address) tile.save(outfile, quality=self._quality) self._queue.task_done()
def load_slide(): slidefile = app.config['DEEPZOOM_SLIDE'] if slidefile is None: raise ValueError('No slide file specified') config_map = { 'DEEPZOOM_TILE_SIZE': 'tile_size', 'DEEPZOOM_OVERLAP': 'overlap', } opts = dict((v, app.config[k]) for k, v in config_map.items()) slide = open_slide(slidefile) app.slides = { SLIDE_NAME: DeepZoomGenerator(slide, **opts) } app.associated_images = [] app.slide_properties = slide.properties for name, image in slide.associated_images.items(): app.associated_images.append(name) slug = slugify(name) app.slides[slug] = DeepZoomGenerator(ImageSlide(image), **opts)
def _run_image(self, associated=None): """Run a single image from self._slide.""" if associated is None: image = self._slide basename = self._basename else: image = ImageSlide(self._slide.associated_images[associated]) basename = os.path.join(self._basename, self._slugify(associated)) dz = DeepZoomGenerator(image, self._tile_size, self._overlap, limit_bounds=self._limit_bounds) MAG_BASE = self._slide.properties.get(openslide.PROPERTY_NAME_OBJECTIVE_POWER) if MAG_BASE is None: MAG_BASE = self._objective first_level = int(math.log2(float(MAG_BASE)/self._base_mag)) # raw / input, 40/20=2, 40/40=0 target_levels = [i+first_level for i in self._mag_levels] # levels start from 0 target_levels.reverse() tiler = DeepZoomImageTiler(dz, basename, target_levels, MAG_BASE, self._format, associated, self._queue) tiler.run()
def _run_image(self, associated=None): """Run a single image from self._slide.""" if associated is None: image = self._slide if self._with_viewer: basename = os.path.join(self._basename, VIEWER_SLIDE_NAME) else: basename = self._basename else: image = ImageSlide(self._slide.associated_images[associated]) basename = os.path.join(self._basename, self._slugify(associated)) print('start dz') dz = DeepZoomGenerator(image, self._tile_size, self._overlap, limit_bounds=self._limit_bounds) print('-' * 30) print('dz.level_count') print(dz.level_count) print('-' * 30) print('dz.level_tiles') print(dz.level_tiles) print('-' * 30) print('dz.level_dimensions') print(dz.level_dimensions) print('-' * 30) print('dz.tile_count') print(dz.tile_count) tiler = DeepZoomImageTiler(dz, basename, self._format, associated, self._queue) tiler.run() self._dzi_data[self._url_for(associated)] = tiler.get_dzi()
def test_open(self): self.assertRaises(IOError, lambda: ImageSlide(file_path('__does_not_exist'))) self.assertRaises(IOError, lambda: ImageSlide(file_path('../setup.py')))
# Tile slide def do_tile(associated, image): dz = DeepZoomGenerator(image, TILE_SIZE, OVERLAP, limit_bounds=LIMIT_BOUNDS) return sync_image(pool, slide_relpath, slide_path, associated, dz, key_basepath, key_md5sums, mpp if associated is None else None) metadata['slide'] = do_tile(None, slide) # Tile associated images for associated, image in sorted(slide.associated_images.items()): cur_props = do_tile(associated, ImageSlide(image)) metadata['associated'].append(cur_props) finally: shutil.rmtree(tempdir) # Delete old keys for name in metadata_key_name, properties_key_name: key_md5sums.pop(name, None) if key_md5sums: print "Pruning %d keys for %s..." % (len(key_md5sums), slide_relpath) delete_result = bucket.delete_keys(key_md5sums, quiet=True) if delete_result.errors: raise IOError('Failed to delete %d keys' % len(delete_result.errors)) # Update metadata
def test_detect_format(self): self.assertTrue(ImageSlide.detect_format(file_path("__missing_file")) is None) self.assertTrue(ImageSlide.detect_format(file_path("../setup.py")) is None) self.assertEqual(ImageSlide.detect_format(file_path("boxes.png")), "PNG")
def test_context_manager(self): osr = ImageSlide(file_path("boxes.png")) with osr: pass self.assertRaises(AttributeError, lambda: osr.read_region((0, 0), 0, (100, 100)))
def setUp(self): self.osr = ImageSlide(file_path("boxes.png"))
def setUp(self): self.osr = ImageSlide(file_path('boxes.png'))
def test_context_manager(self): osr = ImageSlide(file_path('boxes.png')) with osr: pass self.assertRaises(AttributeError, lambda: osr.read_region((0, 0), 0, (100, 100)))
def predict_wsi(model, global_fixed, slide_path): # size_g, size_p = (244, 244), (244, 244) # size_g, size_p = (1008, 1008), (1008, 1008) # n_class = 2 # sub_batch_size = 1 def predict(image_as_tensor, size_g=(244, 244), size_p=(244, 244), n_class=2): images_glb = resize(image_as_tensor, size_g) scores = [ np.zeros((1, n_class, image_as_tensor[i].size[1], image_as_tensor[i].size[0])) for i in range(len(image_as_tensor)) ] images_glb = images_transform(images_glb) patches, coordinates, templates, sizes, ratios = global2patch( image_as_tensor, size_p) predicted_ensembles = [ np.zeros((len(coordinates[i]), n_class, size_p[0], size_p[1])) for i in range(len(image_as_tensor)) ] for i in range(len(image_as_tensor)): j = 0 while j < len(coordinates[i]): patches_var = images_transform(patches[i][j:j + 1]) # b, c, h, w fm_patches, _ = model.module.collect_local_fm( images_glb[i:i + 1], patches_var, ratios[i], coordinates[i], [j, j + 1], len(image_as_tensor), global_model=global_fixed, template=templates[i], n_patch_all=len(coordinates[i]), ) j += 1 _, fm_global = model.forward(images_glb, None, None, None, mode=PhaseMode.GlobalFromLocal) for i in range(len(image_as_tensor)): j = 0 # while j < n ** 2: while j < len(coordinates[i]): fl = fm_patches[i][j:j + 1].cuda() fg = crop_global(fm_global[i:i + 1], coordinates[i][j:j + 1], ratios[i])[0] fg = F.interpolate(fg, size=fl.size()[2:], mode="bilinear") output_ensembles = model.module.ensemble( fl, fg) # include cordinates # output_ensembles = F.interpolate(model.module.ensemble(fl, fg), size_p, **model.module._up_kwargs) # ensemble predictions predicted_ensembles[i][j:j + output_ensembles.size()[0]] += ( F.interpolate( output_ensembles, size=size_p, mode="nearest", ).data.cpu().numpy()) j += 1 scores[i] += np.rot90( np.array( patch2global( predicted_ensembles[i:i + 1], n_class, sizes[i:i + 1], coordinates[i:i + 1], size_p, )), k=0, axes=(3, 2), ) return [score.argmax(1)[0] for score in scores] slide = OpenSlide(slide_path) w, h = slide.level_dimensions[2] img = slide.read_region((0, 0), 2, (w, h)) slide.close() img.convert('RGB').save('/tmp/temp.jpg') slide = ImageSlide('/tmp/temp.jpg') dz = deepzoom.DeepZoomGenerator(slide, tile_size=1024, overlap=0) cols, rows = dz.level_tiles[-1] out = np.zeros((rows * 1024, cols * 1024), dtype=np.uint8) for row in range(rows): for col in range(cols): tile = dz.get_tile(dz.level_count - 1, (col, row)) # col, row tile_coors = dz.get_tile_coordinates(dz.level_count - 1, (col, row)) left, top = tile_coors[0] t_w, t_h = tile_coors[2] if tile.size != (1024, 1024): tile = add_extra_pixels(tile, expected_shape=(1024, 1024)) tile = np.array(tile) processed = apply_filters(tile) pred = predict([Image.fromarray(processed)]) pil_pred = pred[0].astype(np.uint8) newmask = remove_mask_overlay_background(processed, pil_pred) # applied_mask = apply_mask(tile, newmask) applied_mask = newmask out[top:top + t_h, left:left + t_w] = applied_mask[:t_h, :t_w] return out[:h, :w]
def test_open_image(self): # passing PIL.Image to ImageSlide with image_open(file_path('boxes.png')) as img: with ImageSlide(img) as osr: self.assertEqual(osr.dimensions, (300, 250)) self.assertEqual(repr(osr), 'ImageSlide(%r)' % img)