imogen 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa9d6f61ab8d5aa8f99517c1d4d638cf3a5cb508179d05cf8262bd24f796df35
4
- data.tar.gz: 27dc10c53681b2fbd7ea25b258dd5d049c5bbf5b31dc4e01d16d25f829798300
3
+ metadata.gz: f78baebd0825df57e7ddeea7a7ca02c95a9c2c064c264532a911b12e72d289ad
4
+ data.tar.gz: c2d64e9187fa67bf65c6be9eb256cd430155609b4e5c8a0f2d5a48742fc87ceb
5
5
  SHA512:
6
- metadata.gz: f482b46a68ae037dd849cac3232ec7fe74a4902fde31a5c84c7ec323cbddb61a1138aa4192d58092b80acdbc0ae4475569e4d14bb4c17513d18cb8637cad5ae4
7
- data.tar.gz: e54a8310bb1af53d1cb6f2287ea6aa23fade2cf51980cc3096dec7fe91844b77c982d46373df67c0028a385175e1276cc7deed5356515e695339cff912cf8bf3
6
+ metadata.gz: 72f13fe92f9dc14fb61131218d84eb6516dab1a3737839e7377f717d0badee2ffe0bd8b57bb0c6fb6ba056bf2ad151c910296d09f1943e20bcaf96621c1db20d
7
+ data.tar.gz: 9eb6bd80a0dfa8d797a39267d805acde74e7ac33fe9395556db2d143396fe7aef0dd2603b9fd8df58b4b2d519adf24019b82113cf7506fca867a53eeb43404c4
@@ -0,0 +1,99 @@
1
+ require 'mkmf-rice'
2
+
3
+ osx = RbConfig::CONFIG['target_os'] =~ /darwin/
4
+
5
+ if osx
6
+ $CFLAGS << " -x c++ -std=c++14"# damn the torpedoes!
7
+ else
8
+ $CFLAGS << " -x c++"
9
+ end
10
+
11
+ def real_inc_dir(src)
12
+ File.symlink?(src) ? File.realdirpath(src) : src
13
+ end
14
+
15
+ def add_flags_if_header(header, header_dir, lib_dir)
16
+ a_file = File.join(header_dir, header)
17
+ exists = File.exist?(a_file)
18
+ puts "#{a_file} exists ... #{exists}"
19
+ if exists
20
+ inc_opt = "-I#{header_dir}".quote
21
+ lib_opt = "-L#{lib_dir}".quote
22
+ puts "adding compiler flags:\n#{inc_opt}\n#{lib_opt}"
23
+ $INCFLAGS << " " << inc_opt
24
+ $LIBPATH = $LIBPATH | [lib_dir]
25
+ end
26
+ exists
27
+ end
28
+
29
+ incdir_default = "/usr/local/include"
30
+ libdir_default = "/usr/local/lib"
31
+
32
+ have_library('stdc++')
33
+ # MakeMakefile::CONFTEST_C = "#{CONFTEST}.cc"
34
+
35
+ required_headers = {}
36
+ required_libs = {}
37
+
38
+ required_headers['opencv4'] = [ 'opencv2/features2d.hpp' ]
39
+ required_libs['opencv4'] = [
40
+ 'opencv_core',
41
+ 'opencv_imgcodecs',
42
+ 'opencv_imgproc',
43
+ 'opencv_features2d'
44
+ ]
45
+
46
+ required_libs['zlib'] = ['z']
47
+ required_libs['libwebp'] = ['webp']
48
+ required_libs['libjpeg'] = ['jpeg']
49
+ required_libs['libtiff-4'] = ['tiff']
50
+ required_libs['libpng'] = ['png16']
51
+ required_libs['jasper'] = [] # just run pkg-config if you can
52
+ required_libs['OpenEXR'] = ['IlmImf']
53
+
54
+ all_deps = (required_libs.keys | required_headers.keys).sort.uniq
55
+ all_deps.each do |dep_key|
56
+ has_pkg_config = (pkg_config(dep_key) || []).detect { |c| c =~ /\-L\/\w+/ }
57
+
58
+ # expect to call with --with-opencv4-include=DIR and --with-opencv4-lib=DIR or --withopencv4-dir=DIR
59
+ incdir, libdir = dir_config(dep_key, incdir_default, libdir_default) unless has_pkg_config
60
+
61
+ unless !has_pkg_config && incdir && incdir != incdir_default
62
+ puts "using default #{dep_key} include path: #{incdir_default}"
63
+ end
64
+
65
+ unless !has_pkg_config && libdir && libdir != libdir_default
66
+ puts "using default #{dep_key} library path: #{libdir_default}"
67
+ end
68
+
69
+ include_paths = [incdir_default, "/usr/local"]
70
+ include_paths = ([incdir, File.join(incdir, dep_key)] | include_paths) if incdir
71
+
72
+ required_headers.fetch(dep_key, []).each do |hdr|
73
+ unless find_header(hdr, *include_paths.compact.uniq)
74
+ open(MakeMakefile::Logging.instance_variable_get(:@logfile), 'r') do |logblob|
75
+ logblob.each { |logline| puts logline.strip }
76
+ end
77
+ puts "Cannot find required header: #{hdr}"
78
+ puts "if this output is from rake compile, consider adding:"
79
+ puts "rake compile -- --with#{dep_key}-include=DIR"
80
+ exit 1
81
+ end
82
+ end
83
+
84
+ lib_paths = [libdir_default, "/usr/local"]
85
+ lib_paths.unshift(libdir) if libdir
86
+
87
+ required_libs.fetch(dep_key, []).each do |lib|
88
+ unless find_library(lib, nil, *lib_paths.compact.uniq)
89
+ puts "Cannot find required lib: #{lib}"
90
+ exit 1
91
+ end
92
+ end
93
+ append_cflags(lib_paths.compact.uniq.map {|x| "-L#{x}"}.join(' '))
94
+ end
95
+
96
+ append_cflags('-stdlib=libc++')
97
+ @libdir_basename ||= 'lib'
98
+ $LIBRUBYARG.prepend(' ') # there's some weird spacing issue in rice's lib linking routine
99
+ create_makefile('imogencv')
@@ -0,0 +1,87 @@
1
+ #include "rice/Class.hpp"
2
+ #include "rice/Constructor.hpp"
3
+ #include "rice/Enum.hpp"
4
+ #include "opencv2/features2d.hpp"
5
+ #include "opencv2/imgproc.hpp"
6
+ #include "opencv2/imgcodecs.hpp"
7
+
8
+ using namespace Rice;
9
+
10
+ Object process_kaze_features(Object r_image)
11
+ {
12
+ cv::Mat image = from_ruby<cv::Mat>(r_image);
13
+ std::vector<cv::KeyPoint> keyPoints;
14
+ cv::Ptr<cv::KAZE> alg = cv::KAZE::create();
15
+ cv::Mat features;
16
+ alg->detectAndCompute(image, cv::noArray(), keyPoints, features);
17
+ Array a;
18
+ for(cv::KeyPoint keyPoint : keyPoints)
19
+ {
20
+ a.push(to_ruby<cv::Point2f>(keyPoint.pt));
21
+ }
22
+ keyPoints.clear();
23
+ return a;
24
+ }
25
+
26
+ Object load_grayscale(Object filename)
27
+ {
28
+ Check_Type(filename, T_STRING);
29
+ cv::String const c_path = cv::String(String(filename).str());
30
+ cv::Mat image = imread(c_path, cv::IMREAD_GRAYSCALE);
31
+ return to_ruby<cv::Mat>(image);
32
+ }
33
+
34
+ Object point2f_x(Object self)
35
+ {
36
+ cv::Point2f point = from_ruby<cv::Point2f>(self);
37
+ return to_ruby<int>(point.x);
38
+ }
39
+
40
+ Object point2f_y(Object self)
41
+ {
42
+ cv::Point2f point = from_ruby<cv::Point2f>(self);
43
+ return to_ruby<int>(point.y);
44
+ }
45
+
46
+ Object mat_cols(Object self)
47
+ {
48
+ cv::Mat image = from_ruby<cv::Mat>(self);
49
+ return to_ruby<int>(image.cols);
50
+ }
51
+
52
+ Object mat_rows(Object self)
53
+ {
54
+ cv::Mat image = from_ruby<cv::Mat>(self);
55
+ return to_ruby<int>(image.rows);
56
+ }
57
+
58
+ Object mat_good_features_to_track(Object self, int maxCorners, double qualityLevel, double minDistance, int blockSize, bool useHarrisDetector, double k)
59
+ {
60
+ cv::Mat image = from_ruby<cv::Mat>(self);
61
+ cv::Mat mask;
62
+ std::vector<cv::Point2f> corners;
63
+ cv::goodFeaturesToTrack(image, corners, maxCorners, qualityLevel, minDistance, mask, blockSize, useHarrisDetector, k);
64
+ Array a;
65
+ for(cv::Point2f corner : corners)
66
+ {
67
+ a.push(to_ruby<cv::Point2f>(corner));
68
+ }
69
+ corners.clear();
70
+ return a;
71
+ }
72
+
73
+ extern "C"
74
+ void Init_imogencv()
75
+ {
76
+ Module rb_mOpenCV = define_module("ImogenCV");
77
+ Class rb_cKazeFeatures = rb_mOpenCV.define_class("KazeFeatures");
78
+ rb_cKazeFeatures.define_singleton_method("process", &process_kaze_features);
79
+ Data_Type<cv::Mat> rb_cMat = rb_mOpenCV.define_class<cv::Mat>("Mat")
80
+ .define_method(Identifier("cols"), &mat_cols)
81
+ .define_method(Identifier("rows"), &mat_rows)
82
+ .define_method("good_features_to_track", &mat_good_features_to_track)
83
+ .define_singleton_method("load_grayscale", &load_grayscale);
84
+ Data_Type<cv::Point2f> rb_cPoint2f = rb_mOpenCV.define_class<cv::Point2f>("Point2f")
85
+ .define_method(Identifier("x"), &point2f_x)
86
+ .define_method(Identifier("y"), &point2f_y);
87
+ }
@@ -1,10 +1,11 @@
1
1
  #!ruby
2
- require 'opencv'
2
+ require 'imogencv'
3
3
  module Imogen::AutoCrop::Box
4
- include OpenCV
4
+ include ImogenCV
5
5
  class Best
6
6
  def initialize(grayscale)
7
- @corners = grayscale.good_features_to_track(0.3, 1.0, block_size: 3, max: 20)
7
+ # mat_good_features_to_track(std::int maxCorners, std::double qualityLevel, std:double minDistance, std::int blockSize, std::bool useHarrisDetector, std::double k)
8
+ @corners = grayscale.good_features_to_track(20, 0.3, 1.0, 3, false, 0.04)
8
9
  if @corners.nil? or @corners.length == 0
9
10
  @center = Center.new(grayscale)
10
11
  else
@@ -77,7 +78,7 @@ module Imogen::AutoCrop::Box
77
78
  dims = [img.width, img.height]
78
79
  ratio = dims.min.to_f / dims.max
79
80
  return ratio >= BoxInfo::SQUARISH
80
- elsif img.is_a? OpenCV::CvMat
81
+ elsif img.is_a? ImogenCV::Mat
81
82
  dims = [img.cols, img.rows]
82
83
  ratio = dims.min.to_f / dims.max
83
84
  return ratio >= BoxInfo::SQUARISH
@@ -1,67 +1,67 @@
1
1
  #!ruby
2
- require 'opencv'
2
+ require 'imogencv'
3
3
  require 'free-image'
4
4
  require 'tempfile'
5
5
 
6
6
  module Imogen::AutoCrop
7
- class Edges
8
- include OpenCV
9
- def initialize(src)
10
- @xoffset = 0
11
- @yoffset = 0
12
- if src.is_a? FreeImage::Bitmap
13
- img = src
14
- @xoffset = img.width.to_f/6
15
- @yoffset = img.height.to_f/6
16
- if Imogen::AutoCrop::Box.squarish? img
17
- @xoffset = @xoffset/2
18
- @yoffset = @yoffset/2
19
- end
20
- @tempfile = Tempfile.new(['crop','.png'])
7
+ class Edges
8
+ include ImogenCV
9
+ def initialize(src)
10
+ @xoffset = 0
11
+ @yoffset = 0
12
+ tempfile = nil
13
+ if src.is_a? FreeImage::Bitmap
14
+ img = src
15
+ @xoffset = img.width.to_f/6
16
+ @yoffset = img.height.to_f/6
17
+ if Imogen::AutoCrop::Box.squarish? img
18
+ @xoffset = @xoffset/2
19
+ @yoffset = @yoffset/2
20
+ end
21
+ tempfile = Tempfile.new(['crop','.png'])
21
22
 
22
- img.copy(@xoffset,@yoffset,img.width-@xoffset,img.height-@yoffset) do |crop|
23
- crop.save(@tempfile.path, :png)
24
- crop.free
23
+ img.copy(@xoffset,@yoffset,img.width-@xoffset,img.height-@yoffset) do |crop|
24
+ crop.save(tempfile.path, :png)
25
+ crop.free
26
+ end
27
+ else
28
+ raise src.class.name
25
29
  end
26
- else
27
- raise src.class.name
30
+ # use bigger features on bigger images
31
+ @grayscale = ImogenCV::Mat.load_grayscale(tempfile.path)
32
+ @xrange = (0..@grayscale.cols)
33
+ @yrange = (0..@grayscale.rows)
34
+ ensure
35
+ tempfile.unlink if tempfile
28
36
  end
29
- # use bigger features on bigger images
30
- @grayscale = CvMat.load(@tempfile.path, CV_LOAD_IMAGE_GRAYSCALE)
31
- @xrange = (0..@grayscale.cols)
32
- @yrange = (0..@grayscale.rows)
33
- end
34
-
35
- def bound_min(center)
36
- [center.x - @xrange.min, @xrange.max - center.x, center.y - @yrange.min, @yrange.max - center.y].min
37
- end
38
37
 
39
- # returns leftX, topY, rightX, bottomY
40
- def get(*args)
41
- c = Imogen::AutoCrop::Box.info(@grayscale)
42
- r = c.radius.floor
43
- # adjust the box
44
- coords = [c.x, c.y]
45
- min_rad = args.max/2
46
- unless r >= min_rad && r <= bound_min(c)
47
- # first adjust to the lesser of max (half short dimension) and min (half requested length) radius
48
- # this might require upscaling in rare situations to preserve bound safety
49
- r = min_rad if r < min_rad
50
- max_rad = [@xrange.max - @xrange.min, @yrange.max - @yrange.min].min / 2
51
- r = max_rad if r > max_rad
52
- # now move the center point minimally to accomodate the necessary radius
53
- coords[0] = @xrange.max - r if (coords[0] + r) > @xrange.max
54
- coords[0] = @xrange.min + r if (coords[0] - r) < @xrange.min
55
- coords[1] = @yrange.max - r if (coords[1] + r) > @yrange.max
56
- coords[1] = @yrange.min + r if (coords[1] - r) < @yrange.min
38
+ def bound_min(center)
39
+ [center.x - @xrange.min, @xrange.max - center.x, center.y - @yrange.min, @yrange.max - center.y].min
57
40
  end
58
- coords = [coords[0] + @xoffset, coords[1] + @yoffset].collect {|i| i.floor}
59
- c = coords
60
41
 
61
- return [c[0]-r, c[1]-r, c[0]+r, c[1] + r]
62
- end
63
- def unlink
64
- @tempfile.unlink
42
+ # returns leftX, topY, rightX, bottomY
43
+ def get(*args)
44
+ c = Imogen::AutoCrop::Box.info(@grayscale)
45
+ r = c.radius.floor
46
+ # adjust the box
47
+ coords = [c.x, c.y]
48
+ min_rad = args.max/2
49
+ unless r >= min_rad && r <= bound_min(c)
50
+ # first adjust to the lesser of max (half short dimension) and min (half requested length) radius
51
+ # this might require upscaling in rare situations to preserve bound safety
52
+ r = min_rad if r < min_rad
53
+ max_rad = [@xrange.max - @xrange.min, @yrange.max - @yrange.min].min / 2
54
+ r = max_rad if r > max_rad
55
+ # now move the center point minimally to accomodate the necessary radius
56
+ coords[0] = @xrange.max - r if (coords[0] + r) > @xrange.max
57
+ coords[0] = @xrange.min + r if (coords[0] - r) < @xrange.min
58
+ coords[1] = @yrange.max - r if (coords[1] + r) > @yrange.max
59
+ coords[1] = @yrange.min + r if (coords[1] - r) < @yrange.min
60
+ end
61
+ coords = [coords[0] + @xoffset, coords[1] + @yoffset].collect {|i| i.floor}
62
+ c = coords
63
+
64
+ return [c[0]-r, c[1]-r, c[0]+r, c[1] + r]
65
+ end
65
66
  end
66
67
  end
67
- end
@@ -14,7 +14,6 @@ module Imogen
14
14
  thumb.free
15
15
  end
16
16
  end
17
- frame.unlink
18
17
  end
19
18
  end
20
- end
19
+ end
@@ -46,15 +46,11 @@ class Region < Transform
46
46
  else
47
47
  if edges == :featured
48
48
  frame = Imogen::AutoCrop::Edges.new(img)
49
- begin
50
- edges = frame.get([img.width, img.height,768].min)
51
- ensure
52
- frame.unlink
53
- end
49
+ edges = frame.get([img.width, img.height,768].min)
54
50
  end
55
51
  img.copy(*edges) {|crop| yield crop}
56
52
  end
57
53
  end
58
54
  end
59
55
  end
60
- end
56
+ end
data/lib/imogen.rb CHANGED
@@ -104,4 +104,5 @@ module Imogen
104
104
  FreeImage::Bitmap.new(ptr, nil, &block)
105
105
  end
106
106
  end
107
- end
107
+ end
108
+ require 'imogencv'
Binary file
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imogen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Armintor
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-16 00:00:00.000000000 Z
11
+ date: 2019-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: ruby-opencv
14
+ name: rice
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -38,12 +38,29 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake-compiler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  description:
42
56
  email: armintor@gmail.com
43
57
  executables: []
44
- extensions: []
58
+ extensions:
59
+ - ext/imogencv/extconf.rb
45
60
  extra_rdoc_files: []
46
61
  files:
62
+ - ext/imogencv/extconf.rb
63
+ - ext/imogencv/imogencv.cpp
47
64
  - lib/imogen.rb
48
65
  - lib/imogen/auto_crop.rb
49
66
  - lib/imogen/auto_crop/box.rb
@@ -55,6 +72,7 @@ files:
55
72
  - lib/imogen/iiif/size.rb
56
73
  - lib/imogen/iiif/tiles.rb
57
74
  - lib/imogen/zoomable.rb
75
+ - lib/imogencv.bundle
58
76
  - spec/spec_helper.rb
59
77
  - spec/unit/imogen_iiif_quality_spec.rb
60
78
  - spec/unit/imogen_iiif_region_spec.rb