Class: Imogen::AutoCrop::Box::Best

Inherits:
Object
  • Object
show all
Defined in:
lib/imogen/auto_crop/box.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(grayscale) ⇒ Best

Returns a new instance of Best.



6
7
8
9
10
11
12
13
# File 'lib/imogen/auto_crop/box.rb', line 6

def initialize(grayscale)
  @corners = grayscale.good_features_to_track(0.3, 1.0, block_size: 3, max: 20)
  if @corners.nil? or @corners.length == 0
    @center = Center.new(grayscale)
  else
    @center = nil
  end
end

Class Method Details

.distance(p1, p2) ⇒ Object



15
16
17
18
19
# File 'lib/imogen/auto_crop/box.rb', line 15

def self.distance(p1, p2)
  dx = p1.x.to_i - p2.x.to_i
  dy = p1.y.to_i - p2.y.to_i
  return Math.sqrt((dx * dx) + (dy * dy)) 
end

Instance Method Details

#boxObject



21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/imogen/auto_crop/box.rb', line 21

def box()
  return @center.box unless @center.nil?
  c = median()
  cp = BoxInfo.new(c[0], c[1],0)
  total_distance = 0;
  features = @corners.collect {|corner| d = Best.distance(corner, cp); total_distance += d; {x: corner.x, y: corner.y, d: d}}
  mean_distance = total_distance/features.length
  sigma = features.inject(0) {|memo, feature| v = feature[:d] - mean_distance; memo += (v*v)}
  sigma = Math.sqrt(sigma.to_f/features.length)
  # 2 sigmas would capture > 95% of normally distributed features
  cp.radius = 2*sigma
  cp
end

#medianObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/imogen/auto_crop/box.rb', line 35

def median()
  @median ||= begin
    xs = []
    ys = []
    @corners.each {|c| xs << c.x.to_i; ys << c.y.to_i}
    xs.sort!
    ys.sort!
    ix = 0
    if (@corners.length % 2 == 0)
      l = (@corners.length == 2) ? 0 : (@corners.length/2)
      x = ((xs[l] + xs[l+1]) /2).floor
      y = ((ys[l] + ys[l+1]) /2).floor
      [x,y]
    else
      r = (@corners.length/2).ceil
      [xs[r], ys[r]]
    end
  end
end