Dr. Cho’s Website
Course Materials

Full-color image processing

Dr. Huidae Cho
Institute for Environmental and Spatial Analysis...University of North Georgia

1   Color components

Since there are three components in the RGB color system, we can interpret a color point as a vector: \[ \mathbf{c}= \begin{bmatrix} c_R\\ c_G\\ c_B \end{bmatrix}= \begin{bmatrix} R\\ G\\ B \end{bmatrix}. \]

In the spatial domain, \[ \mathbf{c}(x,y)= \begin{bmatrix} c_R(x,y)\\ c_G(x,y)\\ c_B(x,y) \end{bmatrix}= \begin{bmatrix} R(x,y)\\ G(x,y)\\ B(x,y) \end{bmatrix}. \]

2   Color transformations

Similar to gray transformations, we can formulate color transformations as \[ g(x,y)=T\left[f(x,y)\right] \] where $f(x,y)$ and $g(x,y)$ are input and transformed color images, respectively, and $T()$ is a transform function. Note that $f(x,y)$ and $g(x,y)$ have three components (or four in the CMYK color system).

3   Per-color-component transformations

Let $r_i$ and $s_i$ be input and transformed component $i$ of $f(x,y)$ and $g(x,y)$, respectively. We can write one of the simplest form of color transformations as follows: \[ s_i=T_i(r_i)\quad i=1,2,\cdots,n. \]

What this equation means is that we can apply the transform function to each color component individually independent of other components (on a per-color-component basis).

3.1   Intensity transformation

\[g(x,y)=kf(x,y)\] where $0<k<1$.

In the RGB color system, \[s_i=kr_i\quad i=1,2,3.\]

In the HSI color system, \begin{align*} s_1&=r_1\\ s_2&=r_2\\ s_3&=kr_3. \end{align*}

The HSI transformation is simpler, but converting between the RGB and HSI color spaces can be costly.

3.2   Color complements

Analogous to the grayscale negatives.

In the RGB color system, \[s_i=1-r_i\quad i=1,2,3.\]

3.3   Histogram equalization

In the HSI color system, the intensity ($r_3$) is histogram equalized.

3.4   Smoothing and sharpening

In the RGB color system, averaging spatial filters and the Laplacian operator can be applied to each color component.

In the HSI color system, averaging spatial filters and the Laplacian operator can be applied to the intensity component leaving the hue and saturation components unmodified.

4   Color transformations using multiple components

By extending the per-color-component transformation, we can obtain \[ s_i=T_i(r_1, r_2, \cdots, r_n)\quad i=1,2,\cdots,n \] where all input color components participate in a transformation for the transformed color component $i$.

4.1   Color slicing

You can highlight a specific range of colors using color slicing.

Slicing by a cube with its center color $\mathbf{a}$ and width $W$ can be done using \[ s_i= \begin{cases} 0.5&\text{if}\left[\lvert r_j-a_j\rvert>\frac{W}{2}\right]_{\text{any }1\leq j\leq n}\\ r_i&\text{otherwise} \end{cases}\quad i=1,2,\cdots,n. \]

Slicing by a sphere with its center color $\mathbf{a}$ and radius $R_0$ can be done using \[ s_i= \begin{cases} 0.5&\text{if}\sum_{j=1}^n(r_j-a_j)^2>R_0^2\\ r_i&\text{otherwise} \end{cases}\quad i=1,2,\cdots,n. \]

Note that 0.5 represent a neutral grayscale color.

4.2   Color segmentation

Color segmentation can be done using equations similar to those for color slicing: \[ s_i= \begin{cases} 0&\text{if}\left[\lvert r_j-a_j\rvert>\frac{W}{2}\right]_{\text{any }1\leq j\leq n}\\ 1&\text{otherwise} \end{cases}\quad i=1,2,\cdots,n \] and \[ s_i= \begin{cases} 0&\text{if}\sum_{j=1}^n(r_j-a_j)^2>R_0^2\\ 1&\text{otherwise} \end{cases}\quad i=1,2,\cdots,n. \]

5   Exercise: RGB-to-CMY conversion in ArcGIS Pro

C = 255-"R"
M = 255-"G"
Y = 255-"B"

Rnew = 255-"C"
Gnew = 255-"M"
Bnew = 255-"Y"

6   Exercise: RGB-to-HSI conversion in ArcGIS Pro

I = ("R"+"G"+"B")/3/255
theta = ACos(1/2*(("R"-"G")+("R"-"B"))/SquareRoot(("R"-"G")**2+("R"-"B")*("G"-"B")))/3.14159*180
H = Con("G">="B", "theta", 360-"theta")
Hnorm = "H"/360
S = 1-Con(("R"<="G") & ("R"<="B"), "R",  Con(("G"<="R") & ("G"<="B"), "G", "B"))/"I"/255

7   Exercise: HSI-to-RGB conversion in ArcGIS Pro

hcase = Con("H"<120, 1, Con("H"<240, 2, 3))
c1 = "I"*(1-"S")
c21 = "I"*(1+"S"*Cos("H"/180*3.14159)/Cos((60-"H")/180*3.14159))
c22 = "I"*(1+"S"*Cos(("H"-120)/180*3.14159)/Cos((60-"H"+120)/180*3.14159))
c23 = "I"*(1+"S"*Cos(("H"-240)/180*3.14159)/Cos((60-"H"+240)/180*3.14159))
c2 = Con("hcase"==1, "c21", Con("hcase"==2, "c22", "c23"))
c3 = 3*"I"-("c1"+"c2")
R1 = Con(IsNull("S"), 0, Con(IsNull("H"), "I", Con("hcase"==1, "c2", Con("hcase"==2, "c1", "c3"))))
G1 = Con(IsNull("S"), 0, Con(IsNull("H"), "I", Con("hcase"==1, "c3", Con("hcase"==2, "c2", "c1"))))
B1 = Con(IsNull("S"), 0, Con(IsNull("H"), "I", Con("hcase"==1, "c1", Con("hcase"==2, "c3", "c2"))))
R255 = "R1"*255
G255 = "G1"*255
B255 = "B1"*255

8   Exercise: Smoothing

  1. Convert RGB to HSI
  2. Use the Weighted average tool to smooth the intensity
    • Neighborhood width: 3
    • Neighborhood height: 3
    • Weights: 1 2 1 2 4 2 1 2 1
  3. Convert HSI back to RGB
  4. Composite RGB bands

9   Exercise: Sharpening

  1. Convert RGB to HSI
  2. Use the Raster Calculator to convert I from $[0, 1]$ to 8 bits
    • "I"*255
  3. Use the Sharpen using the Laplacian tool to smooth the 8-bit intensity
    • Consider diagonal directions
  4. Use the Raster Calculator to convert I back to $[0, 1]$
    • "I"/255
  5. Convert HSI back to RGB
  6. Composite RGB bands

Have you noticed extra saturated colors? Check the maximum S.

10   Exercise: Extracting clouds using color segmentation

  1. Create a mask first using sphere color segmentation (close to white)
    Con(("R"-255)**2+("G"-255)**2+("B"-255)**2 <= 10**2, 1, 0)
  2. Convert the raster output to polygon
  3. Delete non-cloud features (gridcode = 0)
  4. Delete small features (potentially noises) (Shape_Area <= 100)
  5. Delete remaining non-cloud features visually
  6. Extract by mask
  7. Colors may not look right, but that’s because of color stretching

11   Exercise: Removing clouds using color segmentation

  1. Create a mask first using sphere color segmentation (close to white)
    Con(("R"-255)**2+("G"-255)**2+("B"-255)**2 <= 10**2, 1, 0)
  2. Convert the raster output to polygon
  3. Use the definition query to display features with gridcode = 1 only
  4. Find non-cloud features visually and assign 0 to their gridcode
  5. Clear the definition query
  6. Delete big cloud features (gridcode = 1 and Shape_Area > 100)
  7. Extract by mask