text: '''
  Created on Dec 12, 2014
  
  @author: busta
  '''
  
  import numpy as np
  import cv2
  
  import pylab
  import matplotlib
  import matplotlib.pyplot as plt
  from matplotlib.widgets import RectangleSelector
  
  from matplotlib.text import Text
  
  from _collections import defaultdict
  import sys
  import ftext
  import os
  import matplotlib as mpl
  
  added_objects = []
  last_selection = ()
  
  fastOffsetsC = [[0,  4], [ 1,  4], [ 2,  4], [ 3,  3], [ 4, 2], [ 4, 1], [ 4, 0], [ 4, -1], [ 4, -2], [ 3, -3], [ 2, -4], [ 1, -4], [0, -4], [-1, -4], [-2, -4], [-3, -3], [-4, -2], [-4, -1], [-4, 0], [-4,  1], [-4,  2], [-3,  3], [-2,  4], [-1,  4]]
  fastOffsets = [[0,  3], [ 1,  3], [ 2,  2], [ 3,  1], [ 3, 0], [ 3, -1], [ 2, -2], [ 1, -3], [0, -3], [-1, -3], [-2, -2], [-3, -1], [-3, 0], [-3,  1], [-2,  2], [-1,  3]]
  fastCorners = [[ 2,  3], [ 3,  2], [ 3, -2], [ 2, -3], [-3, -2], [-2, -3], [-3,  2], [-2,  3]]
  fastAll = fastOffsets
  fastAll.extend(fastCorners)
  
  drawGrayScale = False
  
  def segment_fasts(img, point, distFunction, ax, threshold):
      
      pointmarkers = np.asarray(fastOffsets)
      pointmarkers[:, 0] += point[0]
      pointmarkers[:, 1] += point[1]
      negative = False
      
      if img[point[1], point[0]] <= img[point[6], point[5]]:
          negative = True
      
      otsu_t = otsu_threshold(img, point, pointmarkers, negative=negative)
      
      
      
  
  def floodFill(img, x, y, distFunction, ax, threshold):
      global added_objects
      for k in range( len(added_objects ) ) :
          plotObject =  added_objects[k]
          if type(plotObject) is matplotlib.collections.PathCollection:
              plotObject.remove()
          elif type(plotObject) is matplotlib.text.Text:
              plotObject.remove()
          else:
              plotObject[0].remove()
      added_objects = []
      
      added_objects = []
      # Starting at x and y, changes any adjacent
      # characters that match oldChar to newChar.
      worldWidth = img.shape[1]
      worldHeight = img.shape[0]
      visited = {}
      seedx = x
      seedy = y
  
      theStack = [ (x, y) ]
      fillx = []
      filly = []
      while len(theStack) > 0:
          x, y = theStack.pop()
          if len(fillx) > 800:
              break
          visited[(x, y)] = 1
  
          if not distFunction(img[y, x], threshold):
              # Base case. If the current x, y character is not the oldChar,
              # then do nothing.
              continue
  
          # Change the character at world[x][y] to newChar
          fillx.append(x)
          filly.append(y)
  
          if x > 0: # left
              if not visited.has_key((x-1, y)):
                  theStack.append( (x-1, y) )
  
          if y > 0: # up
              if not visited.has_key((x, y-1)):
                  theStack.append( (x, y-1) )
  
          if x < worldWidth-1: # right
              if not visited.has_key( (x+1, y) ):
                  theStack.append( (x+1, y) )
  
          if y < worldHeight-1: # down
              if not visited.has_key( (x, y+1) ):
                  theStack.append( (x, y+1) )
      
      added_objects.append(ax.plot(fillx, filly, 'wo')) 
      print('area: {0}'.format(len(fillx)))    
      ax.figure.canvas.draw()
  
  def line_select_callback(eclick, erelease):
      'eclick and erelease are the press and release events'
      x1, y1 = eclick.xdata, eclick.ydata
      x2, y2 = erelease.xdata, erelease.ydata
      print ("(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2))
      for i in range(len(toggle_selector.RS)):
          if toggle_selector.RS[i].to_draw.get_height() > 1:
              
              mask = np.logical_and( np.logical_and( toggle_selector.RS[i].keypoints[:, 0] > x1,  toggle_selector.RS[i].keypoints[:, 0] < x2), np.logical_and(toggle_selector.RS[i].keypoints[:, 1] > y1, toggle_selector.RS[i].keypoints[:, 1] < y2))
              idx = np.nonzero(mask)[0]
              inpoints = toggle_selector.RS[i].keypoints[mask, :]
              for j in range( inpoints.shape[0] ):
                  drawFast(inpoints[j,:], toggle_selector.RS[i].ax, toggle_selector.RS[i].image, toggle_selector.RS[i].threshold, toggle_selector.RS[i].octIdx[0][idx[j]])
              
              #toggle_selector.RS[i].ax.plot(inpoints[:, 5], inpoints[:, 6], 'go')
              #toggle_selector.RS[i].to_draw.set_height(0)
              toggle_selector.RS[i].ax.figure.canvas.draw()
  
  class FastDrawer:
      def __init__(self, ax, img, threshold):
          
          self.ax = ax
          self.img = img
          self.threshold = threshold
          
          self.cid = plt.connect('button_press_event', self)
  
      def __call__(self, event):
          if event.dblclick:
              if event.inaxes!=self.ax: return
              point = [event.xdata, event.ydata]
              drawFast(point, self.ax, self.img, self.threshold, -1)
          elif event.button == 3:
              if event.inaxes!=self.ax: return
              if len(last_selection) > 0:
                  point = last_selection[0]
                  threshold = last_selection[1]
                  distFunction = last_selection[2] 
                  floodFill(self.img, point[0], point[1], distFunction, self.ax, threshold)
                  
              
  
  def toggle_selector(event):
      if event.dblclick:
          #print event
          return 
      
  def cdist(e1, e2):
      ur1 = int(e1[2])
      ur2 = int(e2[2])
      rmean = (  ur1 + ur2 ) / 2
      r = ur1 - ur2
      ug1 = int(e1[1])
      ug2 = int(e2[1])
      g = ug1 - ug2
      ub1 = int(e1[0])
      ub2 = int(e2[0])
      b = ub1 - ub2;
      return (((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8)
  
  def lower_then_b(e1, threshold):
      return e1[2] < threshold
  
  def lower_then(e1, threshold):
      return e1 < threshold
  
  def greater_then(e1, threshold):
      return e1 > threshold
  
  def greater_then_b(e1, threshold):
      return e1[2] > threshold
  
  from skimage.exposure import histogram
  def otsu_threshold(img, point, offsets, negative = False):
      
      hist = defaultdict(int)
      max = 0
      sum = 0
      hist[img[point[1], point[0]]] += 1
      sum += img[point[1], point[0]]
      for  i in range(16):
          hist[img[offsets[i, 1], offsets[i, 0]]] += 1
          sum += img[offsets[i, 1], offsets[i, 0]]
      wB = 0
      threshold1 = 0
      next = -1
      count = 0
      sumB = 0
      for val in sorted(hist.keys()):
          wB += hist[val]
          wF = 17 - wB
          if next == -1:
              next = val
              
          if wF == 0:
              break
          sumB += val * hist[val]
          mB = sumB / float(wB)
          mF = (sum - sumB) / float(wF)
          between = wB * wF * pow(mB - mF, 2)
          
      
          
          if between >= max:
              threshold1 = val
              max = between
              count = wB
              next = -1
          
      
      if negative:
          return (2 * next + threshold1) / 3
      
      return (2 * threshold1 + next) / 3
  
  fastOffsets12 = [[0,  2], [ 1,  2], [ 2,  1], [ 2, 0], [ 2, -1], [ 1, -2], [0, -2], [-1, -2], [-2, -1], [-2, 0], [-2,  1], [-1,  2]]
  fastCorners12 = [[ 2, 2], [2, -2], [-2,  -2], [-2,  2]]
  fastOffsets8 = [[0,  1], [ 1,  1], [1, 0], [ 1, -1], [0, -1], [-1, -1], [-1, 0], [-1,  1]]
  showFast8 = True
  showFast16 = False
  s = 50
  
  from matplotlib.patches import Wedge
  
  def drawFast(point, ax, img, threshold, idx):
      #s = 2000
      point[0] = int(round(point[0]))
      point[1] = int(round(point[1]))
      global added_objects
      for k in range( len(added_objects ) ) :
          plotObject =  added_objects[k]
          if type(plotObject) is matplotlib.collections.PathCollection:
              plotObject.remove()
          elif type(plotObject) is matplotlib.text.Text:
              plotObject.remove()
          elif type(plotObject) is Wedge:
              plotObject.remove()
          else:
              plotObject[0].remove()
      added_objects = []
      
      if idx > -1:
          strokes = ftext.getKeypointStrokes(idx)
          if strokes.shape[0] > 0:
              added_objects.append( ax.scatter(strokes[:,0], strokes[:,1], c='yellow', s=s) )
      
      global last_selection
      pointmarkers = np.asarray(fastAll)
      pointmarkers[:, 0] += int(round(point[0]))
      pointmarkers[:, 1] += int(round(point[1]))
      pointmarkers12 = np.asarray(fastOffsets12)
      pointmarkers12[:, 0] += int(round(point[0]))
      pointmarkers12[:, 1] += int(round(point[1]))
      if len(point) > 4:
          print('point: {0} - {1} - {2} - {3}'.format(point, img[round(point[1]), round(point[0])], img[round(point[6]), round(point[5])], img[round(point[8]), round(point[7])]))
      
      np.round(pointmarkers, 0, pointmarkers)
      if len(img.shape) == 3:
          
          diff = (img[pointmarkers12[:, 1], pointmarkers12[:, 0]]).astype(np.int) - img[point[1], point[0]]
          if len(point) > 10:
              diff = diff[:, point[11]]
          else:
              diff = diff[:, 0]
          '''
          diff = np.zeros((pointmarkers12.shape[0]), dtype=np.int)
          for i in range(pointmarkers12.shape[0]):
              diff[i] = cdist(img[round(point[1]), round(point[0])], img[pointmarkers12[i, 1], pointmarkers12[i, 0]])
          print(diff)
          '''    
          masksame = diff < threshold
          maskDiff = np.invert(masksame)
          added_objects.append( ax.scatter(pointmarkers12[masksame,0], pointmarkers12[masksame,1], c='black', s=s) )
          added_objects.append( ax.scatter(pointmarkers12[maskDiff,0], pointmarkers12[maskDiff,1], c='white', s=s) )
          added_objects.append( ax.scatter([round(point[0])], [round(point[1])], c='black') )
          
          if len(point) > 4:
              #added_objects.append(  )
              added_objects.append(ax.plot([point[0], point[7]], [point[1], point[8]], 'r-'))
              #added_objects.append( ax.plot([point[0], point[5]], [point[1], point[6]], 'g-') )
          
          if point[10] == 0:   
              last_selection = (point, img[round(point[1]), round(point[0])][0] + threshold * 4, greater_then_b)
          else :
              last_selection = (point, point[3], greater_then_b)
          return
      diff = (img[pointmarkers12[:, 1], pointmarkers12[:, 0]]).astype(np.int) - img[int(point[1]), int(point[0])]
      print((img[pointmarkers12[:, 1], pointmarkers12[:, 0]]).astype(np.int))
      if len(point) < 3:
          added_objects.append( ax.scatter( [round(point[0])], [round(point[1])], c='black' ) )
          maxDiff = np.argmax(np.abs(diff))
          minDiff = np.argmin(np.abs(diff))
          point = ( point[0], point[1], point[0], point[1], 0, pointmarkers12[maxDiff, 0], pointmarkers12[maxDiff, 1], pointmarkers12[minDiff, 0], pointmarkers12[minDiff, 1])
          print(diff)    
      
      added_objects.append( ax.plot([point[0], point[7]], [point[1], point[8]], 'r-') )
      added_objects.append( ax.plot([point[0], pointmarkers12[0, 0]], [point[1], pointmarkers12[0, 1]], 'r-') )
      #added_objects.append( ax.plot([point[0], pointmarkers12[0, 0]], [point[1], pointmarkers12[0, 1]], 'r-') ) 
      #ax.plot([point[0], point[7]], [point[1], point[8]], 'r-')
      #added_objects.append( ax.plot([point[0], point[5]], [point[1], point[6]], 'g-') )
      #added_objects.append( ax.plot([point[0], pointmarkers12[7, 0]], [point[1], pointmarkers12[7, 1]], 'b-') )
      #added_objects.append( ax.plot([point[0], pointmarkers12[11, 0]], [point[1], pointmarkers12[11, 1]], 'b-') )
      
      if img[point[8], point[7]] <= img[point[6], point[5]]:
          print(diff)
          masksame = diff <= threshold
          maskDiff = np.invert(masksame)
          if showFast16:
              added_objects.append( ax.scatter(pointmarkers[masksame,0], pointmarkers[masksame,1], c='black') )
              added_objects.append( ax.scatter(pointmarkers[maskDiff,0], pointmarkers[maskDiff,1], c='white') )
          print('otsur: {0}'.format( point[3] +  img[point[1], point[0]] ))
          
          if True:
              pointmarkers12 = np.asarray(fastOffsets12)
              pointmarkers12[:, 0] += int(round(point[0]))
              pointmarkers12[:, 1] += int(round(point[1]))
              
              '''
              pointc12 = np.asarray(fastCorners12)
              pointc12[:, 0] += round(point[0])
              pointc12[:, 1] += round(point[1])
              '''
              
              added_objects.append( ax.scatter([point[0]], [point[1]],c='red', s=s ) )
              
              diff12 = ( img[pointmarkers12[:, 1], pointmarkers12[:, 0]].astype(np.int) - (img[point[1], point[0]])).astype(np.int)
              #diffc12 = ( img[pointc12[:, 1], pointc12[:, 0]].astype(np.int) - (img[point[1], point[0]])).astype(np.int)
              print('diff12: {0} ({1})'.format(diff12, threshold)) 
              masksame = diff12 <= threshold
              #masksamec = diffc12 <= threshold
              added_objects.append( ax.scatter(pointmarkers12[masksame,0], pointmarkers12[masksame,1],c='red', s=s ) )
              #added_objects.append( ax.scatter(pointc12[masksamec,0], pointc12[masksamec,1],c='red', s=s ) )
              masksame = np.invert(masksame)
              #masksamec = np.invert(masksamec)
              added_objects.append( ax.scatter(pointmarkers12[masksame,0], pointmarkers12[masksame,1],c='white', s=s ) )
              
              #added_objects.append( ax.scatter(pointc12[masksamec,0], pointc12[masksamec,1],c='white', s=s ) )
              xoffset = -0.05
              for i in range( pointmarkers12.shape[0]):
                  if i > 9:
                      xoffset = -0.1
                  added_objects.append(ax.text(pointmarkers12[i][0] + xoffset, pointmarkers12[i][1] + 0.05, '{0}'.format(i)))
              
              #added_objects.append(ax.text(pointc12[0][0] -0.05, pointc12[0][1] + 0.05, '{0}\''.format(2)))
              #added_objects.append(ax.text(pointc12[1][0] -0.05, pointc12[1][1] + 0.05, '{0}\''.format(5)))
              #added_objects.append(ax.text(pointc12[2][0] -0.05, pointc12[2][1] + 0.05, '{0}\''.format(8)))
              #added_objects.append(ax.text(pointc12[3][0] -0.1, pointc12[3][1] + 0.05, '{0}\''.format(11)))
              
              #w1 = Wedge((round(point[0]), round(point[1])), 2.6, 145, 72, fc='none', ec='green')
              #added_objects.append(ax.add_artist(w1))
              #added_objects.append(ax.text(pointmarkers12[6][0] -0.5, pointmarkers12[6][1] - 0.8, '$P_b$'.format(11), fontsize=24, color='green'))
              
              '''
              w1 = Wedge((round(point[0]), round(point[1])), 2.6, 320, 50, fc='none', ec='green')
              added_objects.append(ax.add_artist(w1))
              added_objects.append(ax.text(pointmarkers12[2][0] + 0.8, pointmarkers12[2][1] + 0.5, '$P_b$'.format(11), fontsize=24, color='green'))
              
              w1 = Wedge((round(point[0]), round(point[1])), 2.6, 105, 255, fc='none', ec='green')
              added_objects.append(ax.add_artist(w1))
              added_objects.append(ax.text(pointmarkers12[8][0] - 0.8, pointmarkers12[8][1] - 0.5, '$P^\prime_b$'.format(11), fontsize=24, color='green'))
              '''
              
              
              if showFast8 and True:
                  pointmarkers8 = np.asarray(fastOffsets8)
                  pointmarkers8[:, 0] += int(round(point[0]))
                  pointmarkers8[:, 1] += int(round(point[1]))
                  diff8 = ( img[pointmarkers8[:, 1], pointmarkers8[:, 0]].astype(np.int) - (img[point[1], point[0]])).astype(np.int)
                  print('diff8: {0} ({1})'.format(diff8, threshold)) 
                  masksame = diff8 <= threshold
                  if (point[1] - point[6]) == 2:
                      if ( point[0] - point[5] ) == 0:
                          added_objects.append( ax.scatter(pointmarkers8[0,0], pointmarkers8[0,1],c='magenta', s=s ) )
                          added_objects.append( ax.scatter(pointmarkers8[7,0], pointmarkers8[7,1],c='magenta', s=s ) )
                  if (point[1] - point[6]) == -1:
                      if ( point[0] - point[5] ) == -2:
                          added_objects.append( ax.scatter(pointmarkers8[2,0], pointmarkers8[2,1],c='magenta', s=s ) )
                          added_objects.append( ax.scatter(pointmarkers8[3,0], pointmarkers8[3,1],c='magenta', s=s ) )
                          
                          added_objects.append( ax.scatter(pointmarkers8[7,0], pointmarkers8[7,1],c='magenta', s=s ) )
                          added_objects.append( ax.scatter(pointmarkers8[0,0], pointmarkers8[0,1],c='magenta', s=s ) )
                          #added_objects.append( ax.scatter(pointmarkers8[7,0], pointmarkers8[7,1],c='red' ) )
                  #added_objects.append( ax.scatter(pointmarkers8[masksame,0], pointmarkers8[masksame,1],c='black' ) )
                  #masksame = np.invert(masksame)
                  added_objects.append( ax.scatter(pointmarkers8[masksame,0], pointmarkers8[masksame,1],c='magenta', s=s ) )
              '''
              pointmarkers12 = np.asarray(fastOffsetsC)
              pointmarkers12[:, 0] += round(point[0])
              pointmarkers12[:, 1] += round(point[1])
              diff12 = ( img[pointmarkers12[:, 1], pointmarkers12[:, 0]].astype(np.int) - (img[point[1], point[0]])).astype(np.int) 
              masksame = diff12 <= threshold
              added_objects.append( ax.scatter(pointmarkers12[masksame,0], pointmarkers12[masksame,1],c='#000044' ) )
              masksame = np.invert(masksame)
              added_objects.append( ax.scatter(pointmarkers12[masksame,0], pointmarkers12[masksame,1],c='#ffffaa' ) )
              '''
              
              
              
          
      else:
          vt = img[int(round(point[1])), int(round(point[0]))] - threshold
          diff = img[point[1], point[0]] - (img[pointmarkers[:, 1], pointmarkers[:, 0]]).astype(np.int)  
          print(diff)
          masksame = img[pointmarkers[:, 1], pointmarkers[:, 0]] >= vt
          maskDiff = np.invert(masksame)
          if showFast16:
              added_objects.append( ax.scatter(pointmarkers[masksame,0], pointmarkers[masksame,1], c='black') )
              added_objects.append( ax.scatter(pointmarkers[maskDiff,0], pointmarkers[maskDiff,1], c='white') )
          otsu_t = otsu_threshold(img, point, pointmarkers, negative=False)
          print('otsu: {0}'.format(otsu_t))
          print('otsur: {0}'.format( img[point[1], point[0]] - point[3]  ))
          last_selection = (point, otsu_t, greater_then)
          
          if True:
              pointmarkers12 = np.asarray(fastOffsets12)
              pointmarkers12[:, 0] += int(round(point[0]))
              pointmarkers12[:, 1] += int(round(point[1]))
              
              diff12 = ((img[point[1], point[0]]) - img[pointmarkers12[:, 1], pointmarkers12[:, 0]].astype(np.int)).astype(np.int) 
              print('diff12: {0}'.format(diff12))
              masksame = diff12 <= threshold
              added_objects.append( ax.scatter(pointmarkers12[masksame,0], pointmarkers12[masksame,1],c='red' ) )
              masksame = np.invert(masksame)
              added_objects.append( ax.scatter(pointmarkers12[masksame,0], pointmarkers12[masksame,1],c='white' ) )
              
              if showFast8:
                  pointmarkers8 = np.asarray(fastOffsets8)
                  pointmarkers8[:, 0] += int(round(point[0]))
                  pointmarkers8[:, 1] += int(round(point[1]))
                  diff8 = ( (img[point[1], point[0]]) - img[pointmarkers8[:, 1], pointmarkers8[:, 0]].astype(np.int)).astype(np.int)
                  print('diff8: {0} ({1})'.format(diff8, threshold)) 
                  masksame = diff8 <= threshold
                  added_objects.append( ax.scatter(pointmarkers8[masksame,0], pointmarkers8[masksame,1],c='black' ) )
                  #masksame = np.invert(masksame)
                  #added_objects.append( ax.scatter(pointmarkers8[masksame,0], pointmarkers8[masksame,1],c='#aaffff' ) )
              
              '''
              pointmarkers12 = np.asarray(fastOffsetsC)
              pointmarkers12[:, 0] += round(point[0])
              pointmarkers12[:, 1] += round(point[1])
              diff12 = ((img[point[1], point[0]]) - img[pointmarkers12[:, 1], pointmarkers12[:, 0]].astype(np.int)).astype(np.int) 
              print('diff12: {0}'.format(diff12))
              masksame = diff12 <= threshold
              added_objects.append( ax.scatter(pointmarkers12[masksame,0], pointmarkers12[masksame,1],c='#000044' ) )
              masksame = np.invert(masksame)
              added_objects.append( ax.scatter(pointmarkers12[masksame,0], pointmarkers12[masksame,1],c='#ffffaa' ) )
              '''
  
  
  def draw_keypoints(img, keypoints, threshold, inter = True, color = 1):
      
      scales = ftext.getImageScales()
      #s = 100
      
      octaves = np.unique( keypoints[:, 2])
      if octaves.shape[0] == 0:
          return
      maxOctave = np.max(octaves)
      images = []
      selectors = []
      drawers = []
      for i in range(int(maxOctave) + 1):
          scale = scales[i]
          dst = ftext.getImageAtScale(i)
          cv2.imwrite("/tmp/pycv-{0}.png".format(i), dst)
          if color == 1:
              images.append(cv2.cvtColor(dst, cv2.COLOR_BGR2RGB))
          else:
              '''
              shape = img.shape
              shapet = ( shape[0] * scale, shape[1] * scale) 
              dst = np.zeros(shapet, dtype=np.uint8)
              dst = cv2.resize(img, (0,0), fx=scale, fy=scale)
              images.append(cv2.cvtColor(dst, cv2.COLOR_BGR2RGB))
              '''
              images.append(dst)
              
              #cv2.imshow("img", dst)
              #cv2.waitKey(0)
          
      
      ax_tuple = []
         
      for i in range(int(maxOctave) + 1):
          f = plt.figure(num = i)
          ax = f.add_subplot(111)
          ax_tuple.append(ax)
          
          plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, hspace = 0, wspace = 0)
          plt.margins(0,0)
          
          #tmp = cv2.cvtColor(, cv2.COLOR_GRAY2RGB)
          ax_tuple[i].imshow(images[i], interpolation='nearest', cmap=mpl.cm.gray)
          ax_tuple[i].grid(True)
          ax_tuple[i].axis('off') 
          ax_tuple[i].set_xlim([0, images[i].shape[1]])
          ax_tuple[i].set_ylim([images[i].shape[0], 0])
          ax_tuple[i].axes.get_xaxis().set_ticks([])
          ax_tuple[i].axes.get_yaxis().set_ticks([])
          
          maskOct = keypoints[:, 2] == i
          octIdx = np.nonzero(maskOct)
          octavePoints = keypoints[keypoints[:, 2] == i, :]
          octavePoints[:, 0] *= scales[i]
          octavePoints[:, 1] *= scales[i]
          octavePoints[:, 5] *= scales[i]
          octavePoints[:, 6] *= scales[i]
          octavePoints[:, 7] *= scales[i]
          octavePoints[:, 8] *= scales[i]
          style = 'rx'
          c = 'red'
          if len(octavePoints) > 0 and octavePoints.shape[1] > 9:
              for k in range(6):
                  maski = octavePoints[:, 9] == k + 1
                  if k == 1:
                      style = "rv"
                  if k == 2:
                      style = "ro"
                  if k == 4:
                      style = "bo"
                      c = 'blue'
                  if k == 5:
                      style = "yo"
                      continue
                  
                  if drawGrayScale:
                      style = 'wv'
                      if k == 1:
                          style = "wv"
                      if k == 2:
                          style = "wv"
                      if k == 4:
                          style = "wo"
                          c = 'blue'
                      c = style
                  
                  ax_tuple[i].scatter(octavePoints[maski, 0], octavePoints[maski, 1],c=c, s=s )
                  #ax_tuple[i].plot(octavePoints[maski, 0], octavePoints[maski, 1], style, markersize = 10) 
          else:
              ax_tuple[i].plot(octavePoints[:, 0], octavePoints[:, 1], style)
          #ax_tuple[i].plot(octavePoints[:, 6] * scales[i], octavePoints[:, 7] * scales[i], 'bo')
          #for j in range( octavePoints.shape[0] ):
          #    ax_tuple[i].plot([octavePoints[j,0] * scales[i], octavePoints[j,6]* scales[i]], [octavePoints[j,1] * scales[i], octavePoints[j,7]* scales[i]], 'r-')
          if inter:
              rs = RectangleSelector(ax_tuple[i], line_select_callback,
                                         drawtype='box', useblit=True,
                                         button=[1,3], # don't use middle button
                                         minspanx=5, minspany=5,
                                         spancoords='pixels')
              rs.keypoints = octavePoints
              rs.octIdx = octIdx
              rs.image = images[i]
              rs.threshold = threshold
              selectors.append(rs)
              drawer = FastDrawer(ax_tuple[i], images[i], threshold)
              drawers.append(drawer)
      
      if inter:
          toggle_selector.RS = selectors
          plt.show() 
          plt.show(block=False)
      else:
          plt.show()
      
  
  def draw_letter_histogram(letterKeypointHistogram, title = 'Letter FAST Keypoints Histogram', figNo = 101):
      
      keys = []
      ticks = []
      values = []
      values.append([])
      values.append([])
      values.append([])
      values.append([])
      ticks.append([])
      ticks.append([])
      ticks.append([])
      ticks.append([])
      
      listlen = 0
      for letter in letterKeypointHistogram.keys():
          keys.append(letter)
          values[0].append(0)
          ticks[0].append(listlen)
          values[1].append(0)
          ticks[1].append(listlen + 0.2)
          values[2].append(0)
          ticks[2].append(listlen + 0.4)
          values[3].append(0)
          ticks[3].append(listlen + 0.6)
          for num in letterKeypointHistogram[letter].keys():
              values[num][listlen] = letterKeypointHistogram[letter][num]
      
          listlen += 1
          
      indices = sorted(range(len(values[0])),key=lambda x:values[0][x])
      for i in range(len(indices)):
          if values[0][indices[i]] == 1:
              break
      indices = indices[0:i]
      ticks[0] = ticks[0][0:i]
      ticks[1] = ticks[1][0:i]
      
          
      f = plt.figure(num = figNo, figsize=(16, 8))
      ax = f.add_subplot(111)
      plt.bar(ticks[0], np.asarray(values[0])[np.asarray(indices)], align='center', width=0.25, facecolor='r')
      plt.bar(ticks[1], np.asarray(values[1])[np.asarray(indices)], align='center', width=0.25, facecolor='b')
      #plt.bar(ticks[2], np.asarray(values[2])[np.asarray(indices)], align='center', width=0.15, facecolor='g', alpha=0.5)
      #plt.bar(ticks[3], np.asarray(values[3])[np.asarray(indices)], align='center', width=0.15, facecolor='g')
      plt.xticks(ticks[0], np.asarray(keys)[np.asarray(indices)])
      ax.set_title(title)
      plt.xlabel('Letter')
      plt.ylabel('Keypoints Count')
      
      #plt.show()
      
      
  def show_image(image_path = '/datagrid/personal/TextSpotter/evaluation-sets/icdar2013-Train/196.jpg'):
        
      img = cv2.imread(image_path, 0)
      imgc = cv2.imread(image_path)
      
      scaleFactor = 2.0
      nleves = -1
      edgeThreshold = 12
      keypointTypes = 3
      kMin = 9
      kMax = 15
      charClsModelFile = '/home/busta/workspace/TextSpotter/BoostCharacterDetector.xml'
      
      ft.init('/home/busta/git/SmsReader/charclassifier.xml', 1, scaleFactor, nleves, edgeThreshold, keypointTypes, kMin, kMax, 2, charClsModelFile)
      
      inputDir = '/datagrid/personal/TextSpotter/evaluation-sets/icdar2013-Train'
      segmDir = '{0}/segmentations'.format(inputDir)
      
      baseName = os.path.basename(image_path)
      baseName = baseName[:-4]
      
      segmGt = '{0}/{1}_GT.txt'.format(segmDir, baseName)
      segmentations = ft.getCharSegmentations(img, outputDir, baseName)
      for i in range(segmentations.shape[0]):
              rectn = segmentations[i, :]
              rectn[2] += rectn[0]
              rectn[3] += rectn[1] 
      
      if os.path.exists(segmGt):
          gt_rects = utls.read_icdar2013_segm_gt(segmGt)
              
          rcurrent = 0
          rden = 0
          for gt_rect in gt_rects:
              best_match = 0 
              for detId in range(segmentations.shape[0]):
                  rectn = segmentations[detId, :]
                  rect_int =  utils.intersect( rectn, gt_rect )
                  int_area = utils.area(rect_int)
                  union_area = utils.area(utils.union(rectn, gt_rect))
              
                  ratio = int_area / float(union_area)
              
                  if ratio > best_match:
                      best_match = ratio
                      
              thickness = 1
              color = (0, 0, 255)
              if best_match > 0.5:
                  color = (0, 255, 0)
              if best_match > 0.7:
                  thickness = 2
              cv2.rectangle(imgc, (gt_rect[0], gt_rect[1]), (gt_rect[2], gt_rect[3]), color, thickness)
                      
              rcurrent += best_match   
              rden += 1
              
          pden = 0
          pcurrent = 0
          for detId in range(segmentations.shape[0]):
              best_match = 0
              rectn = segmentations[detId, :]
              for gt_rect in gt_rects:
                  rect_int =  utils.intersect( rectn, gt_rect )
                  int_area = utils.area(rect_int)
                  union_area = utils.area(utils.union(rectn, gt_rect))
                  
                  ratio = int_area / float(union_area)
                  
                  if ratio > best_match:
                      best_match = ratio
              
              pcurrent += best_match   
              pden += 1
      
      ax0 = plt.imshow(img, cmap=pylab.gray())
      keypoints = ft.findKeyPoints(img, scaleFactor, nleves, edgeThreshold, keypointTypes, kMin, kMax)
      tz = plt.plot(keypoints[:, 0], keypoints[:, 1], 'ro')
      plt.show(block=False)
      if imgc.shape[0] > 1024:
          shape = imgc.shape
          shapet = ( shape[0] / 2, shape[1] / 2, shape[2]) 
          dst = np.zeros(shapet, dtype=np.uint8)
          dst = cv2.resize(imgc, (0,0), fx=0.5, fy=0.5)
          imgc = dst
          
      cv2.imshow('imgc', imgc)
      cv2.waitKey(0)
      