Grayscale image: Difference between revisions

From Rosetta Code
Content added Content deleted
(added ocaml)
Line 49: Line 49:
end Color;
end Color;
</ada>
</ada>


=={{header|OCaml}}==

Conversion to a grayscale image:
<ocaml>let to_grayscale ~img:(_, r_channel, g_channel, b_channel) =
let width = Bigarray.Array2.dim1 r_channel
and height = Bigarray.Array2.dim2 r_channel in

let gray_channel =
let kind = Bigarray.int8_unsigned
and layout = Bigarray.c_layout
in
(Bigarray.Array2.create kind layout width height)
in
for y = 0 to pred height do
for x = 0 to pred width do
let r = r_channel.{x,y}
and g = g_channel.{x,y}
and b = b_channel.{x,y} in
let v = (2_126 * r + 7_152 * g + 722 * b) / 10_000 in
gray_channel.{x,y} <- v;
done;
done;
(gray_channel)</ocaml>

Conversion to a color image:
<ocaml>let to_color ~img:gray_channel =
let width = Bigarray.Array2.dim1 gray_channel
and height = Bigarray.Array2.dim2 gray_channel in
let all_channels =
let kind = Bigarray.int8_unsigned
and layout = Bigarray.c_layout
in
Bigarray.Array3.create kind layout 3 width height
in
let r_channel = Bigarray.Array3.slice_left_2 all_channels 0
and g_channel = Bigarray.Array3.slice_left_2 all_channels 1
and b_channel = Bigarray.Array3.slice_left_2 all_channels 2
in
Bigarray.Array2.blit gray_channel r_channel;
Bigarray.Array2.blit gray_channel g_channel;
Bigarray.Array2.blit gray_channel b_channel;
(all_channels,
r_channel,
g_channel,
b_channel)</ocaml>

Revision as of 21:30, 7 December 2008

Task
Grayscale image
You are encouraged to solve this task according to the task description, using any language you may know.

Many image processing algorithms are defined for grayscale (or else monochromatic) images. Extend the data storage type defined on this page to support grayscale images. Define two operations, one to convert a color image to a grayscale image and one for the backward conversion. To get luminance of a color use the formula recommended by CIE:

L = 0.2126·R + 0.7152·G + 0.0722·B

When using floating-point arithmetic make sure that rounding errors would not cause run-time problems or else distorted results when calculated luminance is stored as an unsigned integer.

Ada

<ada> type Grayscale_Image is array (Positive range <>, Positive range <>) of Luminance; </ada> Conversion to a grayscale image: <ada> function Grayscale (Picture : Image) return Grayscale_Image is

  type Extended_Luminance is range 0..10_000_000;
  Result : Grayscale_Image (Picture'Range (1), Picture'Range (2));
  Color  : Pixel;

begin

  for I in Picture'Range (1) loop
     for J in Picture'Range (2) loop
        Color := Picture (I, J);
        Result (I, J) :=
           Luminance
           (  Extended_Luminance'Min
              (  Extended_Luminance (Luminance'Last),
                 (  (  2_126 * Extended_Luminance (Color.R)
                    +  7_152 * Extended_Luminance (Color.G)
                    +    722 * Extended_Luminance (Color.B)
                    )
                 /  10_000
           )  )  );
     end loop;
  end loop;
  return Result;

end Grayscale; </ada> Conversion to a color image: <ada> function Color (Picture : Grayscale_Image) return Image is

  Result : Image (Picture'Range (1), Picture'Range (2));

begin

  for I in Picture'Range (1) loop
     for J in Picture'Range (2) loop
        Result (I, J) := (others => Picture (I, J));
     end loop;
  end loop;
  return Result;

end Color; </ada>


OCaml

Conversion to a grayscale image: <ocaml>let to_grayscale ~img:(_, r_channel, g_channel, b_channel) =

 let width = Bigarray.Array2.dim1 r_channel
 and height = Bigarray.Array2.dim2 r_channel in
 let gray_channel =
   let kind = Bigarray.int8_unsigned
   and layout = Bigarray.c_layout
   in
   (Bigarray.Array2.create kind layout width height)
 in
 for y = 0 to pred height do
   for x = 0 to pred width do
     let r = r_channel.{x,y}
     and g = g_channel.{x,y}
     and b = b_channel.{x,y} in
     let v = (2_126 * r +  7_152 * g + 722 * b) / 10_000 in
     gray_channel.{x,y} <- v;
   done;
 done;
 (gray_channel)</ocaml>

Conversion to a color image: <ocaml>let to_color ~img:gray_channel =

 let width = Bigarray.Array2.dim1 gray_channel
 and height = Bigarray.Array2.dim2 gray_channel in
 let all_channels =
   let kind = Bigarray.int8_unsigned
   and layout = Bigarray.c_layout
   in
   Bigarray.Array3.create kind layout 3 width height
 in
 let r_channel = Bigarray.Array3.slice_left_2 all_channels 0
 and g_channel = Bigarray.Array3.slice_left_2 all_channels 1
 and b_channel = Bigarray.Array3.slice_left_2 all_channels 2
 in
 Bigarray.Array2.blit gray_channel r_channel;
 Bigarray.Array2.blit gray_channel g_channel;
 Bigarray.Array2.blit gray_channel b_channel;
 (all_channels,
  r_channel,
  g_channel,
  b_channel)</ocaml>