def test_operations_on_closed_handle(self):
     osr = OpenSlide(file_path('boxes.tiff'))
     props = osr.properties
     associated = osr.associated_images
     osr.close()
     self.assertRaises(ArgumentError,
             lambda: osr.read_region((0, 0), 0, (100, 100)))
     self.assertRaises(ArgumentError, lambda: osr.close())
     self.assertRaises(ArgumentError, lambda: props['openslide.vendor'])
     self.assertRaises(ArgumentError, lambda: associated['label'])
    def read_wsi_normal(wsi_path):
        """
            # =====================================================================================
            # read WSI image and resize
            # Due to memory constraint, we use down sampled (4th level, 1/32 resolution) image
            # ======================================================================================
        """
        try:
            wsi_image = OpenSlide(wsi_path)
            level_used = wsi_image.level_count - 1
            rgb_image = np.array(wsi_image.read_region((0, 0), level_used,
                                                       wsi_image.level_dimensions[level_used]))

        except OpenSlideUnsupportedFormatError:
            print('Exception: OpenSlideUnsupportedFormatError')
            return None, None, None

        return wsi_image, rgb_image, level_used
    def read_wsi_tumor(wsi_path, mask_path):
        """
            # =====================================================================================
            # read WSI image and resize
            # Due to memory constraint, we use down sampled (4th level, 1/32 resolution) image
            # ======================================================================================
        """
        try:
            wsi_image = OpenSlide(wsi_path)
            wsi_mask = OpenSlide(mask_path)

            level_used = wsi_image.level_count - 1

            rgb_image = np.array(wsi_image.read_region((0, 0), level_used,
                                                       wsi_image.level_dimensions[level_used]))

            mask_level = wsi_mask.level_count - 1
            mask_image = wsi_mask.read_region((0, 0), mask_level,
                                              wsi_image.level_dimensions[mask_level])
            resize_factor = float(1.0 / pow(2, level_used - mask_level))
            # print('resize_factor: %f' % resize_factor)
            mask_image = cv2.resize(np.array(mask_image), (0, 0), fx=resize_factor, fy=resize_factor)

            wsi_mask.close()
        except OpenSlideUnsupportedFormatError:
            print('Exception: OpenSlideUnsupportedFormatError')
            return None, None, None, None

        return wsi_image, rgb_image, mask_image, level_used
    def read_wsi_tumor(wsi_path, mask_path):
        """
            # =====================================================================================
            # read WSI image and resize
            # Due to memory constraint, we use down sampled (4th level, 1/32 resolution) image
            # ======================================================================================
        """
        try:
            wsi_image = OpenSlide(wsi_path)
            wsi_mask = OpenSlide(mask_path)

            level_used = wsi_image.level_count - 1

            rgb_image = np.array(wsi_image.read_region((0, 0), level_used,
                                                       wsi_image.level_dimensions[level_used]))

            mask_level = wsi_mask.level_count - 1
            tumor_gt_mask = wsi_mask.read_region((0, 0), mask_level,
                                                 wsi_image.level_dimensions[mask_level])
            resize_factor = float(1.0 / pow(2, level_used - mask_level))
            # print('resize_factor: %f' % resize_factor)
            tumor_gt_mask = cv2.resize(np.array(tumor_gt_mask), (0, 0), fx=resize_factor, fy=resize_factor)

            # wsi_mask.close()
        except OpenSlideUnsupportedFormatError:
            print('Exception: OpenSlideUnsupportedFormatError')
            return None, None, None, None

        return wsi_image, rgb_image, wsi_mask, tumor_gt_mask, level_used
    class InferTumorSegDataset(Dataset):
        def __init__(self, wsi_path, patch_size, stride_size, selected_level,
                     mask_level):
            self._wsi_path = wsi_path
            self._patch_size = patch_size
            self._stride_size = stride_size
            self._selected_level = selected_level
            self._mask_level = mask_level
            self._os_image = OpenSlide(os.path.join(self._wsi_path))
            self._points = []
            self._basic_preprocessing()

        def _basic_preprocessing(self):
            mask_xdim, mask_ydim = self._os_image.level_dimensions[
                self._mask_level]
            print(self._wsi_path, self._os_image)
            extracted_image = self._os_image.read_region(
                (0, 0), self._mask_level,
                (mask_xdim, mask_ydim)).convert('RGB')
            mask = tissue_mask_generation(extracted_image)
            del extracted_image
            ydim, xdim = self._os_image.level_dimensions[self._selected_level]
            mask = resize(mask, (xdim, ydim))
            mask = (mask > 0).astype(np.uint8)
            for i in range(0, ydim - self._patch_size[0],
                           self._stride_size[0]):
                for j in range(0, xdim - self._patch_size[1],
                               self._stride_size[1]):
                    self._points.append([j, i])
            for i in range(len(self._points)):
                point = self._points[i]
                if not np.any(mask[point[0]:point[0] + self._patch_size[0],
                                   point[1]:point[1] + self._patch_size[1]]):
                    self._points[i] = [-1, -1]
            self._points = np.array(self._points)
            self._points = np.delete(
                self._points, np.argwhere(self._points == np.array([-1, -1])),
                0)
            self._points[:, [0, 1]] = self._points[:, [1, 0]]
            self._mask = mask

        def __len__(self):
            return len(self._points)

        def __getitem__(self, idx):
            x_loc, y_loc = self._points[idx]
            patch = np.array(
                self._os_image.read_region(
                    (x_loc * 4, y_loc * 4), self._selected_level,
                    (self._patch_size[0], self._patch_size[1])).convert('RGB'))
            patch = np.array(patch / 255)
            patch = patch.transpose([2, 0, 1])
            return patch, (x_loc, y_loc)
    def next_batch(self, n, **kwargs):
        assert self.initialized == True, "Data Source not initialized"

        flat = 'flat' in kwargs and kwargs['flat'] is True
        noise = 'noise' in kwargs and kwargs['noise'] is True
        nc = kwargs['nc'] if 'nc' in kwargs else 0.05
        level = kwargs['level'] if 'level' in kwargs else 0
        isfloat = kwargs['isfloat'] if 'isfloat' in kwargs else False

        selected_image = np.random.randint(len(self.images))
        chunks = np.random.random((3,n))

        im_path = self.images[selected_image][0]
        osr = OpenSlide(im_path)
        mask = self.masks[selected_image]
        imsize = osr.level_dimensions[level]
        ratios = [imsize[0]*1./mask.shape[0], imsize[1]*1./mask.shape[1]]

        n_px_in_mask = mask.sum()
        indexes = np.arange(n_px_in_mask)+1
        mask_indexes = np.zeros(mask.shape)
        mask_indexes[mask] = indexes

        chunks[0,:] *= n_px_in_mask # index in mask
        chunks[1,:] *= (ratios[0]-self.chunksize[0])    # y pixel offset in higher def image from top-left of region
        chunks[2,:] *= (ratios[1]-self.chunksize[1])    # x pixel offset in higher def image from top-left of region
        if isfloat:
            chunks = chunks.astype('float')
            if chunks.max() > 1:
                chunks = chunks / 255.
        else:
            if chunks.max() < 1:
                chunks = chunks*255
            chunks = np.round(chunks).astype('uint16')

        lowres_coordinates = [np.where(mask_indexes==c) for c in chunks[0,:]]
        highres_coordinates = [ ( int((lr[0]*ratios[0] + chunks[1,i])[0]), int((lr[1]*ratios[1] + chunks[2,i])[0]) ) for i,lr in enumerate(lowres_coordinates) ]

        if noise:
            if flat:
                toAdd = np.random.rand(n, self.chunksize[0]*self.chunksize[1]*3)*nc
            else:
                toAdd = np.random.rand(n, self.chunksize[0], self.chunksize[1], 3)*nc
        else:
            if flat:
                toAdd = np.zeros((n, self.chunksize[0]*self.chunksize[1]*3))
            else:
                toAdd = np.zeros((n, self.chunksize[0], self.chunksize[1], 3))

        if flat :
            return [np.asarray(osr.read_region((chunk[0], chunk[1]), level, self.chunksize)).flatten().astype(np.float32)[:,:,:3]/255.+toAdd[i] for i,chunk in enumerate(highres_coordinates)]
        else:
            return [np.asarray(osr.read_region((chunk[0], chunk[1]), level, self.chunksize)).astype(np.float32)[:,:,:3]/255.+toAdd[i] for i,chunk in enumerate(highres_coordinates)]
Beispiel #7
0
def convert_image(path_img, level=DEFAULT_LEVEL, overwrite=False):
    """ convert TIFF/SVS image to standard format
    The output image has the same name and it is exported in the same folder

    :param str path_img: path to the input image
    :param int level: selected level of the internal pyramid representation
        the level 0 means full scale and higher number is small image in pyramid scaling
    :param bool overwrite: whether overwrite existing image on output
    """
    slide_img = OpenSlide(path_img)
    if level >= len(slide_img.level_dimensions):
        raise ValueError('unsupported level %i of %i' %
                         (level, slide_img.level_count))

    path_img_new = os.path.splitext(path_img)[0] + IMAGE_EXTENSION
    if os.path.isfile(path_img_new) and not overwrite:
        logging.warning('existing "%s"', path_img_new)
        return

    level_size = slide_img.level_dimensions[level]
    level_scale = slide_img.level_downsamples[level]

    level_downsample = 1
    while max(np.array(level_size) / level_downsample) > MAX_LOAD_IMAGE_SIZE:
        level_downsample *= 2
    logging.debug('using down-sample: %i', level_downsample)

    tile_size = (np.array(level_size) / level_downsample).astype(int)
    locations = [(i * tile_size[0], j * tile_size[1])
                 for i in range(level_downsample)
                 for j in range(level_downsample)]
    im = np.array(slide_img.read_region((0, 0), 0, size=(10, 10)))
    nb_channels = min(3, im.shape[2]) if im.ndim == 3 else 1
    img_size = list(tile_size * level_downsample)[::-1] + [nb_channels]
    image = np.zeros(img_size, dtype=np.uint8)
    for loc_i, loc_j in tqdm.tqdm(locations, desc=os.path.basename(path_img)):
        loc_img = int(loc_i * level_scale), int(loc_j * level_scale)
        img = np.array(slide_img.read_region(loc_img, level, size=tile_size))
        image[loc_j:loc_j + img.shape[0], loc_i:loc_i + img.shape[1],
              ...] = img[:, :, :nb_channels]
        del img

    if nb_channels == 2:
        image = image[:, :, 0]

    logging.debug('save image: "%s"', path_img_new)
    cv.imwrite(path_img_new, image, params=(cv.IMWRITE_PNG_COMPRESSION, 9))
    gc.collect()
    time.sleep(1)
Beispiel #8
0
class Slide(object):
    def __init__(self, image_path):
        super(Slide, self).__init__()
        self.image_path = image_path.strip()
        self.image_file = os.path.basename(image_path)
        self.image_name, self.suffix = self.image_file.split('.')
        if not self.suffix in config.format_mapping.keys():
            raise Exception('Error: File format ' + self.suffix +
                            ' is supported yet.')
        self._slide = OpenSlide(image_path)
        self._level_downsamples = self._slide.level_downsamples
        self._level_dimensions = self._slide.level_dimensions
        self.width, self.height = self._level_dimensions[0]

    @property
    def dimensions(self):
        return self._level_dimensions[0]

    @property
    def level_dimensions(self):
        return self._level_dimensions

    @property
    def level_downsamples(self):
        return self._level_downsamples

    def read_region(self, level, location, size):
        (x, y), (w, h) = location, size
        try:
            _ds = self._level_downsamples[level]
            patch = self._slide.read_region(level=level,
                                            location=(int(x * _ds),
                                                      int(y * _ds)),
                                            size=size)
        except Exception:
            raise
        else:
            return patch

    def get_thumbnail(self):
        try:
            image = self._slide.read_region(location=(0, 0),
                                            level=0,
                                            size=(1000, 1000))
        except Exception:
            raise
        else:
            return image
Beispiel #9
0
def main():
    filepath = sys.argv[1]
    img = OpenSlide(filepath)
    if not os.path.exists(sys.argv[3]):
        os.makedirs(sys.argv[3])
    if str(img.properties.values.__self__.get('tiff.ImageDescription')).split(
            "|")[1] == "AppMag = 40":
        sz = 1024
        seq = 924
    else:
        sz = 512
        seq = 462
    [w, h] = img.dimensions
    for x in range(1, w, seq):
        for y in range(1, h, seq):
            print(str(x) + ", " + str(y))
            img1 = img.read_region(location=(x, y), level=0, size=(sz, sz))
            img11 = img1.convert("RGB")
            img111 = img11.resize((512, 512), Image.ANTIALIAS)
            grad = getGradientMagnitude(np.array(img111))
            unique, counts = np.unique(grad, return_counts=True)
            if counts[np.argwhere(unique <= 20)].sum() < 512 * 512 * 0.6:
                img111.save(sys.argv[3] + "/" + sys.argv[2] + "_" + str(x) +
                            "_" + str(y) + '.jpg',
                            'JPEG',
                            optimize=True,
                            quality=94)
Beispiel #10
0
def v_slide(svs_path, bound_y, queue, tile_size, start_point):
    """
    """
    logger = logging.getLogger(__name__)
    AVG_THRESHOLD = 170
    LAYER = 0
    GREEN_CHANNEL_INDEX = 1
    try:
        svs_file = OpenSlide(svs_path)
        filename = os.path.basename(svs_path)

        x0 = start_point[0]
        y0 = start_point[1]

        pid = os.getpid()
        logger.debug(f'{pid}: start working...')
        logger.debug(f'worker {pid} working on {filename}...')
        while y0 < bound_y:
            img = svs_file.read_region((x0, y0), LAYER, (tile_size, tile_size))
            green_c_avg = np.average(np.array(img)[:, :, GREEN_CHANNEL_INDEX])
            if green_c_avg < AVG_THRESHOLD:
                img = np.array(img)
                img = img[:, :, 0:3]
                queue.put(img)

            y0 += tile_size

        logger.debug(f'{pid}: work finished.')
    finally:
        svs_file.close()
def convert(data):
    UNIT_X, UNIT_Y = 5000, 5000
    try:
        fname, input_dir, output_dir = data
        save_name = fname.split(".")[0] + ".jpg"
        print("Processing : %s"%fname)
        os_obj = OpenSlide(input_dir+"/"+fname)
        w, h = os_obj.dimensions
        w_rep, h_rep = int(w/UNIT_X)+1, int(h/UNIT_Y)+1
        w_end, h_end = w%UNIT_X, h%UNIT_Y
        w_size, h_size = UNIT_X, UNIT_Y
        w_start, h_start = 0, 0
        v_lst = []
        for i in range(h_rep):
            if i == h_rep-1:
                h_size = h_end 
            h_lst = []
            for j in range(w_rep):
                if j == w_rep-1:
                    w_size = w_end
                img = os_obj.read_region((w_start,h_start), 0, (w_size,h_size))
                img = img.convert("RGB")
                h_lst.append(img)
                w_start += UNIT_X
            v_lst.append(h_lst)
            w_size = UNIT_X
            h_start += UNIT_Y
            w_start = 0
        concat_h = [_get_concat_h(v) for v in v_lst]
        concat_hv = _get_concat_v(concat_h)
        concat_hv.save(output_dir+"/"+save_name)
    except:
        print("Can't open image file : %s"%fname)
        traceback.print_exc()
    return    
Beispiel #12
0
    def get_image_open(wsi_path):
        try:
            wsi_image = OpenSlide(wsi_path)
            level_used = 6
            rgb_image = np.array(
                wsi_image.read_region((0, 0), level_used,
                                      wsi_image.level_dimensions[level_used]))
            wsi_image.close()
        except OpenSlideUnsupportedFormatError:
            raise ValueError(
                'Exception: OpenSlideUnsupportedFormatError for %s' % wsi_path)

        # hsv -> 3 channel
        hsv = cv2.cvtColor(rgb_image, cv2.COLOR_BGR2HSV)
        lower_red = np.array([20, 20, 20])
        upper_red = np.array([200, 200, 200])
        # mask -> 1 channel
        mask = cv2.inRange(hsv, lower_red, upper_red)

        close_kernel = np.ones((20, 20), dtype=np.uint8)
        image_close = cv2.morphologyEx(np.array(mask), cv2.MORPH_CLOSE,
                                       close_kernel)
        open_kernel = np.ones((5, 5), dtype=np.uint8)
        image_open = cv2.morphologyEx(np.array(image_close), cv2.MORPH_OPEN,
                                      open_kernel)

        return image_open
Beispiel #13
0
def convert_image(path_img, level=DEFAULT_LEVEL, level_shift=DEFAULT_LEVEL_OFFSET, overwrite=False):
    slide_img = OpenSlide(path_img)
    assert level < len(slide_img.level_dimensions), \
        'unsupported level %i' % level
    assert (level + level_shift) < len(slide_img.level_dimensions), \
        'unsupported shift %i for level %i' % (level_shift, level)

    path_img_new = os.path.splitext(path_img)[0] + IMAGE_EXTENSION
    if os.path.isfile(path_img_new) and not overwrite:
        logging.debug('existing "%s"', path_img_new)
        return

    tile_size = slide_img.level_dimensions[level + level_shift]
    img_tiles_d0 = []
    tqdm_bar = tqdm.tqdm(total=(2 ** level_shift) ** 2,
                         desc=os.path.basename(path_img))
    for i in range(2 ** level_shift):
        img_tiles_d1 = []
        for j in range(2 ** level_shift):
            loc = (i * tile_size[0] * 2 ** level,
                   j * tile_size[1] * 2 ** level)
            img = slide_img.read_region(loc, level, size=tile_size)
            img_tiles_d1.append(img)
            tqdm_bar.update()
        img_tiles_d0.append(np.vstack(img_tiles_d1))
    image = np.hstack(img_tiles_d0)
    if image.shape[2] == 4:
        image = cv.cvtColor(image, cv.COLOR_RGBA2RGB)

    logging.debug('save image: "%s"', path_img_new)
    cv.imwrite(path_img_new, image, params=(cv.IMWRITE_PNG_COMPRESSION, 9))
    gc.collect()
    time.sleep(1)
def save_slide_cutting_multiple(file_path, save_location, multiple):
    slide = OpenSlide(file_path)
    level_cnt = slide.level_count
    for level in reversed(range(level_cnt)):
        downsample = slide.level_downsamples[level]
        w_lv_, h_lv_ = slide.level_dimensions[level]
        wsi_pil_lv_ = slide.read_region((0, 0), level, (w_lv_, h_lv_))
        wsi_ary_lv_ = np.array(wsi_pil_lv_)
        wsi_bgr_lv_ = cv2.cvtColor(wsi_ary_lv_, cv2.COLOR_RGBA2BGR)
        downsample = round(downsample)
        print(downsample)
        if downsample > multiple:
            continue
        elif downsample < multiple:
            downsample = multiple / downsample
            w = int(w_lv_ / downsample)
            h = int(h_lv_ / downsample)
            img = cv2.resize(wsi_bgr_lv_, (w, h),
                             interpolation=cv2.INTER_LINEAR)
            cv2.imwrite(save_location, img)
            break
        else:
            img = wsi_bgr_lv_
            cv2.imwrite(save_location, img)
            break
Beispiel #15
0
def generate_patches(filepath, window, stride, K, auto_ws, scaling_factor):
    slide = OpenSlide(filepath)
    image = np.asarray(slide.read_region((0, 0), 2,
                                         slide.level_dimensions[2]))[:, :, :3]
    image = np.array(image)
    if auto_ws:
        window = detect_best_window_size(image, 16, scaling_factor)
        stride = window
    h, w = image.shape[:2]
    regions = []
    j = 0
    while window + stride * j <= h:
        i = 0
        while window + stride * i <= w:
            x_start = i * stride
            y_start = j * stride
            patch = image[y_start:y_start + window,
                          x_start:x_start + window, :]
            white_ratio, g_mean, b_mean = compute_statistics(patch)
            region = (x_start, y_start, white_ratio, g_mean, b_mean)
            regions.append(region)
            i += 1
        j += 1
    regions = select_k_best_regions(regions, K)
    patches = get_k_best_regions(regions, image, window)
    return image, regions, patches, window
Beispiel #16
0
def v_slide(slp, n_y, x, y, tile_size, stepsize, x0, outdir, level, dp, std):
    # pid = os.getpid()
    # print('{}: start working'.format(pid))
    slide = OpenSlide(slp)
    imloc = []
    y0 = 0
    target_x = x0 * stepsize
    image_x = (target_x + x)*(4**level)
    while y0 < n_y:
        target_y = y0 * stepsize
        image_y = (target_y + y)*(4**level)
        img = slide.read_region((image_x, image_y), level, (tile_size, tile_size))
        wscore = bgcheck(img, tile_size)
        if wscore < 0.7:
            img = img.resize((299, 299))
            img = normalization(img, std)
            if dp:
                img.save(outdir + "/region_x-{}-y-{}_{}.png".format(image_x, image_y, str(dp)))
                strr = outdir + "/region_x-{}-y-{}_{}.png".format(image_x, image_y, str(dp))
            else:
                img.save(outdir + "/region_x-{}-y-{}.png".format(image_x, image_y))
                strr = outdir + "/region_x-{}-y-{}.png".format(image_x, image_y)
            imloc.append([x0, y0, image_x, image_y, strr])
        y0 += 1
    slide.close()
    return imloc
Beispiel #17
0
class MIRAX_Slide:

    def __init__(self, mirax_path):
        self.mirax_slide = OpenSlide(mirax_path)

    def read_region(self, location, level, size):
        """
        Read image region
        :param location: (x, y)
        :param level:
        :param size: (w, h)
        :return:
        """
        image = self.mirax_slide.read_region(location, level, size)
        image = np.array(image)
        if image.shape[2] > 3:
            image = image[:, :, 0:3]  # convert from RGBA to RGB
        return image

    def read_properties(self):

        mmp_x = float(self.mirax_slide.properties['openslide.mpp-x'])  # pixel size in um
        mmp_y = float(self.mirax_slide.properties['openslide.mpp-y'])  # pixel size in um

        # Distance in X from the center of the entire slide (i.e., the macro image) to the center of the main image, in nm
        offset_x = float(self.mirax_slide.properties['hamamatsu.XOffsetFromSlideCentre'])
        # Distance in Y from the center of the entire slide to the center of the main image, in nm
        offset_y = float(self.mirax_slide.properties['hamamatsu.YOffsetFromSlideCentre'])
        level_0_dim = self.mirax_slide.level_dimensions[0]
        level_0_width = level_0_dim[0]
        level_0_height = level_0_dim[1]
Beispiel #18
0
def sz(image_file, path_to_slide="../Neutrophil/"):
    slide = OpenSlide(path_to_slide + image_file)

    assert 'openslide.bounds-height' in slide.properties
    assert 'openslide.bounds-width' in slide.properties
    assert 'openslide.bounds-x' in slide.properties
    assert 'openslide.bounds-y' in slide.properties

    x = int(slide.properties['openslide.bounds-x'])
    y = int(slide.properties['openslide.bounds-y'])
    bounds_height = int(slide.properties['openslide.bounds-height'])
    bounds_width = int(slide.properties['openslide.bounds-width'])

    half_width_region = 49
    full_width_region = 299
    stepsize = full_width_region - half_width_region

    n_x = int((bounds_width - 1) / stepsize)
    n_y = int((bounds_height - 1) / stepsize)

    residue_x = int((bounds_width - n_x * stepsize) / 50)
    residue_y = int((bounds_height - n_y * stepsize) / 50)
    lowres = slide.read_region(
        (x, y), 2, (int(n_x * stepsize / 16), int(n_y * stepsize / 16)))
    lowres = np.array(lowres)[:, :, :3]

    return n_x, n_y, lowres, residue_x, residue_y
Beispiel #19
0
    def semantic2patch(self, patch_path):
        """
        Extract the patch of boundary
        :param patch_path: the path of save
        :return:
        """
        contours = measure.find_contours(self.result, 0.5)
        casepath = os.path.join(self.img_WSI_dir, self.name)
        wsi = OpenSlide(casepath)
        for i in xrange(len(contours)):
            print i, '/', len(contours)
            for j in range(len(contours[i])):
                y = int(contours[i][j, 0] * self.stride * 2**self.using_level)
                x = int(contours[i][j, 1] * self.stride * 2**self.using_level)
                img = np.array(
                    wsi.read_region((x, y), self.using_level,
                                    self.patch))[..., 0:-1]
                savepath = os.path.join(
                    patch_path, ''.join(os.path.basename(casepath).split(' ')))
                if not os.path.exists(savepath):
                    os.makedirs(savepath)
                io.imsave(
                    os.path.join(savepath,
                                 str(x) + '_' + str(y) + '.png'),
                    img.astype(np.float) / 255)

        print 'semantic2patch done'
Beispiel #20
0
def read_img(slide_file, location, level, size):
    slide = OpenSlide(slide_file)
    location = [int(x) for x in location]
    size = [int(x) for x in size]
    img = np.array(
        slide.read_region(location, int(level), size).convert(mode='RGB'))
    return img
Beispiel #21
0
def v_slide(slp, n_y, x, y, tile_size, stepsize, x0, outdir, std):
    # pid = os.getpid()
    # print('{}: start working'.format(pid))
    slide = OpenSlide(slp)
    imloc = []
    imlist = []
    y0 = 0
    target_x = x0 * stepsize
    image_x = target_x + x
    while y0 < n_y:
        target_y = y0 * stepsize
        image_y = target_y + y
        img = slide.read_region((image_x, image_y), 0, (tile_size, tile_size))
        wscore = bgcheck(img, tile_size)
        if wscore < 0.3:
            img = img.resize((tile_size, tile_size))
            # try:
            #     img = normalization(img, std)
            # except staintools.miscellaneous.exceptions.TissueMaskException:
            #     print("Empty tissue mask computed: region_x-{}-y-{}".format(image_x, image_y))
            #     y0 += 1
            #     continue
            # except:
            #     print('An error occurred: region_x-{}-y-{}'.format(image_x, image_y))
            #     y0 += 1
            #     continue
            img.save(outdir + "/region_x-{}-y-{}.png".format(image_x, image_y))
            strr = outdir + "/region_x-{}-y-{}.png".format(image_x, image_y)
            imloc.append([x0, y0, image_x, image_y, target_x, target_y, strr])
            # imlist.append(np.array(img)[:, :, :3])
        y0 += 1
    slide.close()
    return imloc, imlist
def random_tiles(imgfilename, inputdir, outputdir):
	print(imgfilename, inputdir, outputdir)
	print(os.path.join(inputdir, imgfilename), "\n \n ")
	if imgfilename.find(".svs") != -1 or imgfilename.find("mrxs") != -1:
		filepath = os.path.join(inputdir, imgfilename)
		sample_id = imgfilename.split(".")[0]
		#try:	
		img  = OpenSlide(filepath)
		if len(os.listdir(os.path.join(outputdir, sample_id))) == 0: 
			print("Sample ID in process   ", sample_id)
			try:
				os.mkdir(os.path.join(outputdir))
			except:
				print("The Folder already exist")
			try:
				os.mkdir(os.path.join(outputdir, sample_id))
			except:
				print("The Folder for the sample id {} already exist".format(sample_id))
				print("HERE")
			if imgfilename.find(".svs") != -1 :
				if str(img.properties.values.__self__.get('tiff.ImageDescription')).split("|")[1] == "AppMag = 40":
					sz=2048
					seq=1748
				else:
					sz=1024
					seq=874
			elif  imgfilename.find("mrxs") != -1:
				if str(img.properties.values.__self__.get("mirax.GENERAL.OBJECTIVE_MAGNIFICATION")) == 20:
					sz=1024
					seq=874
				else: 
					sz=2048
					seq=1748
			[w, h] = img.dimensions
			couple_coords_accepted = []
			for x in range(1, w, seq):
				for y in range(1, h, seq):
					#try:
					img1=img.read_region(location=(x,y), level=0, size=(sz,sz))
					print('img1')
					img11=img1.convert("RGB")
					print('img11')
					img111=img11.resize((512,512),Image.ANTIALIAS)
					print('img111')
					pix = np.array(img111)
					print('pix')
					grad=getGradientMagnitude(pix)
					print('grad')
					unique, counts = np.unique(grad, return_counts=True)
					print('unique')
					mean_ch = np.mean(pix, axis=2)
					print('mean_ch')
					bright_pixels_count = np.argwhere(mean_ch > 220).shape[0]
					print('bright_pixels_count')
					if counts[np.argwhere(unique<=15)].sum() < 512*512*0.6 and bright_pixels_count <  512*512*0.5 :
						couple_coords_accepted.append((x,y))
						img111.save( os.path.join(outputdir, sample_id, sample_id + "_" +  str(x) + "_" + str(y) + '.jpg'  ) , 'JPEG', optimize=True, quality=94)
						print('tiles written ', os.path.join(outputdir, sample_id, sample_id + "_" +  str(x) + "_" + str(y) + '.jpg'  ))
Beispiel #23
0
 def test_operations_on_closed_handle(self):
     osr = OpenSlide(file_path('boxes.tiff'))
     props = osr.properties
     associated = osr.associated_images
     osr.close()
     self.assertRaises(ArgumentError, lambda: osr.read_region((0, 0), 0, (100, 100)))
     self.assertRaises(ArgumentError, lambda: osr.close())
     self.assertRaises(ArgumentError, lambda: props['openslide.vendor'])
     self.assertRaises(ArgumentError, lambda: associated['label'])
def save_slide_as_jpg_with_level(file_path, save_location, level):
    slide_tif = OpenSlide(file_path)
    print(('==> saving slide_lv_%s at ' + save_location) % level)

    wsi_pil_lv_ = slide_tif.read_region((0, 0), level, \
                                        slide_tif.level_dimensions[level])
    wsi_ary_lv_ = np.array(wsi_pil_lv_)
    wsi_bgr_lv_ = cv2.cvtColor(wsi_ary_lv_, cv2.COLOR_RGBA2BGR)
    cv2.imwrite(save_location, wsi_bgr_lv_)
Beispiel #25
0
def wsi_to_numpy(wsi: openslide.OpenSlide, level: int = 3) -> np.ndarray:
    """Transforme une lame format .svs en une matrice numpy selon un 
    niveau de résolution prédéfini en paramètre. Attention: le niveau
    doit être suffisamment élevé pour que l'image rentre en mémoire !
    """
    assert level > 0, 'Sélectionnez un niveau de résolution plus faible!'
    image = np.asarray(
        wsi.read_region((0, 0), level,
                        wsi.level_dimensions[level]).convert('RGB'))
    return image
def read_wsi_normal(wsi_normal_path, resolution_level=None):

    wsi_normal = OpenSlide(wsi_normal_path)
    if resolution_level is None:
        resolution_level = wsi_normal.level_count - 1
    wsi_normal_sample = wsi_normal.read_region(
        (0, 0), resolution_level,
        wsi_normal.level_dimensions[resolution_level])
    wsi_normal.close()
    return wsi_normal_sample
Beispiel #27
0
def wsi_to_jpg(sample_path, output_path):
    slide = OpenSlide(sample_path)
    w, h = slide.dimensions
    new_w = math.floor(w / SCALE_FACTOR)
    new_h = math.floor(h / SCALE_FACTOR)
    level = slide.get_best_level_for_downsample(SCALE_FACTOR)
    pil_img = slide.read_region(
        (0, 0), level, slide.level_dimensions[level]).convert("RGB").resize(
            (new_w, new_h), PIL.Image.BILINEAR)
    pil_img.save(output_path)
Beispiel #28
0
def read_wsi(tif_file_path, level):
    
    '''
        Identify and load slides.
        Returns:
            - wsi_image: OpenSlide object.
            - rgba_image: WSI image loaded, NumPy array type.
    '''
    
    time_s = time.time()
    
    try:
        wsi_image = OpenSlide(tif_file_path)
        slide_w_, slide_h_ = wsi_image.level_dimensions[level]
        
        '''
            The read_region loads the target area into RAM memory, and
            returns an Pillow Image object.

            !! Take care because WSIs are gigapixel images, which are could be 
            extremely large to RAMs.

            Load the whole image in level < 3 could cause failures.
        '''

        # Here we load the whole image from (0, 0), so transformation of coordinates 
        # is not skipped.

        rgba_image_pil = wsi_image.read_region((0, 0), level, (slide_w_, slide_h_))
        print("width, height:", rgba_image_pil.size)

        '''
            !!! It should be noted that:
            1. np.asarray() / np.array() would switch the position 
            of WIDTH and HEIGHT in shape.

            Here, the shape of $rgb_image_pil is: (WIDTH, HEIGHT, CHANNEL).
            After the np.asarray() transformation, the shape of $rgb_image is: 
            (HEIGHT, WIDTH, CHANNEL).

            2. The image here is RGBA image, in which A stands for Alpha channel.
            The A channel is unnecessary for now and could be dropped.
        '''
        rgba_image = np.asarray(rgba_image_pil)
        print("transformed:", rgba_image.shape)
        
    except OpenSlideUnsupportedFormatError:
        print('Exception: OpenSlideUnsupportedFormatError')
        return None

    time_e = time.time()
    
    print("Time spent on loading", tif_file_path, ": ", (time_e - time_s))
    
    return wsi_image, rgba_image, (slide_w_, slide_h_)
Beispiel #29
0
def save_patch(\
        file_path_tif,
        save_location_path_patch,
        patch_level,
        size_patch):
    
    print('=> Making patch ..')

    # Read file name list of slide directory
    file_name_list_tif = get_list_file_name(file_path_tif)

    for index in range(len(file_name_list_tif)):

        file_name_tif = file_name_list_tif[index]
        file_name_slide = file_name_tif.split('.')[0]
        file_name_csv = file_name_slide + '.csv'

        cur_file_path_tif =\
                os.path.join(file_path_tif, file_name_tif)
        cur_file_path_csv =\
                os.path.join(save_location_path_patch, file_name_slide)
        cur_file_path_csv =\
                os.path.join(cur_file_path_csv, file_name_csv)

        # Load slide image
        slide = OpenSlide(cur_file_path_tif)

        # Read patch position csv file
        csv_file = open(cur_file_path_csv, 'rb')
        csv_reader = csv.DictReader(csv_file)
        csv_data = list(csv_reader)

        # Make patch and Save 
        for i, row in enumerate(csv_data):

            x = int(row['X'])
            y = int(row['Y'])
            patch = slide.read_region((x, y),\
                                patch_level,\
                                (size_patch, size_patch))
            patch = np.array(patch)
            patch = cv2.cvtColor(patch, cv2.COLOR_RGBA2BGR)
            
            file_name_patch_jpg = file_name_slide + '_patch_' + str(i) + '.jpg'
            cur_save_path_patch_jpg =\
                    os.path.join(save_location_path_patch,\
                                 file_name_slide)
            cur_save_path_patch_jpg =\
                    os.path.join(cur_save_path_patch_jpg ,\
                                 file_name_patch_jpg)
            cv2.imwrite(cur_save_path_patch_jpg, patch)
        
        csv_file.close()

        print('=> Next..')
Beispiel #30
0
def get_region(wsi: openslide.OpenSlide, x: int, y: int, level: int,
               width: int, height: int) -> Image:
    """Sélectionne la région d'intérêt sur la lame.
    Paramètres:
        x, y   : origine en haut à gauche selon la largeur et la hauteur
        level  : niveau de résolution (0 le plus élevé)
        width  : largeur de la région
        height : hauteur de la région
    """
    region = wsi.read_region((x, y), level, (width, height))
    return region
    def read_wsi_mask(mask_path, level=def_level):
        try:
            wsi_mask = OpenSlide(mask_path)

            mask_image = np.array(wsi_mask.read_region((0, 0), level,
                                                       wsi_mask.level_dimensions[level]))

        except OpenSlideUnsupportedFormatError:
            print('Exception: OpenSlideUnsupportedFormatError')
            return None, None

        return wsi_mask, mask_image
def read_wsi_tumor(wsi_tumor_path, wsi_mask_path, resolution_level=None):

    try:

        wsi_tumor = OpenSlide(wsi_tumor_path)
        if resolution_level is None:
            resolution_level = wsi_tumor.level_count - 1
        wsi_tumor_sample = wsi_tumor.read_region(
            (0, 0), resolution_level,
            wsi_tumor.level_dimensions[resolution_level])
        wsi_tumor.close()

        wsi_tumor_mask = OpenSlide(wsi_mask_path)
        wsi_tumor_mask_sample = wsi_tumor_mask.read_region(
            (0, 0), resolution_level,
            wsi_tumor_mask.level_dimensions[resolution_level])
        wsi_tumor_mask.close()
    except Exception as e:
        return None, None

    return wsi_tumor_sample, wsi_tumor_mask_sample
    def read_wsi_mask(mask_path, level=def_level):
        try:
            wsi_mask = OpenSlide(mask_path)

            mask_image = np.array(wsi_mask.read_region((0, 0), level,
                                                       wsi_mask.level_dimensions[level]))

        except OpenSlideUnsupportedFormatError:
            print('Exception: OpenSlideUnsupportedFormatError')
            return None, None

        return wsi_mask, mask_image
def process(opts):
    i, pid, x_center, y_center, file_path_tif, path_patch, patch_size, patch_level = opts
    x = int(int(float(x_center)) - 1024 / 2)
    y = int(int(float(y_center)) - 1024 / 2)
    wsi_path = os.path.join(file_path_tif + pid + '.svs')
    slide = OpenSlide(wsi_path)
    img = slide.read_region((x, y), 0, (1024, 1024)).convert('RGB')
    if not os.path.exists(os.path.join(path_patch,
                                       pid + "_" + str(i) + '.png')):

        print(os.path.join(path_patch, pid + "_" + str(i) + '.png'))
        img.save(os.path.join(path_patch, pid + "_" + str(i) + '.png'))
Beispiel #35
0
def tile(image_file, outdir, level, std_img, path_to_slide=str(cwd+"/../images/"), dp=None, ft=1):
    slide = OpenSlide(path_to_slide+image_file)
    slp = str(path_to_slide+image_file)
    print(slp)
    print(slide.level_dimensions)

    bounds_width = slide.level_dimensions[level][0]
    bounds_height = slide.level_dimensions[level][1]
    x = 0
    y = 0
    half_width_region = 49*ft
    full_width_region = 299*ft
    stepsize = (full_width_region - half_width_region)

    n_x = int((bounds_width - 1) / stepsize)
    n_y = int((bounds_height - 1) / stepsize)

    lowres = slide.read_region((x, y), level+1, (int(n_x*stepsize/4), int(n_y*stepsize/4)))
    lowres = np.array(lowres)[:,:,:3]

    x0 = 0
    # create multiporcessing pool
    print(mp.cpu_count())
    pool = mp.Pool(processes=mp.cpu_count())
    tasks = []
    while x0 < n_x:
        task = tuple((slp, n_y, x, y, full_width_region, stepsize, x0, outdir, level, dp, std_img))
        tasks.append(task)
        x0 += 1
    # slice images with multiprocessing
    temp = pool.starmap(v_slide, tasks)
    tempdict = list(temp)
    temp = None
    pool.close()
    pool.join()

    tempdict = list(filter(None, tempdict))
    imloc = []
    list(map(imloc.extend, tempdict))
    imlocpd = pd.DataFrame(imloc, columns = ["X_pos", "Y_pos", "X", "Y", "Loc"])
    imlocpd = imlocpd.sort_values(["X_pos", "Y_pos"], ascending=[True, True])
    imlocpd = imlocpd.reset_index(drop=True)
    imlocpd = imlocpd.reset_index(drop=False)
    imlocpd.columns = ["Num", "X_pos", "Y_pos", "X", "Y", "Loc"]
    if dp:
        imlocpd.to_csv(outdir + "/{}_dict.csv".format(dp), index=False)
    else:
        imlocpd.to_csv(outdir + "/dict.csv", index=False)
    tempdict = None
    ct = len(imloc)
    print(ct)

    return n_x, n_y, lowres, ct
Beispiel #36
0
def run(filename, split, level, dred, dbrown, debug):

# Create OpenSlide object
	ndpi         = OpenSlide(filename)
	ndpi_width   = ndpi.dimensions[0]
	ndpi_height  = ndpi.dimensions[1]
	total_width  = ndpi.level_dimensions[level][0]
	total_height = ndpi.level_dimensions[level][1]
	
	red_sum     = 0.0
	brown_sum   = 0.0
	surface_sum = 0.0

	startTime    = time.time()

	if debug:
		print "filename: {}".format(filename)
		print "split: {}".format(split)
		print "level: {}".format(level)
		print "dred: {}".format(dred)
		print "dbrown: {}".format(dbrown)
		print "debug: {}".format(debug)


	if debug:
		print "================ START ================="
		print "LOAD {}".format(filename)
		print "width:".ljust(20) + str(ndpi_width)
		print "height:".ljust(20) + str(ndpi_height)
		print "level count:".ljust(20) + str(ndpi.level_count)
		print "split image {}x{} , level:{} , factor:{}".format(total_width,total_height,level,split)
		
	bar = Bar('Processing', max=split**2)
	for i in range(split):
		for j in range(split):
			x     = i * ndpi_width / split
			y     = j * ndpi_height / split
			w     = total_width / split
			h     = total_height / split

			if debug:
				print "\n>SLICE [{}][{}]".format(i,j)
				print "x:{:3} y:{:3} w:{:3}px h:{:3}px:".format(x,y,w,h)

			region  = ndpi.read_region((x,y), level, (w, h))
			red     = bgsa.get_red(region, brightness=-dred)
			brown   = bgsa.get_brown(region, brightness=-dbrown)
			# surface = bgsa.get_surface(region)

			region.save("output/normal_slice{}{}.png".format(i,j))
			red.save("output/red_slice_{}{}.png".format(i,j))
			brown.save("output/brown_slice_{}{}.png".format(i,j))
			# surface.save("output/surface_slice_{}{}.png".format(i,j))

			red_sum    += bgsa.get_white_pixels(red)
			brown_sum  += bgsa.get_white_pixels(brown)
			# surface_sum+= bgsa.get_white_pixels(surface)

			if debug:
				bar.next()

			
			# print "white:{}% black{}%".format(results["white"], results["black"])

	if debug:
		bar.finish()
		print "Finished....in {:.2f} sec".format(time.time() - startTime)
		print "total red   :".ljust(20) + str(red_sum)
		print "total brown :".ljust(20) + str(brown_sum)

	return {"red":red_sum, "brown":brown_sum}
class QtCustomWindow( qt.QWidget ):
    def __init__( self, parent = None ) :
        qt.QWidget.__init__( self, parent )
        self.current_x=0
        self.current_y=0
        #read region always works in the level 0 reference for reading locations
        self.current_zoom=0
        self.image_width=750
        self.image_height=750
        self.setWindowTitle('Red Rock')
        self.hbox = qt.QHBoxLayout(self)
        self.lbl = qt.QLabel(self)
        self.setLayout(self.hbox)
        self.initUI()
    def initUI(self):      
        # initialize the widget, make the openslide object pointing to the
        # multilevel image and initialize the view to the top left corner
        
        archivo=u'/home/martin/Downloads/CMU-1-JP2K-33005.svs'
        # openSlide object
        self.osr = OS(archivo)
        self.level_count = self.osr.level_count
        self.current_x=0
        self.current_y=0
        self.current_zoom=self.level_count-1
        self.level_dimensions=self.osr.level_dimensions
        print self.level_dimensions
        print self.osr.level_downsamples
        #width, height = osr.dimensions

        

        

        self.hbox.addWidget(self.lbl)
        
        
        #self.move(300, 200)

        
        self.updatePixmap()
        self.show()
    def updatePixmap(self):
        im=self.osr.read_region((self.current_x,self.current_y),self.current_zoom,(self.image_width,self.image_height))
        
        data = im.tostring('raw', 'RGBA')
        image = qt.QImage(data, im.size[0], im.size[1], qt.QImage.Format_ARGB32)
        pix = qt.QPixmap.fromImage(image)
        self.lbl.setPixmap(pix)
        self.lbl.show()      
    def keyPressEvent( self, event ) :
        key = event.text()
        #larger steps for zoomed out images
        step =int(64*self.osr.level_downsamples[self.current_zoom])
        print type(step)
        print type(self.current_x)
        if key=="s":
            
            self.current_y += step 
            print type(self.current_y)
            self.current_y = min(self.current_y,int(
                self.level_dimensions[0][1]-self.image_height*self.osr.level_downsamples[self.current_zoom]))
        elif key=="w":
            #larger steps for zoomed out images
            self.current_y -= step
            self.current_y = max(0, self.current_y)
        elif key=="a":
            #larger steps for zoomed out images
            self.current_x -= step
            self.current_x = max(0, self.current_x)
        elif key=="d":
            #larger steps for zoomed out images
            self.current_x += step
            self.current_x = min(self.current_x,int(
                self.level_dimensions[0][0]-self.image_width*self.osr.level_downsamples[self.current_zoom]))
        elif key=="q":
            new_zoom = min(self.current_zoom+1,self.level_count-1)
            self.updateCorner(new_zoom)
            self.current_zoom=new_zoom
        elif key=="e":
            new_zoom = max(self.current_zoom-1,0)
            self.updateCorner(new_zoom)
            self.current_zoom=new_zoom
        print "x: %s" % self.current_x
        print "y: %s" % self.current_y
        print "zoom: %s" % self.current_zoom
        self.updatePixmap()
    def updateCorner(self,new_zoom):
        #updates the current_x and current_y values to preserve the image center
        #while zooming
        self.current_x=int(self.current_x + self.image_width /2 *(self.osr.level_downsamples[self.current_zoom]-self.osr.level_downsamples[new_zoom]))
        self.current_y=int(self.current_y + self.image_height /2 *(self.osr.level_downsamples[self.current_zoom]-self.osr.level_downsamples[new_zoom]))
class WSI(object):
    """
        # ================================
        # Class to annotate WSIs with ROIs
        # ================================

    """
    index = 0
    wsi_paths = []
    mask_paths = []
    def_level = 7
    key = 0

    def read_normal_wsi(self, wsi_path):
        """
            # =====================================================================================
            # read WSI image and resize
            # Due to memory constraint, we use down sampled (4th level, 1/32 resolution) image
            # ======================================================================================
        """
        try:
            self.wsi_path = wsi_path
            self.wsi_image = OpenSlide(wsi_path)

            level = min(self.def_level, self.wsi_image.level_count - 1)
            print('level used: %d' % level)
            print(self.wsi_image.level_dimensions[level])

            self.rgb_image_pil = self.wsi_image.read_region((0, 0), level,
                                                            self.wsi_image.level_dimensions[level])
            self.rgb_image = np.array(self.rgb_image_pil)

        except OpenSlideUnsupportedFormatError:
            print('Exception: OpenSlideUnsupportedFormatError')
            return False

        return True

    def read_tumor_wsi(self, wsi_path, mask_path):
        """
            # =====================================================================================
            # read WSI image and resize
            # Due to memory constraint, we use down sampled (4th level, 1/32 resolution) image
            # ======================================================================================
        """
        try:
            self.wsi_path = wsi_path
            self.wsi_image = OpenSlide(wsi_path)
            self.mask_image = OpenSlide(mask_path)

            level_used = self.wsi_image.level_count - 1

            self.rgb_image_pil = self.wsi_image.read_region((0, 0), level_used,
                                                            self.wsi_image.level_dimensions[level_used])
            self.rgb_image = np.array(self.rgb_image_pil)

            mask_level = self.mask_image.level_count - 1
            self.rgb_mask_pil = self.mask_image.read_region((0, 0), mask_level,
                                                            self.mask_image.level_dimensions[mask_level])

            resize_factor = float(1.0 / pow(2, level_used - mask_level))
            self.mask = cv2.resize(np.array(self.rgb_mask_pil), (0, 0), fx=resize_factor, fy=resize_factor)
            # self.rgb_image = cv2.resize(self.rgb_image, (0, 0), fx=0.50, fy=0.50)
        except OpenSlideUnsupportedFormatError:
            print('Exception: OpenSlideUnsupportedFormatError')
            return False

        return True

    def find_roi_normal(self):
        # self.mask = cv2.cvtColor(self.mask, cv2.CV_32SC1)
        hsv = cv2.cvtColor(self.rgb_image, cv2.COLOR_BGR2HSV)
        # [20, 20, 20]
        lower_red = np.array([30, 30, 30])
        # [255, 255, 255]
        upper_red = np.array([200, 200, 200])
        mask = cv2.inRange(hsv, lower_red, upper_red)
        res = cv2.bitwise_and(self.rgb_image, self.rgb_image, mask=mask)

        # (50, 50)
        close_kernel = np.ones((50, 50), dtype=np.uint8)
        close_kernel_tmp = np.ones((30, 30), dtype=np.uint8)
        image_close = Image.fromarray(cv2.morphologyEx(np.array(mask), cv2.MORPH_CLOSE, close_kernel))
        image_close_tmp = Image.fromarray(cv2.morphologyEx(np.array(mask), cv2.MORPH_CLOSE, close_kernel_tmp))
        # (30, 30)
        open_kernel = np.ones((30, 30), dtype=np.uint8)
        open_kernel_tmp = np.ones((30, 30), dtype=np.uint8)
        image_open = Image.fromarray(cv2.morphologyEx(np.array(image_close), cv2.MORPH_OPEN, open_kernel))
        image_open_tmp = Image.fromarray(cv2.morphologyEx(np.array(image_close_tmp), cv2.MORPH_OPEN, open_kernel_tmp))
        contour_rgb, bounding_boxes, contour_rgb_tmp = self.get_normal_image_contours(np.array(image_open),
                                                                                      self.rgb_image,
                                                                                      np.array(image_open_tmp))
        # self.draw_bbox(bounding_boxes)

        self.display(contour_rgb, contour_rgb_tmp)

    def find_roi_tumor(self):
        # self.mask = cv2.cvtColor(self.mask, cv2.CV_32SC1)
        hsv = cv2.cvtColor(self.rgb_image, cv2.COLOR_BGR2HSV)
        lower_red = np.array([20, 20, 20])
        upper_red = np.array([200, 200, 200])
        mask = cv2.inRange(hsv, lower_red, upper_red)
        res = cv2.bitwise_and(self.rgb_image, self.rgb_image, mask=mask)

        # (50, 50)
        close_kernel = np.ones((20, 20), dtype=np.uint8)
        close_kernel_tmp = np.ones((50, 50), dtype=np.uint8)
        image_close = Image.fromarray(cv2.morphologyEx(np.array(mask), cv2.MORPH_CLOSE, close_kernel))
        image_close_tmp = Image.fromarray(cv2.morphologyEx(np.array(mask), cv2.MORPH_CLOSE, close_kernel_tmp))
        # (30, 30)
        open_kernel = np.ones((5, 5), dtype=np.uint8)
        open_kernel_tmp = np.ones((30, 30), dtype=np.uint8)
        image_open = Image.fromarray(cv2.morphologyEx(np.array(image_close), cv2.MORPH_OPEN, open_kernel))
        image_open_tmp = Image.fromarray(cv2.morphologyEx(np.array(image_close_tmp), cv2.MORPH_OPEN, open_kernel_tmp))
        contour_rgb, contour_mask, bounding_boxes, contour_rgb_tmp, contour_mask_tmp = self.get_tumor_image_contours(
            np.array(image_open), self.rgb_image,
            self.mask, np.array(image_open_tmp))

        wsi_name = utils.get_filename_from_path(self.wsi_path)
        # cv2.imwrite(os.path.join(utils.THESIS_FIGURE_DIR, wsi_name) + '_hsv_mask.png', mask)
        # cv2.imwrite(os.path.join(utils.THESIS_FIGURE_DIR, wsi_name) + '_mask.png', self.mask)
        # cv2.imwrite(os.path.join(utils.THESIS_FIGURE_DIR, wsi_name) + '_image_close.png', np.array(image_close))
        # cv2.imwrite(os.path.join(utils.THESIS_FIGURE_DIR, wsi_name) + '_image_open.png', np.array(image_open))

        # rgb_bbox = self.rgb_image.copy()
        # for i, bounding_box in enumerate(bounding_boxes):
        #     x = int(bounding_box[0])
        #     y = int(bounding_box[1])
        #     cv2.rectangle(rgb_bbox, (x, y), (x + bounding_box[2], y + bounding_box[3]), color=(0, 0, 255),
        #                   thickness=2)

        # cv2.imshow('contour_rgb', contour_rgb)
        # cv2.imshow('contour_bbox', rgb_bbox)
        # cv2.imwrite(os.path.join(utils.THESIS_FIGURE_DIR, wsi_name) + 'contour.png', contour_rgb)
        # cv2.imwrite(os.path.join(utils.THESIS_FIGURE_DIR, wsi_name) + '_bbox.png', rgb_bbox)
        cv2.imwrite(os.path.join(utils.THESIS_FIGURE_DIR, wsi_name) + '_hsv.png', hsv)
        cv2.imshow('hsv', hsv)
        cv2.waitKey(0)

        # self.display(contour_rgb, contour_rgb_tmp, contour_mask)

    def get_normal_image_contours(self, cont_img, rgb_image, cont_img_tmp):
        _, contours, _ = cv2.findContours(cont_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        _, contours_tmp, _ = cv2.findContours(cont_img_tmp, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        # print(contours)
        boundingBoxes = [cv2.boundingRect(c) for c in contours]
        # print(boundingBoxes)
        contours_rgb_image_array = np.array(rgb_image)
        contours_rgb_image_array_tmp = np.array(rgb_image)

        line_color = (255, 0, 0)  # blue color code
        cv2.drawContours(contours_rgb_image_array, contours, -1, line_color, 3)
        cv2.drawContours(contours_rgb_image_array_tmp, contours_tmp, -1, line_color, 3)
        # cv2.drawContours(mask_image, contours_mask, -1, line_color, 3)
        return contours_rgb_image_array, boundingBoxes, contours_rgb_image_array_tmp

    def get_tumor_image_contours(self, cont_img, rgb_image, mask_image, cont_img_tmp):
        _, contours, _ = cv2.findContours(cont_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        _, contours_tmp, _ = cv2.findContours(cont_img_tmp, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        # _, contours_mask, _ = cv2.findContours(mask_image, cv2.RETR_FLOODFILL, cv2.CHAIN_APPROX_SIMPLE)
        # print(contours)
        boundingBoxes = [cv2.boundingRect(c) for c in contours]
        # print(boundingBoxes)
        contours_rgb_image_array = np.array(rgb_image)
        contours_rgb_image_array_tmp = np.array(rgb_image)
        contours_mask_image_array = np.array(mask_image)
        contours_mask_image_array_tmp = np.array(mask_image)

        line_color = (255, 0, 0)  # blue color code
        cv2.drawContours(contours_rgb_image_array, contours, -1, line_color, 3)
        cv2.drawContours(contours_rgb_image_array_tmp, contours_tmp, -1, line_color, 3)
        cv2.drawContours(contours_mask_image_array, contours, -1, line_color, 3)
        cv2.drawContours(contours_mask_image_array_tmp, contours_tmp, -1, line_color, 3)
        # cv2.drawContours(mask_image, contours_mask, -1, line_color, 3)
        return contours_rgb_image_array, contours_mask_image_array, boundingBoxes, contours_rgb_image_array_tmp, \
               contours_mask_image_array_tmp

    def display(self, contour_rgb, contour_rgb_tmp, contour_mask=None):
        # cv2.imshow('rgb', self.rgb_image)
        # cv2.imshow('mask', mask)
        # cv2.imshow('image_close',np.array(image_close))
        # cv2.imshow('image_open', np.array(image_open))

        contour_rgb = cv2.resize(contour_rgb, (0, 0), fx=0.60, fy=0.60)
        cv2.imshow('contour_rgb', np.array(contour_rgb))
        contour_rgb_tmp = cv2.resize(contour_rgb_tmp, (0, 0), fx=0.60, fy=0.60)
        cv2.imshow('contour_rgb_tmp', np.array(contour_rgb_tmp))
        if contour_mask is not None:
            contour_mask = cv2.resize(contour_mask, (0, 0), fx=0.60, fy=0.60)
            cv2.imshow('contour_mask', np.array(contour_mask))

        # contour_mask_tmp = cv2.resize(contour_mask_tmp, (0, 0), fx=0.40, fy=0.40)
        # cv2.imshow('contour_mask_tmp', np.array(contour_mask_tmp))
        # cv2.imshow('contour_mask_only', np.array(contour_mask_only))
        # cv2.imshow('wsi_mask', self.mask)
        # cv2.imshow('self_bb', np.array(self.rgb_image_pil))

    def draw_bbox(self, bounding_boxes):
        draw = ImageDraw.Draw(self.rgb_image_pil)
        for i, bounding_box in enumerate(bounding_boxes):
            x = int(bounding_box[0])
            y = int(bounding_box[1])
            thickness = 5
            for offset in range(thickness):
                draw.rectangle([x + offset, y + offset, x + offset + bounding_box[2], y + offset + bounding_box[3]],
                               outline=(255, 0, 0))

    def wait(self):
        self.key = cv2.waitKey(0) & 0xFF
        print('key: %d' % self.key)

        if self.key == 27:  # escape
            return False
        elif self.key == 81:  # <- (prev)
            self.index -= 1
            if self.index < 0:
                self.index = len(self.wsi_paths) - 1
        elif self.key == 83:  # -> (next)
            self.index += 1
            if self.index >= len(self.wsi_paths):
                self.index = 0

        return True
class WSI(object):
    """
        # ================================
        # Class to annotate WSIs with ROIs
        # ================================

    """
    index = 0
    negative_patch_index = 118456
    positive_patch_index = 2230
    wsi_paths = []
    mask_paths = []
    def_level = 7
    key = 0

    def extract_patches_mask(self, bounding_boxes):
        """
        Extract positive patches targeting annotated tumor region

        Save extracted patches to desk as .png image files

        :param bounding_boxes: list of bounding boxes corresponds to tumor regions
        :return:

        """
        mag_factor = pow(2, self.level_used)

        print('No. of ROIs to extract patches from: %d' % len(bounding_boxes))

        for i, bounding_box in enumerate(bounding_boxes):
            b_x_start = int(bounding_box[0]) * mag_factor
            b_y_start = int(bounding_box[1]) * mag_factor
            b_x_end = (int(bounding_box[0]) + int(bounding_box[2])) * mag_factor
            b_y_end = (int(bounding_box[1]) + int(bounding_box[3])) * mag_factor
            X = np.random.random_integers(b_x_start, high=b_x_end, size=500)
            Y = np.random.random_integers(b_y_start, high=b_y_end, size=500)
            # X = np.arange(b_x_start, b_x_end-256, 5)
            # Y = np.arange(b_y_start, b_y_end-256, 5)

            for x, y in zip(X, Y):
                mask = self.mask_image.read_region((x, y), 0, (PATCH_SIZE, PATCH_SIZE))
                mask_gt = np.array(mask)
                mask_gt = cv2.cvtColor(mask_gt, cv2.COLOR_BGR2GRAY)

                white_pixel_cnt_gt = cv2.countNonZero(mask_gt)

                if white_pixel_cnt_gt > ((PATCH_SIZE * PATCH_SIZE) * 0.90):
                    # mask = Image.fromarray(mask)
                    patch = self.wsi_image.read_region((x, y), 0, (PATCH_SIZE, PATCH_SIZE))
                    patch.save(PROCESSED_PATCHES_FROM_USE_MASK_POSITIVE_PATH + PATCH_TUMOR_PREFIX +
                               str(self.positive_patch_index), 'PNG')
                    self.positive_patch_index += 1
                    patch.close()

                mask.close()

    def extract_patches_normal(self, bounding_boxes):
        """
            Extract negative patches from Normal WSIs

            Save extracted patches to desk as .png image files

            :param bounding_boxes: list of bounding boxes corresponds to detected ROIs
            :return:

        """
        mag_factor = pow(2, self.level_used)

        print('No. of ROIs to extract patches from: %d' % len(bounding_boxes))

        for i, bounding_box in enumerate(bounding_boxes):
            b_x_start = int(bounding_box[0]) * mag_factor
            b_y_start = int(bounding_box[1]) * mag_factor
            b_x_end = (int(bounding_box[0]) + int(bounding_box[2])) * mag_factor
            b_y_end = (int(bounding_box[1]) + int(bounding_box[3])) * mag_factor
            X = np.random.random_integers(b_x_start, high=b_x_end, size=500)
            Y = np.random.random_integers(b_y_start, high=b_y_end, size=500)
            # X = np.arange(b_x_start, b_x_end-256, 5)
            # Y = np.arange(b_y_start, b_y_end-256, 5)

            for x, y in zip(X, Y):
                patch = self.wsi_image.read_region((x, y), 0, (PATCH_SIZE, PATCH_SIZE))
                patch_array = np.array(patch)

                patch_hsv = cv2.cvtColor(patch_array, cv2.COLOR_BGR2HSV)
                # [20, 20, 20]
                lower_red = np.array([20, 20, 20])
                # [255, 255, 255]
                upper_red = np.array([200, 200, 200])
                mask = cv2.inRange(patch_hsv, lower_red, upper_red)
                white_pixel_cnt = cv2.countNonZero(mask)

                if white_pixel_cnt > ((PATCH_SIZE * PATCH_SIZE) * 0.50):
                    # mask = Image.fromarray(mask)
                    patch.save(PROCESSED_PATCHES_NORMAL_NEGATIVE_PATH + PATCH_NORMAL_PREFIX +
                               str(self.negative_patch_index), 'PNG')
                    # mask.save(PROCESSED_PATCHES_NORMAL_PATH + PATCH_NORMAL_PREFIX + str(self.patch_index),
                    #           'PNG')
                    self.negative_patch_index += 1

                patch.close()

    def extract_patches_tumor(self, bounding_boxes):
        """
            Extract both, negative patches from Normal area and positive patches from Tumor area

            Save extracted patches to desk as .png image files

            :param bounding_boxes: list of bounding boxes corresponds to detected ROIs
            :return:
            
        """
        mag_factor = pow(2, self.level_used)

        print('No. of ROIs to extract patches from: %d' % len(bounding_boxes))

        for i, bounding_box in enumerate(bounding_boxes):
            b_x_start = int(bounding_box[0]) * mag_factor
            b_y_start = int(bounding_box[1]) * mag_factor
            b_x_end = (int(bounding_box[0]) + int(bounding_box[2])) * mag_factor
            b_y_end = (int(bounding_box[1]) + int(bounding_box[3])) * mag_factor
            X = np.random.random_integers(b_x_start, high=b_x_end, size=500)
            Y = np.random.random_integers(b_y_start, high=b_y_end, size=500)
            # X = np.arange(b_x_start, b_x_end-256, 5)
            # Y = np.arange(b_y_start, b_y_end-256, 5)

            for x, y in zip(X, Y):
                patch = self.wsi_image.read_region((x, y), 0, (PATCH_SIZE, PATCH_SIZE))
                mask = self.mask_image.read_region((x, y), 0, (PATCH_SIZE, PATCH_SIZE))
                mask_gt = np.array(mask)
                # mask_gt = cv2.cvtColor(mask_gt, cv2.COLOR_BGR2GRAY)
                mask_gt = cv2.cvtColor(mask_gt, cv2.COLOR_BGR2GRAY)
                patch_array = np.array(patch)

                white_pixel_cnt_gt = cv2.countNonZero(mask_gt)

                if white_pixel_cnt_gt == 0:  # mask_gt does not contain tumor area
                    patch_hsv = cv2.cvtColor(patch_array, cv2.COLOR_BGR2HSV)
                    lower_red = np.array([20, 20, 20])
                    upper_red = np.array([200, 200, 200])
                    mask_patch = cv2.inRange(patch_hsv, lower_red, upper_red)
                    white_pixel_cnt = cv2.countNonZero(mask_patch)

                    if white_pixel_cnt > ((PATCH_SIZE * PATCH_SIZE) * 0.50):
                        # mask = Image.fromarray(mask)
                        patch.save(PROCESSED_PATCHES_TUMOR_NEGATIVE_PATH + PATCH_NORMAL_PREFIX +
                                   str(self.negative_patch_index), 'PNG')
                        # mask.save(PROCESSED_PATCHES_NORMAL_PATH + PATCH_NORMAL_PREFIX + str(self.patch_index),
                        #           'PNG')
                        self.negative_patch_index += 1
                else:  # mask_gt contains tumor area
                    if white_pixel_cnt_gt >= ((PATCH_SIZE * PATCH_SIZE) * 0.85):
                        patch.save(PROCESSED_PATCHES_POSITIVE_PATH + PATCH_TUMOR_PREFIX +
                                   str(self.positive_patch_index), 'PNG')
                        self.positive_patch_index += 1

                patch.close()
                mask.close()

    def read_wsi_mask(self, wsi_path, mask_path):
        try:
            self.cur_wsi_path = wsi_path
            self.wsi_image = OpenSlide(wsi_path)
            self.mask_image = OpenSlide(mask_path)

            self.level_used = min(self.def_level, self.wsi_image.level_count - 1, self.mask_image.level_count - 1)

            self.mask_pil = self.mask_image.read_region((0, 0), self.level_used,
                                                            self.mask_image.level_dimensions[self.level_used])
            self.mask = np.array(self.mask_pil)

        except OpenSlideUnsupportedFormatError:
            print('Exception: OpenSlideUnsupportedFormatError')
            return False

        return True

    def read_wsi_normal(self, wsi_path):
        """
            # =====================================================================================
            # read WSI image and resize
            # Due to memory constraint, we use down sampled (4th level, 1/32 resolution) image
            # ======================================================================================
        """
        try:
            self.cur_wsi_path = wsi_path
            self.wsi_image = OpenSlide(wsi_path)
            self.level_used = min(self.def_level, self.wsi_image.level_count - 1)

            self.rgb_image_pil = self.wsi_image.read_region((0, 0), self.level_used,
                                                            self.wsi_image.level_dimensions[self.level_used])
            self.rgb_image = np.array(self.rgb_image_pil)

        except OpenSlideUnsupportedFormatError:
            print('Exception: OpenSlideUnsupportedFormatError')
            return False

        return True

    def read_wsi_tumor(self, wsi_path, mask_path):
        """
            # =====================================================================================
            # read WSI image and resize
            # Due to memory constraint, we use down sampled (4th level, 1/32 resolution) image
            # ======================================================================================
        """
        try:
            self.cur_wsi_path = wsi_path
            self.wsi_image = OpenSlide(wsi_path)
            self.mask_image = OpenSlide(mask_path)

            self.level_used = min(self.def_level, self.wsi_image.level_count - 1, self.mask_image.level_count - 1)

            self.rgb_image_pil = self.wsi_image.read_region((0, 0), self.level_used,
                                                            self.wsi_image.level_dimensions[self.level_used])
            self.rgb_image = np.array(self.rgb_image_pil)

        except OpenSlideUnsupportedFormatError:
            print('Exception: OpenSlideUnsupportedFormatError')
            return False

        return True

    def find_roi_n_extract_patches_mask(self):
        mask = cv2.cvtColor(self.mask, cv2.COLOR_BGR2GRAY)
        contour_mask, bounding_boxes = self.get_image_contours_mask(np.array(mask), np.array(self.mask))

        # contour_mask = cv2.resize(contour_mask, (0, 0), fx=0.40, fy=0.40)
        # cv2.imshow('contour_mask', np.array(contour_mask))
        self.mask_pil.close()
        self.extract_patches_mask(bounding_boxes)
        self.wsi_image.close()
        self.mask_image.close()

    def find_roi_n_extract_patches_normal(self):
        hsv = cv2.cvtColor(self.rgb_image, cv2.COLOR_BGR2HSV)
        # [20, 20, 20]
        lower_red = np.array([20, 50, 20])
        # [255, 255, 255]
        upper_red = np.array([200, 150, 200])
        mask = cv2.inRange(hsv, lower_red, upper_red)

        # (50, 50)
        close_kernel = np.ones((25, 25), dtype=np.uint8)
        image_close = Image.fromarray(cv2.morphologyEx(np.array(mask), cv2.MORPH_CLOSE, close_kernel))
        # (30, 30)
        open_kernel = np.ones((30, 30), dtype=np.uint8)
        image_open = Image.fromarray(cv2.morphologyEx(np.array(image_close), cv2.MORPH_OPEN, open_kernel))
        contour_rgb, bounding_boxes = self.get_image_contours_normal(np.array(image_open), self.rgb_image)

        # contour_rgb = cv2.resize(contour_rgb, (0, 0), fx=0.40, fy=0.40)
        # cv2.imshow('contour_rgb', np.array(contour_rgb))
        self.rgb_image_pil.close()
        self.extract_patches_normal(bounding_boxes)
        self.wsi_image.close()

    def find_roi_n_extract_patches_tumor(self):
        hsv = cv2.cvtColor(self.rgb_image, cv2.COLOR_BGR2HSV)
        lower_red = np.array([20, 20, 20])
        upper_red = np.array([255, 255, 255])
        mask = cv2.inRange(hsv, lower_red, upper_red)

        # (50, 50)
        close_kernel = np.ones((50, 50), dtype=np.uint8)
        image_close = Image.fromarray(cv2.morphologyEx(np.array(mask), cv2.MORPH_CLOSE, close_kernel))
        # (30, 30)
        open_kernel = np.ones((30, 30), dtype=np.uint8)
        image_open = Image.fromarray(cv2.morphologyEx(np.array(image_close), cv2.MORPH_OPEN, open_kernel))
        contour_rgb, bounding_boxes = self.get_image_contours_tumor(np.array(image_open), self.rgb_image)

        # contour_rgb = cv2.resize(contour_rgb, (0, 0), fx=0.40, fy=0.40)
        # cv2.imshow('contour_rgb', np.array(contour_rgb))
        self.rgb_image_pil.close()
        self.extract_patches_tumor(bounding_boxes)
        self.wsi_image.close()
        self.mask_image.close()

    @staticmethod
    def get_image_contours_mask(cont_img, mask_img):
        _, contours, _ = cv2.findContours(cont_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        bounding_boxes = [cv2.boundingRect(c) for c in contours]
        contours_mask_image_array = np.array(mask_img)
        line_color = (255, 0, 0)  # blue color code
        cv2.drawContours(contours_mask_image_array, contours, -1, line_color, 1)
        return contours_mask_image_array, bounding_boxes

    @staticmethod
    def get_image_contours_normal(cont_img, rgb_image):
        _, contours, _ = cv2.findContours(cont_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        bounding_boxes = [cv2.boundingRect(c) for c in contours]
        contours_rgb_image_array = np.array(rgb_image)
        line_color = (255, 0, 0)  # blue color code
        cv2.drawContours(contours_rgb_image_array, contours, -1, line_color, 3)
        return contours_rgb_image_array, bounding_boxes

    @staticmethod
    def get_image_contours_tumor(cont_img, rgb_image):
        _, contours, _ = cv2.findContours(cont_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        bounding_boxes = [cv2.boundingRect(c) for c in contours]
        contours_rgb_image_array = np.array(rgb_image)

        line_color = (255, 0, 0)  # blue color code
        cv2.drawContours(contours_rgb_image_array, contours, -1, line_color, 3)
        # cv2.drawContours(mask_image, contours_mask, -1, line_color, 3)
        return contours_rgb_image_array, bounding_boxes

    def wait(self):
        self.key = cv2.waitKey(0) & 0xFF
        print('key: %d' % self.key)

        if self.key == 27:  # escape
            return False
        elif self.key == 81:  # <- (prev)
            self.index -= 1
            if self.index < 0:
                self.index = len(self.wsi_paths) - 1
        elif self.key == 83:  # -> (next)
            self.index += 1
            if self.index >= len(self.wsi_paths):
                self.index = 0

        return True
class QtCustomWindow( qt.QWidget ):
    def __init__( self, parent = None ) :
        qt.QWidget.__init__( self, parent )
        self.current_x=0
        self.current_y=0
        #read region always works in the level 0 reference for reading locations
        self.current_zoom=0
        self.image_width=750
        self.image_height=750
        self.setWindowTitle('Large scale image viewing module')
        self.resize(self.image_width,self.image_height)
        self.hbox = qt.QHBoxLayout(self)
        self.lbl = qt.QLabel(self)
        sp=qt.QSizePolicy() # Size policy setting
        sp.setHorizontalPolicy(qt.QSizePolicy.Ignored)
        sp.setVerticalPolicy(qt.QSizePolicy.Ignored)
        self.lbl.setSizePolicy(sp)
        self.setLayout(self.hbox)
        self.filename=None
      
        #
        #self.mouseInitialPosition
        self.panningLock=False
        self.zoomingLock=False
        self.resizeLock=True
        
        self.initUI()
        
        
    def initUI(self):      
        # initialize the widget, make the openslide object pointing to the
        # multilevel image and initialize the view to the top left corner

        if self.filename is not None:
            # openSlide object
            self.osr = OS(self.filename)
            self.level_count = self.osr.level_count
            self.current_x=0
            self.current_y=0
            self.current_zoom=self.level_count-1
            self.level_dimensions=self.osr.level_dimensions
            self.step =int(64*self.osr.level_downsamples[self.current_zoom])
            self.hbox.addWidget(self.lbl)
            self.updatePixmap()
            self.show()
            self.resizeLock=False
        
        
    def updatePixmap(self):
        self.panningLock=True
        
        im=self.osr.read_region((self.current_x,self.current_y),self.current_zoom,(self.image_width,self.image_height))
        
        data = im.tostring('raw', 'RGBA')
        image = qt.QImage(data, im.size[0], im.size[1], qt.QImage.Format_ARGB32)
        pix = qt.QPixmap.fromImage(image)
        self.lbl.setPixmap(pix)
        self.lbl.show()
        
        self.panningLock=False      
    def keyPressEvent( self, event ) :
        key = event.text()
        if key=="s":
            
            self.current_y += self.step 
            self.current_y = min(self.current_y,int(
                self.level_dimensions[0][1]-self.image_height*self.osr.level_downsamples[self.current_zoom]))
        elif key=="w":
            #larger steps for zoomed out images
            self.current_y -= self.step
            self.current_y = max(0, self.current_y)
        elif key=="a":
            #larger steps for zoomed out images
            self.current_x -= self.step
            self.current_x = max(0, self.current_x)
        elif key=="d":
            #larger steps for zoomed out images
            self.current_x += self.step
            self.current_x = min(self.current_x,int(
                self.level_dimensions[0][0]-self.image_width*self.osr.level_downsamples[self.current_zoom]))
        elif key=="q":
            new_zoom = min(self.current_zoom+1,self.level_count-1)
            self.updateCorner(new_zoom)           
            
        elif key=="e":
            new_zoom = max(self.current_zoom-1,0)
            self.updateCorner(new_zoom)

#         print "x: %s" % self.current_x
#         print "y: %s" % self.current_y
#         print "zoom: %s" % self.current_zoom
#         print "downsample: %s" % self.osr.level_downsamples[self.current_zoom]
        self.updatePixmap()
    def updateCorner(self,new_zoom, new_center=None):
        #updates the current_x and current_y values to preserve the desired image center
        
        if new_center:
            center_x=new_center[0]
            center_y=new_center[1]            
        else:
            center_x=self.image_width /2
            center_y=self.image_height /2
        
        
        #while zooming
        self.current_x=int(self.current_x + center_x *self.osr.level_downsamples[self.current_zoom]- self.image_width /2  * self.osr.level_downsamples[new_zoom])
        self.current_y=int(self.current_y + center_y *self.osr.level_downsamples[self.current_zoom]- self.image_height /2 * self.osr.level_downsamples[new_zoom])
        #update step size and current zoom
        self.current_zoom=new_zoom
        
        #larger steps for zoomed out images
        self.step =int(64*self.osr.level_downsamples[self.current_zoom])

################################################################################
################################################################################
    def mousePressEvent(self, QMouseEvent):
        #cursor =qt.QCursor()
        position = QMouseEvent.pos()
        xpos = QMouseEvent.x()
        ypos = QMouseEvent.y()

        self.mouseInitialPosition=np.array([QMouseEvent.x(), QMouseEvent.y()])


       
    def mouseMoveEvent(self, QMouseEvent):
        #cursor =qt.QCursor()
        
        if self.panningLock:
            return
        
        
        currentPosition=np.array([QMouseEvent.x(), QMouseEvent.y()])
        difference=self.mouseInitialPosition-currentPosition
        self.mouseInitialPosition=currentPosition 
          
          
        self.current_x= self.current_x + int(difference[0]*self.osr.level_downsamples[self.current_zoom])
        self.current_x = max(0, self.current_x)
        self.current_x = min(self.current_x,int(
            self.level_dimensions[0][0]-self.image_width*self.osr.level_downsamples[self.current_zoom]))
        
        self.current_y= self.current_y + int(difference[1]*self.osr.level_downsamples[self.current_zoom])
        self.current_y = max(0, self.current_y) 
        self.current_y = min(self.current_y,int(
            self.level_dimensions[0][1]-self.image_height*self.osr.level_downsamples[self.current_zoom]))
            
        self.updatePixmap()
        
    def wheelEvent(self,QMouseEvent):      
        new_zoom = min(max(self.current_zoom- QMouseEvent.delta()/120,0), self.level_count-1)
        
        if new_zoom != self.current_zoom:
            new_center=[0,0]
            new_center[0]= int(QMouseEvent.x())
            new_center[1]= int(QMouseEvent.y())

            
            self.updateCorner(new_zoom, new_center)
            self.updatePixmap()

    def resizeEvent(self,event):
         
        if self.resizeLock:
            return
         
        self.resizeLock=True
        
        difw=event.size().width()-event.oldSize().width()
        difh = event.size().height()-event.oldSize().height()
          
        self.image_width+=difw
        self.image_height+=difh
        self.updatePixmap()
        self.resizeLock=False