Skip to content

Image Gradient

kkrmno edited this page Sep 26, 2020 · 2 revisions

"The Music Lesson" by Chelsea Porcelain Manufactory from the collection of the Metropolitan Museum of Art is licensed under CC0 1.0.

Computing the gradient:

require "imgrb"

file_name = "MET_music_lesson_cropped"
img = Imgrb::Image.new("#{file_name}.png")
img_gray = img.to_gray.get_channel(0) #Grayscale without alpha channel.

sigma = 1
grad_x, grad_y = img_gray.gradient(sigma)
grad_mag = ((grad_x**2 + grad_y**2)**0.5).rescale
theta = (-grad_y).atan2(grad_x)

#Colormap
hsv_lambda = ->(angle){
  val = ((angle / (Math::PI)) + 1) * 3
  rgb = [0,0,0]
  comp = 255 * (1 - ((val % 2) - 1).abs)
  if 0 <= val && val <= 1
    rgb = [255, comp, 0]
  elsif 1 < val && val <= 2
    rgb = [comp, 255, 0]
  elsif 2 < val && val <= 3
    rgb = [0, 255, comp]
  elsif 3 < val && val <= 4
    rgb = [0, comp, 255]
  elsif 4 < val && val <= 5
    rgb = [comp, 0, 255]
  elsif 5 < val && val <= 6
    rgb = [255, 0, comp]
  end
  rgb
}

#Illustrate gradient by coloring based on direction and magnitude.
angle_rgb = theta.apply_lambda(hsv_lambda)*Imgrb::Image.new(grad_mag, grad_mag, grad_mag)

(grad_x.rescale*255).round.save("#{file_name}_grad_x.png")
(grad_y.rescale*255).round.save("#{file_name}_grad_y.png")
(grad_mag*255).round.save("#{file_name}_grad_mag.png")
angle_rgb.round.save("#{file_name}_angles.png")

This results in the following set of images:

Gradient in horizontal direction:


Gradient in vertical direction:


Gradient magnitude:


Gradient direction: