Many image processing algorithms are defined for grayscale (or else monochromatic) images.



Task

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.




INCLUDE "H6:RGB2GRAY.ACT" ;from task Grayscale image
 
PROC PrintB3(BYTE x)
  IF x<10 THEN
    Print("  ")
  ELSEIF x<100 THEN
    Print(" ")
  FI
  PrintB(x)
RETURN
 
PROC PrintRgbImage(RgbImage POINTER img)
  BYTE x,y
  RGB c
 
  FOR y=0 TO img.h-1
  DO
    FOR x=0 TO img.w-1
    DO
      GetRgbPixel(img,x,y,c)
      Put(32)
      PrintB3(c.r) Put(32)
      PrintB3(c.g) Put(32)
      PrintB3(c.b) Put(32)
    OD
    PutE()
  OD
RETURN
 
PROC PrintGrayImage(GrayImage POINTER img)
  BYTE x,y,c
 
  FOR y=0 TO img.h-1
  DO
    FOR x=0 TO img.w-1
    DO
      c=GetGrayPixel(img,x,y)
      Put(32)
      PrintB3(c)
    OD
    PutE()
  OD
RETURN
 
PROC Main()
  BYTE ARRAY rgbdata=[
      0   0   0    0   0 255    0 255   0
    255   0   0    0 255 255  255   0 255
    255 255   0  255 255 255   31  63 127
     63  31 127  127  31  63  127  63  31]
  BYTE ARRAY graydata(12)
  BYTE width=[3],height=[4],LMARGIN=$52,oldLMARGIN
  RgbImage rgbimg
  GrayImage grayimg
 
  oldLMARGIN=LMARGIN
  LMARGIN=0 ;remove left margin on the screen
  Put(125) PutE() ;clear the screen
  InitRgbToGray()
  InitRgbImage(rgbimg,width,height,rgbdata)
  InitGrayImage(grayimg,width,height,graydata)
 
  PrintE("Original RGB image:")
  PrintRgbImage(rgbimg) PutE()
 
  RgbToGray(rgbimg,grayimg)
  PrintE("RGB to grayscale image:")
  PrintGrayImage(grayimg) PutE()
 
  GrayToRgb(grayimg,rgbimg)
  PrintE("Grayscale to RGB image:")
  PrintRgbImage(rgbimg)
 
  LMARGIN=oldLMARGIN ;restore left margin on the screen
RETURN