def batch_evaluate_image_quality(path, options):
    """
    Batch calculate quality features for images in a directory
    :param options: options for the quality ranking scripts, as in miplib/ui/image_quality_options.py
    :parame path:   directory that contains the images to be analyzed
    """

    df = pd.DataFrame(columns=["Filename", "tEntropy", "tBrenner", "fMoments", "fMean", "fSTD", "fEntropy",
               "fTh", "fMaxPw", "Skew", "Kurtosis", "MeanBin", "Resolution"])

    for idx, image_name in enumerate(os.listdir(path)):
        if options.file_filter is None or options.file_filter in image_name:
            real_path = os.path.join(path, image_name)
            # Only process images
            if not os.path.isfile(real_path) or not real_path.endswith((".jpg", ".tif", ".tiff", ".tif")):
                continue
            # ImageJ files have particular TIFF tags that can be processed correctly
            # with the options.imagej switch
            image = read.get_image(real_path, channel=options.rgb_channel)

            # Only grayscale images are processed. If the input is an RGB image,
            # a channel can be chosen for processing.
            results = evaluate_image_quality(image, options)
            results.insert(0, real_path)

            # Add resolution value to the end
            results.append(frc.calculate_single_image_frc(image, options).resolution["resolution"])

            df.loc[idx] = results

            print ("Done analyzing {}".format(image_name))

    return df
        
示例#2
0
def generate_frc_based_psf(image, args):
    fwhm = [
        frc.calculate_single_image_frc(image, args).resolution["resolution"],
    ] * 2
    psf_generator = PsfFromFwhm(fwhm)

    if image.ndim == 2:
        return psf_generator.xy()
    else:
        return psf_generator.volume()
示例#3
0
    def __init__(self, image, psf, writer, options):
        """
        :param image:    a MyImage object

        :param options: command line options that control the behavior
                        of the fusion algorithm
        """
        assert isinstance(image, Image)
        assert isinstance(psf, Image)
        if options.save_intermediate_results:
            assert issubclass(writer.__class__, ImageWriterBase)

        self.image = image
        self.psf = psf
        self.options = options
        self.writer = writer

        self.image_size = numpy.array(self.image.shape)
        self.image_spacing = self.image.spacing
        self.psf_spacing = self.psf.spacing
        self.imdims = image.ndim

        self.__get_psfs()

        if options.verbose:
            print("The original image size is %s" % (self.image_size, ))

        self.iteration_count = 0

        # Setup blocks
        self.num_blocks = options.num_blocks
        self.block_size, self.image_size = self.__calculate_block_and_image_size(
        )
        self.memmap_directory = tempfile.mkdtemp()

        # Memmap the estimates to reduce memory requirements. This will slow
        # down the fusion process considerably..
        if self.options.memmap_estimates:
            estimate_new_f = os.path.join(self.memmap_directory,
                                          "estimate_new.dat")
            self.estimate_new = Image(
                numpy.memmap(estimate_new_f,
                             dtype='float32',
                             mode='w+',
                             shape=tuple(self.image_size)), self.image_spacing)

            estimate_f = os.path.join(self.memmap_directory, "estimate.dat")
            self.estimate = Image(
                numpy.memmap(estimate_f,
                             dtype=numpy.float32,
                             mode='w+',
                             shape=tuple(self.image_size)), self.image_spacing)
        else:
            self.estimate = Image(
                numpy.zeros(tuple(self.image_size), dtype=numpy.float32),
                self.image_spacing)
            self.estimate_new = Image(
                numpy.zeros(tuple(self.image_size), dtype=numpy.float32),
                self.image_spacing)

        if not self.options.disable_tau1:
            prev_estimate_f = os.path.join(self.memmap_directory,
                                           "prev_estimate.dat")
            self.prev_estimate = Image(
                numpy.memmap(prev_estimate_f,
                             dtype=numpy.float32,
                             mode='w+',
                             shape=tuple(self.image_size)), self.image_spacing)

        padded_block_size = tuple(i + 2 * self.options.block_pad
                                  for i in self.block_size)
        if options.verbose:
            print("The deconvolution will be run with %i blocks" %
                  self.num_blocks)
            print("The internal block size is %s" % (padded_block_size, ))

        # Create temporary directory and data file.
        self.column_headers = ('t', 'tau1', 'leak', 'e', 's', 'u', 'n', 'uesu')
        self._progress_parameters = numpy.empty(
            (self.options.max_nof_iterations, len(self.column_headers)),
            dtype=numpy.float32)

        # Get initial resolution (in case you are using the FRC based stopping.)
        if self.options.rl_frc_stop > 0:
            self.resolution = frc.calculate_single_image_frc(
                self.image, self.options).resolution["resolution"]

        # Enable automatic background correction with --rl-auto-background
        if self.options.rl_auto_background:
            background_mask = masking.make_local_intensity_based_mask(
                image, threshold=30, kernel_size=60, invert=True)
            masked_image = Image(image * background_mask, image.spacing)
            self.options.rl_background = numpy.mean(
                masked_image[masked_image > 0])
示例#4
0
    def execute(self):
        """
        This is the main fusion function
        """

        save_intermediate_results = self.options.save_intermediate_results

        first_estimate = self.options.first_estimate

        if first_estimate == 'image':
            self.estimate[:] = self.image[:].astype(numpy.float32)
        elif first_estimate == 'blurred':
            self.estimate[:] = uniform_filter(self.image,
                                              3).astype(numpy.float32)
        elif first_estimate == 'image_mean':
            self.estimate[:] = numpy.float32(numpy.mean(self.image[:]))
        elif first_estimate == 'constant':
            self.estimate[:] = numpy.float32(self.options.estimate_constant)
        else:
            raise NotImplementedError(repr(first_estimate))

        self.iteration_count = 0
        max_count = self.options.max_nof_iterations
        initial_photon_count = self.image[:].sum()

        bar = ops_output.ProgressBar(0,
                                     max_count,
                                     totalWidth=40,
                                     show_percentage=False)

        self._progress_parameters = numpy.zeros(
            (self.options.max_nof_iterations, len(self.column_headers)),
            dtype=numpy.float32)

        # duofrc_prev = 0
        # The Fusion calculation starts here
        # ====================================================================
        try:
            while True:

                if (self.options.update_blind_psf > 0
                        and self.iteration_count > 0 and
                    (self.iteration_count + 1) % self.options.update_blind_psf
                        == 0):
                    self.psf = psfgen.generate_frc_based_psf(
                        Image(self.estimate, self.image_spacing), self.options)
                    self.__get_psfs()
                    self.image = self.estimate.copy()

                info_map = {}
                ittime = time.time()

                self.prev_estimate[:] = self.estimate.copy()

                e, s, u, n = self.compute_estimate()

                self.iteration_count += 1
                photon_leak = 1.0 - (e + s + u) / initial_photon_count
                u_esu = u / (e + s + u)

                tau1 = abs(self.estimate - self.prev_estimate).sum() / abs(
                    self.prev_estimate).sum()
                info_map['TAU1=%s'] = tau1

                t = time.time() - ittime
                leak = 100 * photon_leak

                if self.options.verbose:
                    # Update UI
                    info_map['E/S/U/N=%s/%s/%s/%s'] = int(e), int(s), int(
                        u), int(n)
                    info_map['LEAK=%s%%'] = leak
                    info_map['U/ESU=%s'] = u_esu
                    info_map['TIME=%ss'] = t

                    bar.updateComment(' ' + ', '.join([
                        k % (ops_output.tostr(info_map[k]))
                        for k in sorted(info_map)
                    ]))
                    bar(self.iteration_count)
                    print()

                # Save parameters to file
                self._progress_parameters[self.iteration_count -
                                          1] = (t, tau1, leak, e, s, u, n,
                                                u_esu)

                # Save intermediate image
                if save_intermediate_results:
                    # self.temp_data.save_image(
                    #     self.estimate,
                    #     'result_%s.tif' % self.iteration_count
                    # )
                    self.writer.write(Image(self.estimate, self.image_spacing))

                # Check if it's time to stop:
                if int(u) == 0 and int(n) == 0:
                    stop_message = 'The number of non converging photons reached to zero.'
                    break
                elif self.iteration_count >= max_count:
                    stop_message = 'The number of iterations reached to maximal count: %s' % max_count
                    break
                elif not self.options.disable_tau1 and tau1 <= self.options.stop_tau:
                    stop_message = 'Desired tau-threshold achieved'
                    break
                elif self.options.rl_frc_stop > 0:
                    resolution_new = frc.calculate_single_image_frc(
                        Image(self.estimate, self.image_spacing),
                        self.options).resolution["resolution"]
                    frc_diff = numpy.abs(self.resolution - resolution_new)
                    if frc_diff <= self.options.rl_frc_stop:
                        print('Desired FRC diff reached after {} iterations'.
                              format(self.iteration_count))
                        break
                    else:
                        self.resolution = resolution_new

                # elif self.iteration_count >= 4 and abs(frc_diff) <= .0001:
                #     stop_message = 'FRC stop condition reached'
                #     break
                else:
                    continue

        except KeyboardInterrupt:
            stop_message = 'Iteration was interrupted by user.'

        # if self.num_blocks > 1:
        #     self.estimate = self.estimate[0:real_size[0], 0:real_size[1], 0:real_size[2]]
        if self.options.verbose:
            print()
            bar.updateComment(' ' + stop_message)
            bar(self.iteration_count)
            print()
示例#5
0
def main():

    # Get input arguments
    args = options.get_frc_script_options(sys.argv[1:])
    path = args.directory

    # Create output directory
    output_dir = args.directory
    date_now = datetime.datetime.now().strftime("%H-%M-%S")

    filename = "{}_miplib_{}_frc_results.csv".format(date_now, args.frc_mode)
    filename = os.path.join(output_dir, filename)

    # Get image file names, sort in alphabetic order and complete.
    files_list = list(i for i in os.listdir(path)
                      if i.endswith((".jpg", ".tif", ".tiff", ".png")))
    files_list.sort()
    print('Number of images to analyze: {}'.format(len(files_list)))

    #df_main = pandas.DataFrame(0, index=np.arange(len(files_list)), columns=["Image", "Depth", "Kind", "Resolution"])
    df_main = pandas.DataFrame(0,
                               index=np.arange(len(files_list)),
                               columns=["Image", "Resolution"])

    if args.frc_mode == "two-image":

        def pairwise(iterable):
            a = iter(iterable)
            return zip(a, a)

        for idx, im1, im2 in enumerate(pairwise(files_list)):
            # Read images
            image1 = imread.get_image(os.path.join(path, im1))
            image2 = imread.get_image(os.path.join(path, im2))

            result = frc.calculate_two_image_frc(image1, image2, args)
            title = strutils.common_start(im1, im2)

            resolution = result.resolution['resolution']
            df_main.iloc[idx] = title, resolution

    elif args.frc_mode == "one-image":
        for idx, im in enumerate(files_list):
            image = imread.get_image(os.path.join(path, im))

            print("Analyzing image {}".format(im))

            result = frc.calculate_single_image_frc(image, args)

            title = im.split('.')[0]

            # I left these snippets here to show how one can add additional info
            # to the dataframes in particular use cases.

            #depth = title.split('um_')[0].split("_")[-1]

            # kind = None
            # for x in ("apr_ism", "apr_ism_bplus", "closed", "open", "static_ism", "ism_sim"):
            #     if x in title:
            #         kind = x
            # if kind is None:
            #     raise RuntimeError("Unknown image: {}".format(title))
            resolution = result.resolution['resolution']
            #df_main.iloc[idx] = title, depth, kind, resolution
            df_main.iloc[idx] = title, resolution

    else:
        raise NotImplementedError()

    df_main.index = list(range(len(df_main)))
    df_main.to_csv(filename)