def __init__(self, stitcher_controller):

        self.algorithm_scheduler = algorithm_scheduler.AlgorithmScheduler()

        self.running_algorithms = set()

        self.algo_lock = threading.RLock()

        self.extract_output_list = vs.ExtractOutputPtrVector()
        self.extract_output_managed = []
        for i in range(stitcher_controller.getPano().numInputs()):
            input = stitcher_controller.getPano().getInput(i)
            if not input.getIsVideoEnabled():
                continue
            surf = vs.OffscreenAllocator_createSourceSurface(
                input.width, input.height, "Algorithm")
            if not surf.ok():
                raise errors.AlgorithmError(
                    'Cannot run algorithm:' +
                    str(surf.status().getErrorMessage()))
            dontmemleak = vs.sourceSurfaceSharedPtr(surf.release())
            # SWIG create a proxy object with an empty deleter
            # when passing directly the pointer to the vector object :(
            # DON'T TRY TO FACTORIZE THE PREVIOUS LINE OR MEMLEAK
            extract_output = stitcher_controller.createBlockingExtractOutput(
                i, dontmemleak, None, None)
            if not extract_output.status().ok():
                raise errors.AlgorithmError("Cannot create AsyncExtractOutput")

            # To preserve ownership over outputs
            self.extract_output_managed.append(extract_output)
            self.extract_output_list.push_back(extract_output.object())

        self._connect_signals()
Beispiel #2
0
 def stretch_so_it_looks_like(self, other):
   if self.facing in [DIR_UP, DIR_DOWN]:
     u = self.x_to_range().union_if_match(other.x_to_range())
     if not u:
       raise errors.AlgorithmError('This shouldn\'t be possible')
     return Edge(self.facing, self.y0, u.p0, self.y0, u.p1)
   else:
     u = self.y_to_range().union_if_match(other.y_to_range())
     if not u:
       raise errors.AlgorithmError('This shouldn\'t be possible')
     return Edge(self.facing, u.p0, self.x0, u.p1, self.x1)
Beispiel #3
0
 def different_endpoint(self, point):
   if self.facing in [DIR_UP, DIR_DOWN]:
     assert self.y0 == self.y1 == point.y
     if self.x0 == point.x:
       return Point(self.y0, self.x1)
     elif self.x1 == point.x:
       return Point(self.y0, self.x0)
     else:
       raise errors.AlgorithmError('Not one of my endpoints')
   else:
     assert self.x0 == self.x1 == point.x
     if self.y0 == point.y:
       return Point(self.y1, self.x0)
     elif self.y1 == point.y:
       return Point(self.y0, self.x0)
     else:
       raise errors.AlgorithmError('Not one of my endpoints')
Beispiel #4
0
 def get_move(self, dir, y, x):
     m = self.turn_left(dir, y, x)
     if m:
         return m[0], m[1], m[2]
     m = self.go_forward(dir, y, x)
     if m:
         return m[0], m[1], m[2]
     m = self.turn_right(dir, y, x)
     if m:
         return m[0], m[1], m[2]
     raise errors.AlgorithmError('Stuck, cannot move at %sy, %sx' % (y, x))
Beispiel #5
0
 def distance_from(self, other):
   if isinstance(other, Edge):
     if self.facing in [other.facing, opposite_dir(other.facing)]:
       other = other.get_endpoints()[0]
     else:
       raise errors.AlgorithmError('Cannot get distance from misaligned edges')
   if self.facing == DIR_UP:
     return self.y0 - other.y
   elif self.facing == DIR_RIGHT:
     return other.x - self.x0
   elif self.facing == DIR_DOWN:
     return other.y - self.y0
   elif self.facing == DIR_LEFT:
     return self.x0 - other.x
 def side_between(self, first, second, rotate_clockwise):
   if first.facing != opposite_dir(second.facing):
     raise errors.AlgorithmError('Side direction mismatch!')
   if rotate_clockwise:
     dir = rotate_dir_cw(first.facing)
   else:
     dir = rotate_dir_counter_cw(first.facing)
   if first.facing in DIR_UP:
     #    +---+
     # cc |   | rc
     #    |   |
     #    |   |
     y0, y1 = first.y0, second.y0
     if rotate_clockwise:
       # right-hand side from the top and bottom
       x0 = x1 = first.x1
     else:
       # left-hand side from the top and bottom
       x0 = x1 = first.x0
   elif first.facing == DIR_RIGHT:
     x0, x1 = second.x0, first.x0
     if rotate_clockwise:
       # bottom side from the right and left
       y0 = y1 = first.y1
     else:
       # top side from the right and left
       y0 = y1 = first.y0
   elif first.facing == DIR_DOWN:
     #    |   |
     #    |   |
     # rc |   | cc
     #    +---+
     y0, y1 = second.y0, first.y0
     if rotate_clockwise:
       # left-hand side from the bottom and top
       x0 = x1 = first.x0
     else:
       # right-hand side from the bottom and top
       x0 = x1 = first.x1
   elif first.facing == DIR_LEFT:
     x0, x1 = first.x0, second.x0
     if rotate_clockwise:
       # bottom side from the right and left
       y0 = y1 = first.y0
     else:
       # top side from the right and left
       y0 = y1 = first.y1
   return geometry.Edge(dir, y0, x0, y1, x1)
Beispiel #7
0
    def get_algo_output(self, panorama):
        # Todo: investigate OnlineAlgorithm opaque pointer (shared calibration context? / last parameter)

        # Clone a panorama and acquire ownership.
        self.panorama = panorama.clone()
        self.panorama.thisown = 1

        self._update_config(panorama)

        self.online_algorithm = vs.OnlineAlgorithm_create(self.config_name, self.config.to_config())

        if not self.online_algorithm.status().ok():
            CLIENT_MESSENGER.send_error(
                errors.AlgorithmError("Online algorithm \"{}\" creation failed".format(self.config_name)))
            return None

        self.listener_wrapper = vs.AlgorithmListenerGIL(self.this)
        self.algorithm_output = vs.AlgorithmOutput(self.online_algorithm.release(), panorama,
                                                   vs.toListener(self.listener_wrapper.this), None)

        return self.algorithm_output
Beispiel #8
0
 def add(self, dir, point_y, point_x, next_dir):
     self.count += 1
     if self.count >= 128:
         raise errors.AlgorithmError('loop detected at y=%s, x=%s' %
                                     (point_y, point_x))
     # Adjust
     if dir == DIR_DOWN:
         point_x += 1
     if dir == DIR_LEFT:
         point_y += 1
     if next_dir == DIR_DOWN:
         point_x += 1
     elif next_dir == DIR_LEFT:
         point_y += 1
     # Edge
     edge = geometry.Edge(rotate_dir_cw(dir), self.curr_y, self.curr_x,
                          point_y, point_x)
     self.edges.append(edge)
     # Vertex
     kind = 'convex' if next_dir == rotate_dir_cw(dir) else 'reflex'
     self.vertices.append(
         geometry.Vertex(kind, point_y, point_x, len(self.vertices)))
     # Border
     if point_y < self.min_y:
         self.min_y = point_y
     if point_y > self.max_y:
         self.max_y = point_y
     if point_x < self.min_x:
         self.min_x = point_x
     if point_x > self.max_x:
         self.max_x = point_x
     # Done?
     self.curr_y = point_y
     self.curr_x = point_x
     if point_y == self.start_y and point_x == self.start_x:
         first = self.vertices[-1]
         self.vertices = [first] + self.vertices[:-1]
         return True
Beispiel #9
0
 def common_endpoint(self, other):
   ys = set([self.y0, self.y1]).intersection([other.y0, other.y1])
   xs = set([self.x0, self.x1]).intersection([other.x0, other.x1])
   if len(ys) == 1 and len(xs) == 1:
     return Point(list(ys)[0], list(xs)[0])
   raise errors.AlgorithmError('No common endpoint found')