HW2, Computer problem, Part (b)
Histogram equalization 
EECS 203A, Digital Image Processing. UCI. Fall 2004
Nasser Abbasi

Read the image file, cat.raw, and generate the histogram table, then the probability density function PDF table, then the cumulative density function CDF table. Then scan the image and generate new pixel gray level values by a lookup to the CDF.

Clear["Global`*"];

Now set current directory to where the image is (same folder as this note book) and read the image file

SetDirectory[
        ToFileName[
          Extract["FileName" /. 
              NotebookInformation[EvaluationNotebook[]], {1}, 
            FrontEnd`FileName]]];

     
fileName = "cat.raw";
L = 256;
rows = 480; 
cols = 640;
data = 
        FastBinaryFiles`ReadListBinary[fileName, 
          Byte];
 nPixels = Length[data]; 
Print["Max pixel value in data=", 
        Max[data]];
Print["Min pixel value in data=", Min[data]];

Now that the image is read into data, we display it before processing it.

ListDensityPlot[
        Reverse[Partition[data, cols]], Mesh -> False, 
        Frame -> False, ImageSize -> {rows, cols}, 
        PlotRange -> All, AspectRatio -> Automatic];

\(\(makeHistogram[data_] := 
        Module[{h, i, r, nPixels, L}, 
L = 
            256; 
Print["npixels=", 
            nPixels = Length[data]]; 
h = 
            Table[{0, 0}, {i, 
                L}]; 
Print["h table size=", 
            Dimensions[h]]; 
For[i = 1, 
            i ≤ nPixels, 
            i = i + 1, 
{
\  (*\(If[
                    Mod[i, 10000] == 0, 
                    Print["data[", i, "]=", 
                      data[[
                        i]]]];\)*) 
\ 
              r = data[[i]] + 
                  1; 
\ 
              h[[r, 2]] = 
                h[[r, 2]] + 
                  1;
}
]; 
Return[h];
];\)\)

makePDF[h_, nPixels_] := 
        Module[{i, pdf, L}, 
L = 
            Length[h]; 
pdf = 
            Table[{0, 0}, {i, L}]; 
For[i = 1, 
            i ≤ L, 
            i = i + 1, 
 pdf[[i, 
                  2]] = 
                h[[i, 2]]/nPixels;
]; 
Return[
            pdf];
];

makeCDF[pdf_] := 
        Module[{cdf, L, i}, 
L = 
            Length[pdf]; 
cdf = 
            Table[{0, 0}, {i, 
                L}]; 
cdf[[1, 
              1]] = 
            pdf[[1, 
              1]]; 

For[i = 2, i ≤ L, 
            i = i + 1, 
 cdf[[i, 
                  2]] =  
                pdf[[i, 2]] + 
                  cdf[[i - 1, 
                    2]];
]; 
Return[cdf];
];

\(\(\( (*Print\ the\ histogram*) \)\(
\)\( (*TableForm[
        h]*) \)\(
\)\(\(h = 
        makeHistogram[data];\)

    ListPlot[h[[All, 2]], 
      PlotLabel -> {"Histogram of cat.raw image, num pixels=", \ \ Length[data]}]\)\)\)

\(\(pdf = 
        makePDF[h, 
          Length[data]];\)
 (*Print\ the\ PDF*) \)
\(ListPlot[pdf[[All, 2]], 
      PlotLabel -> {"PDF of cat.raw image, num pixels=", \ \ nPixels}]
\)
\(\(cdf = 
        makeCDF[pdf];\)
 (*Print\ the\ CDF*) \)
\(ListPlot[cdf[[All, 2]], 
      PlotLabel -> {"CDF of cat.raw image, num pixels=", \ \ nPixels}]\)

(*Now generate new image*) 
nPixels = Length[data];

    s = Table[0, {i, nPixels}];

    For[i = 1, i ≤ nPixels, 
      i = i + 1, 
r = 
        data[[i]] + 
          1; 
s[[i]] = 
        Round[ cdf[[r, 
              2]] (L - 
                1) ];
]

Print["Max pixel value in s=", 
        Max[s]];
Print["Min pixel value in s=", Min[s]];

(*Now display the new image*) 

ListDensityPlot[Reverse[Partition[s, cols]], 
        Mesh -> False, Frame -> False, 
        ImageSize -> {rows, cols}, PlotRange -> All, 
        AspectRatio -> Automatic];

h = 
        makeHistogram[s];

    ListPlot[h[[All, 2]], 
      PlotLabel -> {"Histogram of transformed cat.raw image, num \
pixels=",   Length[s]}]

pdf = makePDF[h, Length[s]];
\(ListPlot[pdf[[All, 2]], 
      PlotLabel -> {"PDF of transformed cat.raw image, num pixels=", \ \ nPixels}]\)

cdf = makeCDF[pdf];
\(ListPlot[cdf[[All, 2]], 
      PlotLabel -> {"CDF of transformed cat.raw image, num pixels=", \ \ nPixels}]\)

\(\(\(
\)\( (*\ 
      Now\ write\ the\ new\ image\ to\ file\ *) \)\(
\)\(\(fileName = "cat_histogram_equalized.raw";\)\(
\)
    \(strm = 
        FastBinaryFiles`OpenWriteBinary[fileName];\)\(
\)
    \(FastBinaryFiles`WriteBinary[strm, s, Byte];\)\(
\)
    \(Close[strm];\)\(
\)\(
\)
    \( (*\(That\ is\ all\ folks ... \)\(.\)\ *) \)\)\)\)

Conclusion

With histogram equalization applied, we see that new image contains more gray levels than the original level. Looking at generated plots of the new image histrogram and PDF and CDF we see from the CDF that the distribution of gray levels is uniform in the new image.