Advertisement
sergeypo

Particle Filter Algorithm in Stereo Vision

Sep 28th, 2012
1,222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.32 KB | None | 0 0
  1. import pygame
  2. import pygame.locals
  3. import pygame.image
  4. import pygame.surfarray
  5. import random
  6. import math
  7. import sys, os
  8. import time
  9. import numpy
  10.  
  11. GRAY = pygame.Color(90, 90, 90)
  12. RED = pygame.Color(255, 0, 0)
  13. WHITE = pygame.Color(255, 255, 255, 255)
  14. GREEN = pygame.Color(0, 255, 0)
  15. BLUE = pygame.Color(0, 0, 255)
  16. YELLOW = pygame.Color(255, 255, 0)
  17.  
  18. W = 100
  19. H = 100
  20. SAMPLESIZE = 10
  21. SIGMA = W/6.
  22. N_PARTICLES = 2000
  23.  
  24. def svertka(matrix_a, matrix_b):
  25.     squares = numpy.square(matrix_a - matrix_b)
  26.     return numpy.sum(squares)
  27.  
  28. class Bitmap():
  29.  
  30.     def display(self):
  31.         screen = pygame.display.get_surface()
  32.         screen.blit(self.surface, self.position)
  33.  
  34. class ImageHalf(Bitmap):
  35.     def __init__(self, surface, x, y):
  36.         self.surface = surface
  37.         self.position = [x, y]
  38.        
  39. class FromSurface(Bitmap):
  40.     def __init__(self, source):
  41.         self.array3d = pygame.surfarray.array3d(source.surface)
  42.         self.position = [0, 0]
  43.        
  44.     def to_grayscale(self):
  45.         array3d = numpy.zeros(self.array3d.shape)
  46.         array3d[:, :, 0] = self.array3d[:, :, 0] * 0.21 + self.array3d[:, :, 1] * 0.71 + self.array3d[:, :, 2] * 0.07      
  47.         array3d[:, :, 1] = array3d[:, :, 0]
  48.         array3d[:, :, 2] = array3d[:, :, 0]
  49.         self.array3d = array3d
  50.         self.surface = pygame.surfarray.make_surface(self.array3d)
  51.        
  52.     def get_probe_area(self, x, y):
  53.         return SquareArea(x, y, GREEN, SAMPLESIZE, self.array3d)
  54.        
  55.     def test_area(self, x, y, probe_square):
  56.         x1 = min(W - SAMPLESIZE, max(0, random.gauss(x, SIGMA)))
  57.         y1 = min(H - SAMPLESIZE, max(0, random.gauss(y, SIGMA)))
  58.         lookup_square = SquareArea(x1, y1, RED, SAMPLESIZE, self.array3d)
  59.         lookup_square.position[0] = lookup_square.start_index[0] + W
  60.         matrix_a = probe_square.array3d
  61.         matrix_b = lookup_square.array3d
  62.         error = svertka(matrix_a, matrix_b)
  63.         return lookup_square, error
  64.    
  65. class SquareArea():
  66.     def __init__(self, x, y, color, size, array3d):
  67.         self.position = [x, y]
  68.         self.start_index = [x, y]
  69.         self.color = color
  70.         self.size = size
  71.         self.array3d = array3d[x:x+size, y:y+size, 0]
  72.        
  73.     def display(self, shift = (0, 0), kolor = None):
  74.         screen = pygame.display.get_surface()
  75.         if kolor is None:
  76.             clr = self.color
  77.         else:
  78.             clr = kolor
  79.         pygame.draw.rect(screen, clr,
  80.                             (self.position[0] + shift[0],
  81.                             self.position[1] + shift[1],
  82.                             self.size,
  83.                             self.size),
  84.                         1)
  85.  
  86. def resample(particles):
  87.     #first most important Particle Filter Algorithm part
  88.     #resample particles with substitute, particles with most weight
  89.     #are more likely to be resampled
  90.     #code taken from Sebastian Thrun's course 'Programming a Robotic Car'
  91.     resampled_particles = []
  92.     N = len(particles)
  93.     index = int(random.random() * N)
  94.     beta = 0.0
  95.     mw = max((p[1] for p in particles))
  96.     for i in range(N):
  97.         beta += random.random() * 2.0 * mw
  98.         while beta > particles[index][1]:
  99.             beta -= particles[index][1]
  100.             index = (index + 1) % N
  101.         resampled_particles.append(particles[index])
  102.     return resampled_particles
  103.  
  104. def move(particles, dx, dy, probe_square, rite_panel):
  105.     #second most important Particle Filter Algorithm part
  106.     #move particles randomly by approx. (dx, dy)
  107.     #and calculate importance weight of moved particles
  108.     p2 = []
  109.     for particle in particles:
  110.         x1 = int(round(particle[0].start_index[0] + random.gauss(dx, dx/10.)))
  111.         y1 = int(round(particle[0].start_index[1] + random.gauss(dy, dy/10.)))
  112.         x1 = min(W - SAMPLESIZE, max(0, x1))
  113.         y1 = min(H - SAMPLESIZE, max(0, y1))
  114.         lookup_square = SquareArea(x1, y1, RED, SAMPLESIZE, rite_panel.array3d)
  115.         lookup_square.position[0] = lookup_square.start_index[0] + W
  116.         matrix_a = probe_square.array3d
  117.         matrix_b = lookup_square.array3d
  118.         try:
  119.             error = svertka(matrix_a, matrix_b)
  120.             p2.append((lookup_square, 1. / error))
  121.         except:
  122.             p2.append((lookup_square, 0.))
  123.     return p2
  124.  
  125. class Plan():
  126.     def __init__(self):
  127.         self.points = []
  128.         self.kolor = WHITE
  129.         self.zoom = 10.
  130.        
  131.     def display(self):
  132.         screen = pygame.display.get_surface()
  133.         pygame.draw.rect(screen, pygame.Color(0, 0, 0), (0, H, W, H), 0)
  134.         for x, y in self.points:
  135.             try:
  136.                 pygame.draw.circle(screen, self.kolor, (x, 2 * H - self.zoom * y), 1)
  137.             except:
  138.                 pass
  139.                
  140.     def zoom_up(self):
  141.         self.zoom *= 1.2
  142.        
  143.     def zoom_down(self):
  144.         self.zoom /= 1.2
  145.        
  146.     def push(self, point):
  147.         self.points.append(point)
  148.  
  149. def run_game():
  150.     pygame.init()
  151.     random.seed()
  152.     global W, H
  153.     window = pygame.display.set_mode((W, H))
  154.     left_image = pygame.image.load(sys.argv[1]).convert()
  155.     rite_image = pygame.image.load(sys.argv[2]).convert()
  156.     W, H = left_image.get_size()
  157.     window = pygame.display.set_mode((W*2, H*2 + SAMPLESIZE))
  158.     pygame.display.set_caption("Vision")
  159.    
  160.     the_left = ImageHalf(left_image, 0, 0)
  161.     the_rite = ImageHalf(rite_image, W, 0)
  162.     bw_left = FromSurface(the_left)
  163.     bw_left.position = [0, H]
  164.     bw_left.to_grayscale()
  165.     bw_rite = FromSurface(the_rite)
  166.     bw_rite.position = [W, H]
  167.     bw_rite.to_grayscale()
  168.    
  169.     skip_dislay = False
  170.     x = random.randint(0, W - SAMPLESIZE)
  171.     y = random.randint(0, H - SAMPLESIZE)
  172.     x0, y0 = x, y
  173.     squares = []
  174.     plan = Plan()
  175.    
  176.     while 1:
  177.         for event in pygame.event.get():
  178.             if event.type == pygame.QUIT:
  179.                 sys.exit()
  180.             if event.type == pygame.MOUSEBUTTONUP:
  181.                 x0, y0 = x, y
  182.                 x = event.pos[0]
  183.                 y = event.pos[1]
  184.                 if x >= 0 and x <= W and y >= 0 and y <= H:
  185.                     skip_dislay = False
  186.             if event.type == pygame.KEYUP:
  187.                 if event.key == pygame.K_UP:
  188.                     plan.zoom_up()
  189.                 elif event.key == pygame.K_DOWN:
  190.                     plan.zoom_down()
  191.                 skip_dislay = False
  192.                 x, y = x0, y0
  193.         if skip_dislay:
  194.             continue
  195.         skip_dislay = True
  196.         the_left.display()
  197.         the_rite.display()
  198.         bw_rite.display()
  199.         probe_square = bw_left.get_probe_area(x, y)
  200.         probe_square.display()
  201.         if len(squares):
  202.             squares = move(squares, x-x0, y-y0, probe_square, bw_rite)
  203.             squares = resample(squares)
  204.             for square in squares:
  205.                 square[0].display(shift=(0, H))
  206.         else:
  207.             for j in xrange(N_PARTICLES):
  208.                 lookup_square, error = bw_rite.test_area(x, y, probe_square)
  209.                 weight = 1. / error
  210.                 squares.append((lookup_square, weight))
  211.         #the following is not Particle Filtes algorithm, just presentation
  212.         squares.sort(key=lambda o: o[1])
  213.         M = 10
  214.         for square in squares[-M-10:-M]:
  215.             square[0].display(kolor=WHITE)
  216.         for square in squares[-M:]:
  217.             square[0].display()
  218.         #simple calculation of fake distance to object
  219.         x_arr = numpy.array([square[0].position[0] - W for square in squares])
  220.         #average x coordinate of top weighted M squares
  221.         x_average = numpy.average(x_arr[-M:])
  222.         x_std = numpy.std(x_arr[-M:])
  223.         #average x coordinate of all squares
  224.         x_average1 = numpy.average(x_arr)
  225.         x_std1 = numpy.std(x_arr)
  226.         focL = 30.
  227.         base = 1.
  228.         try:
  229.             distance = focL * base / abs(x_average - probe_square.position[0])
  230.             distance1 = focL * base / abs(x_average1 - probe_square.position[0])
  231.             print "d=%f d1=%f std=%f std1=%f" % (distance, distance1, x_std, x_std1)
  232.             if x_std <= x_std1:
  233.                 plan.push((x, distance))
  234.             else:
  235.                 plan.push((x, distance1))
  236.         except:
  237.             pass
  238.         plan.display()
  239.         pygame.display.flip()
  240.  
  241.  
  242.  
  243.  
  244. if __name__ == "__main__":
  245.     run_game()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement