コード例 #1
0
def _launch_quilt(debug, final_path, src, **kwargs):
    """
    Launches quilt process with the parsed arguments.
    """

    multi_proc = kwargs.pop('multiprocess')

    # ------------- quilt --------------

    qs = time.time()
    log.info('Quilt started at {0}'.format(time.strftime("%H:%M:%S")))

    try:
        # compute quilting
        Quilt.debug = debug
        q = Quilt(src, **kwargs)
        if multi_proc:
            q.optimized_compute()
        else:
            q.compute()

        # get the result
        result = q.get_result()
        if debug:
            show(result)
        save(result, final_path)

    except ValueError as err:
        log.error(err.message)
        return

    t = (time.time() - qs) / 60
    log.debug('Quilt took {0:0.6f} minutes'.format(t))
    log.info('End {0}'.format(time.strftime("%H:%M:%S")))
コード例 #2
0
 def test_save_single_matrix(self, mk_save):
     """
     Test save calls the save() method of each input images with the realtive
     paths.
     """
     a = gray2rgb(np.array([[0, 0.5, 0.8], [1, 0.3, 0.7]]))
     path = 'custom/path/a.jpg'
     save(a, path)
     mk_save.assert_called_once_with(path)
コード例 #3
0
    def test_save_single_img(self):
        """
        Test save calls the save() method of the input image once and with the
        given path.
        """
        a = matrix2img(gray2rgb(np.array([[0, 0.5, 0.8], [1, 0.3, 0.7]])))
        path = 'custom/path'

        with mock.patch.object(a, 'save') as mk_save:
            save(a, path)
            mk_save.assert_called_once_with(path)
コード例 #4
0
    def compute(self):
        """
        Single, traditional, single process computation.
        """
        self.log.info('\nCOMPUTING ...')

        for n in xrange(self.niter):
            for i in xrange(self.num_tiles[0]):

                startI = i * self.tilesize - i * self.overlap
                endI = min(self.Y[0].shape[0], startI + self.tilesize)
                sizeI = endI - startI
                if sizeI <= self.overlap:
                    continue

                for j in xrange(self.num_tiles[1]):

                    startJ = j * self.tilesize - j * self.overlap
                    endJ = min(self.Y[0].shape[1], startJ + self.tilesize)
                    sizeJ = endJ - startJ
                    if sizeJ <= self.overlap:
                        continue

                    # skip if this patch is not meant to be filled
                    if self.Ymask and not np.any(self.Ymask[startI:endI,
                                                            startJ:endJ]):
                        continue

                    # Dist from each tile to the overlap region
                    y_patches = [
                        y[startI:endI, startJ:endJ, :] for y in self.Y
                    ]
                    res_patches = self._compute_patch(
                        y_patches, [sizeI, sizeJ], (i, j),
                        mask=self.Xmask,
                        constraint_start=self.constraint_start)
                    for idx, res in enumerate(res_patches):
                        self.Y[idx][startI:endI, startJ:endJ, :] = res

            self.log.debug('iter {0} / {1}'.format(n, self.niter))
            show(self.Y[0]) if self.debug else None
            if self.result_path:
                save(self.Y[0], self.result_path)
コード例 #5
0
    def test_save_list_img(self):
        """
        Test save calls the save() method of each input images with the realtive
        paths.
        """
        a = matrix2img(gray2rgb(np.array([[0, 0.5, 0.8], [1, 0.3, 0.7]])))
        b = matrix2img(np.array([[0, 0.5, 0.8], [1, 0.3, 0.7], [1, 0.3, 0.7]]))
        c = matrix2img(gray2rgb(np.array([[0.5, 0.8], [0.3, 0.7], [0.3,
                                                                   0.7]])))
        a_path = 'custom/path/a.jpg'
        b_path = 'custom/path/b.jpg'
        c_path = 'custom/path/c.jpg'

        with mock.patch.object(a, 'save') as mka:
            with mock.patch.object(b, 'save') as mkb:
                with mock.patch.object(c, 'save') as mkc:
                    save([a, b, c], [a_path, b_path, c_path])
                    mka.assert_called_once_with(a_path)
                    mkb.assert_called_once_with(b_path)
                    mkc.assert_called_once_with(c_path)
コード例 #6
0
    def optimized_compute(self):
        """
        First process: it computes the quilt algorithm with big tiles,
        manages child processes and them combines the results.

         1) creates the child processes (number defined according to the
            available cores and the number of big tiles in the image)
         2) computes quilting with big tiles
         3) every time a tile is computed (and sewed with the image), it is put
            in a queue
        process 1: big tiles
         for each of the tile: process n

        """

        self.log.info('\nMULTIPROCESSING COMPUTING ...')

        big_num_tiles = self.calc_num_tiles(tile_size=self.big_tilesize,
                                            overlap=self.big_overlap)

        # prepare the pool
        n_proc = min(big_num_tiles[0] * big_num_tiles[1], self.cores)
        out_queue = Queue()
        in_queue = JoinableQueue()
        pool = Pool(n_proc, unwrap_self, (
            self,
            in_queue,
            out_queue,
        ))
        self.log.info('preparing {0} processes - {1}'.format(
            n_proc, time.strftime("%H:%M:%S")))

        if self.Ymask is not None:
            # zero values will become inf
            Ymask_rgb = gray2rgb(self.Ymask)
            # use the mask as a draft of the dst img so that boundaries are
            # respected
            self.Y[0] = deepcopy(Ymask_rgb)

        for i in xrange(big_num_tiles[0]):

            startI = i * self.big_tilesize - i * self.big_overlap
            endI = min(self.Y[0].shape[0], startI + self.big_tilesize)
            sizeI = endI - startI
            if sizeI <= self.overlap:
                continue

            for j in xrange(big_num_tiles[1]):

                startJ = j * self.big_tilesize - j * self.big_overlap
                endJ = min(self.Y[0].shape[1], startJ + self.big_tilesize)
                sizeJ = endJ - startJ
                if sizeJ <= self.overlap:
                    continue

                dst_patches = [y[startI:endI, startJ:endJ, :] for y in self.Y]
                # for the big tiles don't consider the mask, since it would
                # remove most of the image because the tiles are so big
                res_patches = self._compute_patch(
                    dst_patches, [sizeI, sizeJ], (i, j),
                    mask=self.Xmask_big,
                    constraint_start=self.constraint_start,
                    err=0.8)

                # add the mask on top
                if self.Ymask is not None:
                    res_patches = [
                        r * Ymask_rgb[startI:endI, startJ:endJ]
                        for r in res_patches
                    ]
                for idx, res in enumerate(res_patches):
                    self.Y[idx][startI:endI, startJ:endJ, :] = res

                # make a process start in this big tile
                _img = [y[startI:endI, startJ:endJ, :] for y in self.Y]
                _mask = self.Ymask[startI:endI, startJ:endJ] \
                    if self.Ymask is not None else None
                _id = (startI, startJ)
                in_queue.put({'dst': _img, 'mask': _mask, 'id': _id})

        # wait for all the children
        self.log.debug('master finished {0}'.format(time.strftime("%H:%M:%S")))
        show(self.Y[0]) if self.debug else None
        pool.close()
        self.log.debug('closed, in queue: {0} out: {1}'.format(
            in_queue.qsize(), out_queue.qsize()))
        in_queue.join()
        self.log.debug('all children finished {0}'.format(
            time.strftime("%H:%M:%S")))

        # get the results
        results = sorted([
            out_queue.get()
            for _ in xrange(big_num_tiles[0] * big_num_tiles[1])
        ])

        # sew them together
        for idx, res in results:

            # calculate the mask
            base_patch = self.Y[0][idx[0]:idx[0] + self.big_tilesize,
                                   idx[1]:idx[1] + self.big_tilesize]
            new_patch = res[0]
            mask_patch = self.calc_patch_mask(base_patch,
                                              new_patch,
                                              coord=idx,
                                              overlap=self.big_overlap)
            # apply the mask to each layer
            for i, y in enumerate(self.Y):
                base_patch = y[idx[0]:idx[0] + self.big_tilesize,
                               idx[1]:idx[1] + self.big_tilesize]
                new_patch = res[i]
                self.Y[i][idx[0]:idx[0]+self.big_tilesize,
                          idx[1]:idx[1]+self.big_tilesize, :] = \
                    filter_img(new_patch, base_patch, mask_patch)

        # apply the mask again
        if self.Ymask is not None:
            self.Y = [r * Ymask_rgb for r in self.Y]

        show(self.Y[0]) if self.debug else None
        if self.result_path:
            save(self.Y[0], self.result_path)
            self.log.info('saving' + self.result_path)