text: import numpy as np
  import matplotlib.pyplot as plt
  
  # http://www.robots.ox.ac.uk/~vgg/rg/papers/CalonderLSF10.pdf
  # sigma=2 and kernel size of 9x9 for Gaussian smoothing
  
  numBits = 256 
  numBytes = numBits/8
  numInts = numBytes/4
  patchS = 37
  
  #/*********************************************************************
  #* Software License Agreement (BSD License)
  #*
  #*  Copyright (c) 2009, Willow Garage, Inc.
  #*  All rights reserved.
  #*
  #*  Redistribution and use in source and binary forms, with or without
  #*  modification, are permitted provided that the following conditions
  #*  are met:
  #*
  #*   * Redistributions of source code must retain the above copyright
  #*     notice, this list of conditions and the following disclaimer.
  #*   * Redistributions in binary form must reproduce the above
  #*     copyright notice, this list of conditions and the following
  #*     disclaimer in the documentation and/or other materials provided
  #*     with the distribution.
  #*   * Neither the name of the Willow Garage nor the names of its
  #*     contributors may be used to endorse or promote products derived
  #*     from this software without specific prior written permission.
  #*
  #*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  #*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  #*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  #*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  #*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  #*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  #*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  #*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  #*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  #*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  #*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  #*  POSSIBILITY OF SUCH DAMAGE.
  #*********************************************************************/
  #
  #/** Authors: Ethan Rublee, Vincent Rabaud, Gary Bradski */
  
  # From https://github.com/opencv/opencv/blob/master/modules/features2d/src/orb.cpp
  locations = [ 8,-3, 9,5,
      4,2, 7,-12,
      -11,9, -8,2,
      7,-12, 12,-13,
      2,-13, 2,12,
      1,-7, 1,6,
      -2,-10, -2,-4,
      -13,-13, -11,-8,
      -13,-3, -12,-9,
      10,4, 11,9,
      -13,-8, -8,-9,
      -11,7, -9,12,
      7,7, 12,6,
      -4,-5, -3,0,
      -13,2, -12,-3,
      -9,0, -7,5,
      12,-6, 12,-1,
      -3,6, -2,12,
      -6,-13, -4,-8,
      11,-13, 12,-8,
      4,7, 5,1,
      5,-3, 10,-3,
      3,-7, 6,12,
      -8,-7, -6,-2,
      -2,11, -1,-10,
      -13,12, -8,10,
      -7,3, -5,-3,
      -4,2, -3,7,
      -10,-12, -6,11,
      5,-12, 6,-7,
      5,-6, 7,-1,
      1,0, 4,-5,
      9,11, 11,-13,
      4,7, 4,12,
      2,-1, 4,4,
      -4,-12, -2,7,
      -8,-5, -7,-10,
      4,11, 9,12,
      0,-8, 1,-13,
      -13,-2, -8,2,
      -3,-2, -2,3,
      -6,9, -4,-9,
      8,12, 10,7,
      0,9, 1,3,
      7,-5, 11,-10,
      -13,-6, -11,0,
      10,7, 12,1,
      -6,-3, -6,12,
      10,-9, 12,-4,
      -13,8, -8,-12,
      -13,0, -8,-4,
      3,3, 7,8,
      5,7, 10,-7,
      -1,7, 1,-12,
      3,-10, 5,6,
      2,-4, 3,-10,
      -13,0, -13,5,
      -13,-7, -12,12,
      -13,3, -11,8,
      -7,12, -4,7,
      6,-10, 12,8,
      -9,-1, -7,-6,
      -2,-5, 0,12,
      -12,5, -7,5,
      3,-10, 8,-13,
      -7,-7, -4,5,
      -3,-2, -1,-7,
      2,9, 5,-11,
      -11,-13, -5,-13,
      -1,6, 0,-1,
      5,-3, 5,2,
      -4,-13, -4,12,
      -9,-6, -9,6,
      -12,-10, -8,-4,
      10,2, 12,-3,
      7,12, 12,12,
      -7,-13, -6,5,
      -4,9, -3,4,
      7,-1, 12,2,
      -7,6, -5,1,
      -13,11, -12,5,
      -3,7, -2,-6,
      7,-8, 12,-7,
      -13,-7, -11,-12,
      1,-3, 12,12,
      2,-6, 3,0,
      -4,3, -2,-13,
      -1,-13, 1,9,
      7,1, 8,-6,
      1,-1, 3,12,
      9,1, 12,6,
      -1,-9, -1,3,
      -13,-13, -10,5,
      7,7, 10,12,
      12,-5, 12,9,
      6,3, 7,11,
      5,-13, 6,10,
      2,-12, 2,3,
      3,8, 4,-6,
      2,6, 12,-13,
      9,-12, 10,3,
      -8,4, -7,9,
      -11,12, -4,-6,
      1,12, 2,-8,
      6,-9, 7,-4,
      2,3, 3,-2,
      6,3, 11,0,
      3,-3, 8,-8,
      7,8, 9,3,
      -11,-5, -6,-4,
      -10,11, -5,10,
      -5,-8, -3,12,
      -10,5, -9,0,
      8,-1, 12,-6,
      4,-6, 6,-11,
      -10,12, -8,7,
      4,-2, 6,7,
      -2,0, -2,12,
      -5,-8, -5,2,
      7,-6, 10,12,
      -9,-13, -8,-8,
      -5,-13, -5,-2,
      8,-8, 9,-13,
      -9,-11, -9,0,
      1,-8, 1,-2,
      7,-4, 9,1,
      -2,1, -1,-4,
      11,-6, 12,-11,
      -12,-9, -6,4,
      3,7, 7,12,
      5,5, 10,8,
      0,-4, 2,8,
      -9,12, -5,-13,
      0,7, 2,12,
      -1,2, 1,7,
      5,11, 7,-9,
      3,5, 6,-8,
      -13,-4, -8,9,
      -5,9, -3,-3,
      -4,-7, -3,-12,
      6,5, 8,0,
      -7,6, -6,12,
      -13,6, -5,-2,
      1,-10, 3,10,
      4,1, 8,-4,
      -2,-2, 2,-13,
      2,-12, 12,12,
      -2,-13, 0,-6,
      4,1, 9,3,
      -6,-10, -3,-5,
      -3,-13, -1,1,
      7,5, 12,-11,
      4,-2, 5,-7,
      -13,9, -9,-5,
      7,1, 8,6,
      7,-8, 7,6,
      -7,-4, -7,1,
      -8,11, -7,-8,
      -13,6, -12,-8,
      2,4, 3,9,
      10,-5, 12,3,
      -6,-5, -6,7,
      8,-3, 9,-8,
      2,-12, 2,8,
      -11,-2, -10,3,
      -12,-13, -7,-9,
      -11,0, -10,-5,
      5,-3, 11,8,
      -2,-13, -1,12,
      -1,-8, 0,9,
      -13,-11, -12,-5,
      -10,-2, -10,11,
      -3,9, -2,-13,
      2,-3, 3,2,
      -9,-13, -4,0,
      -4,6, -3,-10,
      -4,12, -2,-7,
      -6,-11, -4,9,
      6,-3, 6,11,
      -13,11, -5,5,
      11,11, 12,6,
      7,-5, 12,-2,
      -1,12, 0,7,
      -4,-8, -3,-2,
      -7,1, -6,7,
      -13,-12, -8,-13,
      -7,-2, -6,-8,
      -8,5, -6,-9,
      -5,-1, -4,5,
      -13,7, -8,10,
      1,5, 5,-13,
      1,0, 10,-13,
      9,12, 10,-1,
      5,-8, 10,-9,
      -1,11, 1,-13,
      -9,-3, -6,2,
      -1,-10, 1,12,
      -13,1, -8,-10,
      8,-11, 10,-6,
      2,-13, 3,-6,
      7,-13, 12,-9,
      -10,-10, -5,-7,
      -10,-8, -8,-13,
      4,-6, 8,5,
      3,12, 8,-13,
      -4,2, -3,-3,
      5,-13, 10,-12,
      4,-13, 5,-1,
      -9,9, -4,3,
      0,3, 3,-9,
      -12,1, -6,1,
      3,2, 4,-8,
      -10,-10, -10,9,
      8,-13, 12,12,
      -8,-12, -6,-5,
      2,2, 3,7,
      10,6, 11,-8,
      6,8, 8,-12,
      -7,10, -6,5,
      -3,-9, -3,9,
      -1,-13, -1,5,
      -3,-7, -3,4,
      -8,-2, -8,3,
      4,2, 12,12,
      2,-5, 3,11,
      6,-9, 11,-13,
      3,-1, 7,12,
      11,-1, 12,4,
      -3,0, -3,6,
      4,-11, 4,12,
      2,-4, 2,1,
      -10,-6, -8,1,
      -13,7, -11,1,
      -13,12, -11,-13,
      6,0, 11,-13,
      0,-1, 1,4,
      -13,3, -9,-2,
      -9,8, -6,-3,
      -13,-6, -8,-2,
      5,-9, 8,10,
      2,7, 3,-9,
      -1,-6, -1,-1,
      9,5, 11,-2,
      11,-3, 12,-8,
      3,0, 3,5,
      -1,4, 0,10,
      3,-6, 4,5,
      -13,0, -10,5,
      5,8, 12,11,
      8,9, 9,-6,
      7,-4, 8,-12,
      -10,4, -10,9,
      7,3, 12,4,
      9,-7, 10,-2,
      7,0, 12,-2,
      -1,-6, 0,-11]
  
  
  # using the random sampling strategy with isotropic Gaussian
  n = 0
  xs = np.zeros((2,2*numBits))
  for i in range(256):
    xs[0,2*i] = locations[4*i]
    xs[1,2*i] = locations[4*i+1]
    xs[0,2*i+1] = locations[4*i+2]
    xs[1,2*i+1] = locations[4*i+3]
  
  xs0 = np.copy(xs)
  with open("orb.h",'w') as f:
    for r in range(0,30):
      f.write("case {}:\n".format(r))
      f.write("  ExtractOrb{}(patch, desc);\n".format(r))
      f.write("  return true;\n".format(r))
  
    plt.figure()
    for r in range(0,30):
      alpha = r*12./180.*np.pi
      R = np.array([[np.cos(alpha), -np.sin(alpha)],[np.sin(alpha), np.cos(alpha)]])
      xs = np.copy(xs0)
      xs = R.dot(xs)
      xs += 0.5*patchS
      xs = np.floor(xs).astype(int)
  
      if np.any(xs >= patchS):
        print r,"large values"
      if np.any(xs<0):
        print r,"small values"
  
      print np.mean(xs,axis=1)
  
      if True:
        plt.subplot(6,6,r+1)
        for i in range(numBits):
          plt.plot(xs[0,i*2:(i+1)*2],xs[1,i*2:(i+1)*2],'r-')
  
        plt.xlim([0,patchS-1])
        plt.ylim([0,patchS-1])
  
        f.write("void ExtractOrb{}".format(r)+"(const Image<uint8_t>& patch, Vector8uda& desc) {\n")
        k = 0
        for i in range(numInts):
          f.write("desc({}) = ((patch({},{}) < patch({},{}) ? {} : 0)\n".format(i,xs[0,k*2],xs[1,k*2],xs[0,k*2+1],xs[1,k*2+1],1))
          k+=1
          for j in range(1,31):
            f.write(" | (patch({},{}) < patch({},{}) ? {} : 0)\n".format(xs[0,k*2],xs[1,k*2],xs[0,k*2+1],xs[1,k*2+1],2**j))
            k+=1
          f.write(" | (patch({},{}) < patch({},{}) ? {} : 0));\n".format(xs[0,k*2],xs[1,k*2],xs[0,k*2+1],xs[1,k*2+1],2**31))
        f.write("}\n\n")
  
    plt.show()
    
  
  