finished the edge detectors

This commit is contained in:
Tim Kächele 2015-08-15 00:40:06 +02:00
parent 95806ebd36
commit f2301f5c71
8 changed files with 91 additions and 26 deletions

2
.gitignore vendored
View File

@ -8,3 +8,5 @@
/spec/reports/
/tmp/
/vendor
.DS_Store
/test/output/

View File

@ -8,3 +8,4 @@ require 'edge_detect/differ'
require 'edge_detect/horizontal_differ'
require 'edge_detect/vertical_differ'
require 'edge_detect/edge_detector'
require 'edge_detect/sobel_edge_detector'

View File

@ -11,16 +11,19 @@ module EdgeDetect
end
def detect_edges
h_differ = HorizontalDiffer.new(self.image)
v_differ = VerticalDiffer.new(self.image)
image = ChunkyPNG::Image.new(@image.width, @image.height, ChunkyPNG::Color::TRANSPARENT)
h_diff = HorizontalDiffer.new(self.image)
v_diff = VerticalDiffer.new(self.image)
self.image.width.times do |i|
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
image
end
end

View File

@ -6,7 +6,23 @@ module EdgeDetect
end
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

View 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

View File

@ -2,31 +2,35 @@ require 'test_helper'
class EdgeDetectorTest < Minitest::Test
def setup
@vertical_line = create_vertical_line
@horizontal_line = create_horizontal_line
def test_vertical_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
def test_a
edge = EdgeDetector.new(@vertical_line)
edge.detect_edges
def test_horizontal_line
input = File.expand_path('../../pictures/robot.png', __FILE__)
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
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

BIN
test/pictures/airplane.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

BIN
test/pictures/robot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB