Navigation

Related Articles

Back to Latest Articles

C# Tutorial: How To Use Log Transformation on Images


Andraz Krzisnik
C# Tutorial: How To Use Log Transformation...

What is Log Transformation Anyway?

Log transformation in image processing is a part of gray level transformations. It works by transforming each pixel individually. It is usually the most useful for a use on grayscale images, hence the gray level transform expression.

So the first thing we need to do is transform our image into grayscale. I have already created a separate article on how we can convert our image into grayscale format.

Log transformation spreads the range of darker values and compresses the range of lighter shades. To achieve the opposite we would need to use inverse log transform.

Equation for Log Transform

We will be changing our pixels based on an equation that looks like

s = c log(r + 1)

We are changing each pixel individually. So “s” and “r” variables represent pixel intensity values of output and input values respectively. “c” is a constant that controls our logarithmic curve, or in other words, it changes the expansion and compression of the ranges of darker and lighter intensity values.

That “+1” in the log function is added in case that the intensity value in the input is 0, we still get a usable value.

Let’s Make Our Image Grayscale

There’s already an article that covers how to change images into grayscale format, which goes a little bit more indepth of what’s going on.

Here’s the function we will be using in this example

private Bitmap Grayscale(Bitmap img)
{
    int w = img.Width;
    int h = img.Height;

    BitmapData sd = img.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    int bytes = sd.Stride * sd.Height;
    byte[] buffer = new byte[bytes];
    byte[] result = new byte[bytes];
    Marshal.Copy(sd.Scan0, buffer, 0, bytes);
    img.UnlockBits(sd);
    int current = 0;
    for (int y = 0; y < h; y++)
    {
        for (int x = 0; x < w; x++)
        {
            current = y * sd.Stride + x * 4;
            int gray = (int)(buffer[current] * 0.0722 + buffer[current + 1] * 0.7152 + buffer[current + 2] * 0.2126);
            for (int i = 0; i < 3; i++)
            {
                result[current + i] = (byte)gray;
            }
            result[current + 3] = 255;
        }
    }
    Bitmap resimg = new Bitmap(w, h);
    BitmapData rd = resimg.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
    Marshal.Copy(result, 0, rd.Scan0, bytes);
    resimg.UnlockBits(rd);
    return resimg;
}

Log Transformation Function

private Bitmap LogTransform(Bitmap img, int constant)
{
    int w = img.Width;
    int h = img.Height;

    img = Grayscale(img);

    BitmapData sd = img.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    int bytes = sd.Stride * sd.Height;
    byte[] buffer = new byte[bytes];
    byte[] result = new byte[bytes];
    Marshal.Copy(sd.Scan0, buffer, 0, bytes);
    img.UnlockBits(sd);
    int current = 0;
    for (int y = 0; y < h; y++)
    {
        for (int x = 0; x < w; x++)
        {
            current = y * sd.Stride + x * 4;
            for (int i = 0; i < 3; i++)
            {
                result[current + i] = (byte)(constant * Math.Log10(buffer[current + i] + 1));
            }
            result[current + 3] = 255;
        }
    }
    Bitmap resimg = new Bitmap(w, h);
    BitmapData rd = resimg.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
    Marshal.Copy(result, 0, rd.Scan0, bytes);
    resimg.UnlockBits(rd);
    return resimg;
}

Download Entire Project Here

Download Project

 

Related Articles

Frequency Domain Filtering

How To Use Notch Filters – C# Guide

We can use notch filters for attenuating frequencies on custom locations across the frequency map. But for that we will need to utilize all of the knowledge we’ve acquired...

Posted on by Andraz Krzisnik
Region Segmentation Using Superpixels

How To Make SLIC Superpixel Algorithm With C#

SLIC superpixel segmentation is a modern operation for reducing irrelevant detail for shortening computational time in further processing.

Posted on by Andraz Krzisnik