dhash-vips 0.0.3.1 → 0.0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +148 -3
- data/lib/dhash-vips.rb +5 -8
- data/lib/dhash-vips/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef9b532c31699dd2445292844b5d0760a9e79351
|
4
|
+
data.tar.gz: b4e52489d194424a01c9954053bd38a910178124
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8a286f3b357af1b1fddfc20bda62bb018868b68952f4e706c2a2a336ae12ca24f15d32a0b267ed574295740cb3e3b8efcb83fbf3a8eb75be2f5894662c46444
|
7
|
+
data.tar.gz: f643c1d3b9e6bd13a269cf3ceb5b9ea6ec7dffc27927c4d1cc9384201285be74b335e62a167faf89c5cb0295936a449f10c0201eb987937ae4f050119d662fff
|
data/Rakefile
CHANGED
@@ -2,6 +2,7 @@ STDOUT.sync = true
|
|
2
2
|
|
3
3
|
require "bundler/gem_tasks"
|
4
4
|
|
5
|
+
|
5
6
|
task :default => %w{ spec }
|
6
7
|
|
7
8
|
require "rspec/core/rake_task"
|
@@ -9,11 +10,13 @@ RSpec::Core::RakeTask.new :spec do |t|
|
|
9
10
|
t.verbose = false
|
10
11
|
end
|
11
12
|
|
13
|
+
|
12
14
|
visualize_hash = lambda do |hash|
|
13
15
|
puts hash.to_s(2).rjust(64, ?0).gsub(/(?<=.)/, '\0 ').scan(/.{16}/)
|
14
16
|
end
|
15
17
|
|
16
|
-
|
18
|
+
desc "Compare how Vips and ImageMagick resize images to 9x8"
|
19
|
+
task :compare_pixelation do |_|
|
17
20
|
require_relative "lib/dhash-vips"
|
18
21
|
require "dhash"
|
19
22
|
|
@@ -33,9 +36,10 @@ task :compare_pixelation do |_, args|
|
|
33
36
|
end
|
34
37
|
end
|
35
38
|
|
36
|
-
|
39
|
+
desc "Compare how Vips resizes image to 9x8 with different kernels"
|
40
|
+
task :compare_kernels do |_|
|
37
41
|
require_relative "lib/dhash-vips"
|
38
|
-
require "dhash"
|
42
|
+
# require "dhash"
|
39
43
|
|
40
44
|
%i{ nearest linear cubic lanczos2 lanczos3 }.each do |kernel|
|
41
45
|
hashes = ARGV.drop(1).map do |arg|
|
@@ -45,3 +49,144 @@ task :compare_kernels do |_, args|
|
|
45
49
|
puts "kernel: #{kernel}, distance: #{DHashVips::DHash.hamming *hashes}"
|
46
50
|
end
|
47
51
|
end
|
52
|
+
|
53
|
+
|
54
|
+
desc "Compare the quality of Dhash, DHashVips::DHash and DHashVips::IDHash -- run it only after `rake test`"
|
55
|
+
task :compare_matrixes do |_|
|
56
|
+
require "dhash"
|
57
|
+
require_relative "lib/dhash-vips"
|
58
|
+
require "mll"
|
59
|
+
[Dhash, DHashVips::DHash, DHashVips::IDHash].each do |m|
|
60
|
+
hashes = %w{
|
61
|
+
71662d4d4029a3b41d47d5baf681ab9a.jpg
|
62
|
+
ad8a37f872956666c3077a3e9e737984.jpg
|
63
|
+
1d468d064d2e26b5b5de9a0241ef2d4b.jpg
|
64
|
+
92d90b8977f813af803c78107e7f698e.jpg
|
65
|
+
309666c7b45ecbf8f13e85a0bd6b0a4c.jpg
|
66
|
+
3f9f3db06db20d1d9f8188cd753f6ef4.jpg
|
67
|
+
df0a3b93e9412536ee8a11255f974141.jpg
|
68
|
+
679634ff89a31279a39f03e278bc9a01.jpg
|
69
|
+
}.map{ |filename| m.calculate "images/#{filename}" }
|
70
|
+
table = MLL::table[m.method(:hamming), [hashes], [hashes]]
|
71
|
+
array = Array.new(4){ [] }
|
72
|
+
hashes.size.times.to_a.repeated_combination(2) do |i, j|
|
73
|
+
array[i == j ? 0 : (j - i).abs == 1 && (i + j - 1) % 4 == 0 ? [i, j] == [0, 1] ? 1 : 2 : 3].push table[i][j]
|
74
|
+
end
|
75
|
+
p array.map &:sort
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# ruby -c Rakefile && rm -f ab.png && rake compare_images -- fc762fa286489d8afc80adc8cdcb125e.jpg 9c2c240ec02356472fb532f404d28dde.jpg 2>/dev/null && ql ab.png
|
80
|
+
desc "Visualizes the IDHash difference measurement between two images"
|
81
|
+
task :compare_images do |_|
|
82
|
+
abort "there should be two image filenames passed as arguments" unless ARGV.size == 3
|
83
|
+
require_relative "lib/dhash-vips"
|
84
|
+
ha, hb = ARGV.drop(1).map &DHashVips::IDHash.method(:calculate)
|
85
|
+
puts "distance: #{DHashVips::IDHash.hamming ha, hb}"
|
86
|
+
|
87
|
+
require "delegate"
|
88
|
+
class ImageMutable < SimpleDelegator
|
89
|
+
%i{ draw_line draw_circle }.each do |m|
|
90
|
+
define_method "#{m}!" do |*args|
|
91
|
+
__setobj__ self.send m, *args
|
92
|
+
self
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
a, b = ARGV.drop(1).map do |filename|
|
97
|
+
image = Vips::Image.new_from_file filename
|
98
|
+
ImageMutable.new image.resize(8.fdiv(image.width), vscale: 8.fdiv(image.height)).colourspace("b-w").
|
99
|
+
resize(100, vscale: 100, kernel: :nearest).colourspace("srgb")
|
100
|
+
end
|
101
|
+
|
102
|
+
ad = ha >> 128
|
103
|
+
ai = ha - (ad << 128)
|
104
|
+
bd = hb >> 128
|
105
|
+
bi = hb - (bd << 128)
|
106
|
+
|
107
|
+
n = 0
|
108
|
+
[[a, ad, ai], [b, bd, bi]].each do |image, xd, xi|
|
109
|
+
127.downto(0).each do |i|
|
110
|
+
if i > 63
|
111
|
+
y, x = (127 - i).divmod 8
|
112
|
+
else
|
113
|
+
x, y = (63 - i).divmod 8
|
114
|
+
end
|
115
|
+
x = (image.width * (x + 0.5) / 8).round
|
116
|
+
y = (image.height * (y + 0.5) / 8).round
|
117
|
+
if i > 63
|
118
|
+
(x-2..x+2).map do |x| [
|
119
|
+
[x, y , x, (y + image.height / 16 - 1) % image.height],
|
120
|
+
[x, (y + image.height / 16 + 1) % image.height, x, (y + image.height / 8 ) % image.height],
|
121
|
+
] end
|
122
|
+
else
|
123
|
+
(y-2..y+2).map do |y| [
|
124
|
+
[ x , y, (x + image.width / 16 - 1) % image.width, y],
|
125
|
+
[(x + image.width / 16 + 1) % image.width, y, (x + image.width / 8 ) % image.width, y],
|
126
|
+
] end
|
127
|
+
end.each do |coords1, coords2|
|
128
|
+
n += 1
|
129
|
+
image.draw_line! (1 - xd[i]) * 255, *coords1
|
130
|
+
image.draw_line! xd[i] * 255, *coords2
|
131
|
+
end if ai[i] + bi[i] > 0 && ad[i] != bd[i]
|
132
|
+
cx, cy = if i > 63
|
133
|
+
[x, y + 20]
|
134
|
+
else
|
135
|
+
[x + 20, y]
|
136
|
+
end
|
137
|
+
image.draw_circle! xd[i] * 255, cx, cy, 11, fill: true if xi[i] > 0
|
138
|
+
image.draw_circle! (1 - xd[i]) * 255, cx, cy, 10, fill: true if xi[i] > 0
|
139
|
+
end
|
140
|
+
end
|
141
|
+
puts "distance: #{n / 10}"
|
142
|
+
|
143
|
+
a.join(b.__getobj__, :horizontal, shim: 10).write_to_file "ab.png"
|
144
|
+
end
|
145
|
+
|
146
|
+
desc "Benchmarks Dhash, DHashVips::DHash and DHashVips::IDHash"
|
147
|
+
task :compare_speed do
|
148
|
+
require "dhash"
|
149
|
+
require_relative "lib/dhash-vips"
|
150
|
+
|
151
|
+
filenames = %w{
|
152
|
+
71662d4d4029a3b41d47d5baf681ab9a.jpg
|
153
|
+
ad8a37f872956666c3077a3e9e737984.jpg
|
154
|
+
1d468d064d2e26b5b5de9a0241ef2d4b.jpg
|
155
|
+
92d90b8977f813af803c78107e7f698e.jpg
|
156
|
+
309666c7b45ecbf8f13e85a0bd6b0a4c.jpg
|
157
|
+
3f9f3db06db20d1d9f8188cd753f6ef4.jpg
|
158
|
+
df0a3b93e9412536ee8a11255f974141.jpg
|
159
|
+
679634ff89a31279a39f03e278bc9a01.jpg
|
160
|
+
}.flat_map do |filename|
|
161
|
+
image = Vips::Image.new_from_file "images/#{filename}"
|
162
|
+
[0, 1, 2, 3].map do |a|
|
163
|
+
"benchmark/#{a}_#{filename}".tap do |filename|
|
164
|
+
next if File.exist? filename
|
165
|
+
FileUtils.mkdir_p "benchmark"
|
166
|
+
image.rot(a).write_to_file filename
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
require "benchmark"
|
172
|
+
puts "load and calculate:"
|
173
|
+
hashes = []
|
174
|
+
Benchmark.bm 18 do |bm|
|
175
|
+
[Dhash, DHashVips::DHash, DHashVips::IDHash].each do |m|
|
176
|
+
bm.report m do
|
177
|
+
hashes.push filenames.map &m.method(:calculate)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
puts "hamming (1000 times):"
|
182
|
+
Benchmark.bm 18 do |bm|
|
183
|
+
[Dhash, DHashVips::DHash, DHashVips::IDHash].zip(hashes) do |m, hs|
|
184
|
+
bm.report m do
|
185
|
+
hs.product hs do |h1, h2|
|
186
|
+
1000.times{ m.hamming h1, h2 }
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
data/lib/dhash-vips.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
require_relative "dhash-vips/version"
|
2
2
|
require "vips"
|
3
|
-
require "mll"
|
4
3
|
|
5
4
|
module DHashVips
|
6
|
-
module DHash
|
7
5
|
|
6
|
+
module DHash
|
8
7
|
extend self
|
9
8
|
|
10
9
|
def hamming a, b
|
@@ -28,15 +27,13 @@ module DHashVips
|
|
28
27
|
|
29
28
|
end
|
30
29
|
|
30
|
+
require "mll"
|
31
31
|
module IDHash
|
32
32
|
extend self
|
33
33
|
|
34
34
|
def hamming a, b
|
35
|
-
|
36
|
-
|
37
|
-
bd = b >> 128
|
38
|
-
bi = b - (bd << 128)
|
39
|
-
((ai | bi) & (ad ^ bd)).to_s(2).count "1"
|
35
|
+
# TODO: the hash_size=8 is hardcoded here
|
36
|
+
((a | b) & (a >> 128 ^ b >> 128)).to_s(2).count "1"
|
40
37
|
end
|
41
38
|
|
42
39
|
def median array
|
@@ -72,7 +69,7 @@ module DHashVips
|
|
72
69
|
d.flatten.map{ |c| c.abs >= m ? 1 : 0 }.join.to_i(2),
|
73
70
|
]
|
74
71
|
end
|
75
|
-
(((((d1 <<
|
72
|
+
(((((d1 << hash_size * hash_size) + d2) << hash_size * hash_size) + i1) << hash_size * hash_size) + i2
|
76
73
|
end
|
77
74
|
|
78
75
|
end
|
data/lib/dhash-vips/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dhash-vips
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.3.
|
4
|
+
version: 0.0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Maslov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-vips
|