0

Anyone know how to convert to grayscale, below is some skeleton code i need to use to do so. Specifically, convert "before" to grayscale, apply the Sobel edge detection convolution filter, and store the result in "after". before must be non-empty.

template <typename color_depth> void 
edge_detect(gfx::image<color_depth>& after,
const gfx::image<color_depth>& before) {

  // Check arguments.
  assert(!before.empty());

  // TODO: replace this function body with working code. Make sure
  // to delete this comment.

  // Hint: Use the grayscale(...) and extend_edges(...) filters to
  // prepare for the Sobel convolution. Then compute the Sobel
  // operator one pixel at a time. Finally use crop_extended_edges
  // to un-do the earlier extend_edges.

}

1 Answers1

3

This looks to be a homework question so I won't give a full implementation. I also can't tell if you want to convert to greyscale on the CPU or in a shader. Regardless of where you perform the conversion the formulas are the same.

There is no definitive method for converting to greyscale since since you're discarding information and whether the end results look correct is entirely subjective. Below are some common methods for converting from RGB to greyscale:

A naive approach is to find the colour channel with the highest value and just use that.

grey = max(colour.r, max(colour.g, colour.b));

The naive approach suffers in that certain areas of your image will lose detail completely if they contain none of the colour with the highest value. To prevent this we can use a simple average of all the colour components.

grey = (colour.r + colour.g + colour.b) / 3.0;

A 'better' method is to use the luma value. The human eye perceives some colour wavelengths better than others. So if we give more weight to those colours we produce a more plausible greyscale.

grey = dot_product(colour, vec3(0.299, 0.587, 0.114));

Yet another method is to 'desaturate' the image. This involves first converting from the RGB colour space to HSL. Then reducing the saturation to zero.

Fibbs
  • 1,350
  • 1
  • 13
  • 23