finished the edge detectors
This commit is contained in:
parent
95806ebd36
commit
f2301f5c71
2
.gitignore
vendored
2
.gitignore
vendored
@ -8,3 +8,5 @@
|
|||||||
/spec/reports/
|
/spec/reports/
|
||||||
/tmp/
|
/tmp/
|
||||||
/vendor
|
/vendor
|
||||||
|
.DS_Store
|
||||||
|
/test/output/
|
||||||
|
@ -8,3 +8,4 @@ require 'edge_detect/differ'
|
|||||||
require 'edge_detect/horizontal_differ'
|
require 'edge_detect/horizontal_differ'
|
||||||
require 'edge_detect/vertical_differ'
|
require 'edge_detect/vertical_differ'
|
||||||
require 'edge_detect/edge_detector'
|
require 'edge_detect/edge_detector'
|
||||||
|
require 'edge_detect/sobel_edge_detector'
|
||||||
|
@ -11,15 +11,18 @@ module EdgeDetect
|
|||||||
end
|
end
|
||||||
|
|
||||||
def detect_edges
|
def detect_edges
|
||||||
h_differ = HorizontalDiffer.new(self.image)
|
image = ChunkyPNG::Image.new(@image.width, @image.height, ChunkyPNG::Color::TRANSPARENT)
|
||||||
v_differ = VerticalDiffer.new(self.image)
|
h_diff = HorizontalDiffer.new(self.image)
|
||||||
|
v_diff = VerticalDiffer.new(self.image)
|
||||||
|
|
||||||
self.image.width.times do |i|
|
self.image.width.times do |i|
|
||||||
self.image.height.times do |j|
|
self.image.height.times do |j|
|
||||||
|
|
||||||
|
value = (h_diff[i, j] + v_diff[i, j]).abs
|
||||||
|
image[i, j] = ChunkyPNG::Color.rgb(value, value, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
image
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -6,7 +6,23 @@ module EdgeDetect
|
|||||||
end
|
end
|
||||||
|
|
||||||
def [](x, y)
|
def [](x, y)
|
||||||
ChunkyPNG::Color.to_grayscale(@image[x, y])
|
begin
|
||||||
|
(ChunkyPNG::Color.to_grayscale(@image[x, y]) & 0x0000ff00) >> 8
|
||||||
|
rescue ChunkyPNG::OutOfBounds => e
|
||||||
|
0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def nearby(x, y, radius)
|
||||||
|
output = []
|
||||||
|
((x - radius)..(x + radius)).each do |i|
|
||||||
|
row = []
|
||||||
|
((y - radius)..(y + radius)).each do |j|
|
||||||
|
row << self[i, j]
|
||||||
|
end
|
||||||
|
output << row
|
||||||
|
end
|
||||||
|
output
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
39
lib/edge_detect/sobel_edge_detector.rb
Normal file
39
lib/edge_detect/sobel_edge_detector.rb
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
module EdgeDetect
|
||||||
|
class SobelEdgeDetector < EdgeDetector
|
||||||
|
def detect_edges
|
||||||
|
image = ChunkyPNG::Image.new(@image.width, @image.height, ChunkyPNG::Color::TRANSPARENT)
|
||||||
|
gray = GrayScaler.new(self.image)
|
||||||
|
|
||||||
|
self.image.width.times do |i|
|
||||||
|
self.image.height.times do |j|
|
||||||
|
v_x = (sobel_x * Matrix.columns(gray.nearby(i, j, 1))).sum
|
||||||
|
v_y = (sobel_y * Matrix.columns(gray.nearby(i, j, 1))).sum
|
||||||
|
|
||||||
|
# / 10 because otherwise it's too much noise
|
||||||
|
value = Math.sqrt(v_x ** 2 + v_y ** 2).to_i / 10
|
||||||
|
image[i, j] = ChunkyPNG::Color.rgb(value, value, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
image
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def sobel_x
|
||||||
|
@sobel_x ||= Matrix[
|
||||||
|
[1, 0, -1],
|
||||||
|
[2, 0, -2],
|
||||||
|
[1, 0, -1]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def sobel_y
|
||||||
|
@sobel_y ||= Matrix[
|
||||||
|
[1, 2, 1],
|
||||||
|
[0, 0, 0],
|
||||||
|
[-1, -2, -1]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
@ -2,31 +2,35 @@ require 'test_helper'
|
|||||||
|
|
||||||
class EdgeDetectorTest < Minitest::Test
|
class EdgeDetectorTest < Minitest::Test
|
||||||
|
|
||||||
def setup
|
|
||||||
@vertical_line = create_vertical_line
|
def test_vertical_line
|
||||||
@horizontal_line = create_horizontal_line
|
input = File.expand_path('../../pictures/airplane.png', __FILE__)
|
||||||
|
image = ChunkyPNG::Image.from_file(input)
|
||||||
|
|
||||||
|
standard = EdgeDetector.new(image)
|
||||||
|
sobel = SobelEdgeDetector.new(image)
|
||||||
|
|
||||||
|
output_standard = File.expand_path('../../output/airplane_standard.png', __FILE__)
|
||||||
|
output_sobel = File.expand_path('../../output/airplane_sobel.png', __FILE__)
|
||||||
|
|
||||||
|
standard.detect_edges.save(output_standard)
|
||||||
|
sobel.detect_edges.save(output_sobel)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_a
|
def test_horizontal_line
|
||||||
edge = EdgeDetector.new(@vertical_line)
|
input = File.expand_path('../../pictures/robot.png', __FILE__)
|
||||||
edge.detect_edges
|
image = ChunkyPNG::Image.from_file(input)
|
||||||
|
|
||||||
|
standard = EdgeDetector.new(image)
|
||||||
|
sobel = SobelEdgeDetector.new(image)
|
||||||
|
|
||||||
|
output_standard = File.expand_path('../../output/robot_standard.png', __FILE__)
|
||||||
|
output_sobel = File.expand_path('../../output/robot_sobel.png', __FILE__)
|
||||||
|
|
||||||
|
standard.detect_edges.save(output_standard)
|
||||||
|
sobel.detect_edges.save(output_sobel)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
def create_horizontal_line
|
|
||||||
image = ChunkyPNG::Image.new(7, 3, ChunkyPNG::Color::TRANSPARENT)
|
|
||||||
(1..5).each do |i|
|
|
||||||
image[i, 1] = ChunkyPNG::Color('black')
|
|
||||||
end
|
|
||||||
image
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_vertical_line
|
|
||||||
image = ChunkyPNG::Image.new(3, 7, ChunkyPNG::Color::TRANSPARENT)
|
|
||||||
(1..5).each do |i|
|
|
||||||
image[1, i] = ChunkyPNG::Color('black')
|
|
||||||
end
|
|
||||||
image
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
BIN
test/pictures/airplane.png
Normal file
BIN
test/pictures/airplane.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 346 KiB |
BIN
test/pictures/robot.png
Normal file
BIN
test/pictures/robot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
Loading…
Reference in New Issue
Block a user