Pages: [1]   Go Down

### AuthorTopic: Linear and Gamma Correction - Posterizing Question  (Read 2666 times)

#### rcolombari

• Newbie
• Offline
• Posts: 4
##### Linear and Gamma Correction - Posterizing Question
« on: September 26, 2012, 10:32:45 AM »

Hi to all,
I am new to this forum. My name is Roberto and I am an electronic engineer from Italy.

Well, let go to the question.

I am writing an image processing application focused on astro pictures. The pecularity of these kind of images is that they come out from calibrating tools with a very narrow histogram that needs to be stretched.

I have implemented a common algorithm for histogram stretching that foresees a linear stretching plus a gamma correction based on inputs given by the users.
Basically, the inputs are: Black/White Red/Green/Blue Thresholds (0-255) and gamma (0.01-6.99).

As you can see I am working in a 24bpp scenario (8 per channel).

I am making some unit tests of my program versus PSCS5 and I am noticing that my tool produces a very annoying posterizing. Basically, I took an image and I applied both on my tool and PSCS5 (in 24bpp mode):

• 8 for black on all channels
• 38 for white on all channels
• 1.02 for gray on all channels

My tool produces an output histograms with several peeks while PSCS5 spread the information in a little better way so that posterizing is not present. Now my question is: after the linear and logarithmic stretching is there some other algorithm that I need to apply as PSCS5 does? I cannot find anything around the net.

Thanks a lot.

Regards, Roberto
Logged

#### Sareesh Sudhakaran

• Sr. Member
• Offline
• Posts: 546
##### Re: Linear and Gamma Correction - Posterizing Question
« Reply #1 on: September 26, 2012, 11:14:36 AM »

Welcome to the forum, Roberto!

Since you are interpolating data there are infinite ways in which to do it. Even a 'famous' algorithm can be interpreted in many ways.

Maybe you've considered this already, but posterization is usually caused by unavailability of tones. To 'hide' it, a dithering algorithm is usually applied (See my newbie article here).

If you have applied all the available dithering algorithms and are still facing an issue, then you might want to change your math base (another newbie article here, I'm afraid).

Hope this helps for starters.
Logged
Get the Free Comprehensive Guide to Rigging ANY Camera - one guide to rig them all - DSLRs to the Arri Alexa.

#### rcolombari

• Newbie
• Offline
• Posts: 4
##### Re: Linear and Gamma Correction - Posterizing Question
« Reply #2 on: September 26, 2012, 11:21:18 AM »

Hi  Sareesh,

The algorithm that I implemented (for sake of easiness I will just copy the red channel one) is:

Linear
A) slopeR = 255 / (WhiteR - BlackR)
B)
For i As Integer = 0 To (WhiteR - BlackR - 1)
newranger(BlackR + i) = i * slopeR
Next

C)
For i As Integer = WhiteR To 255
newranger(i) = 255
Next

Logaritmic:
A)
For i As Integer = 0 To 255
gammarangeR(i) = Math.Max(Math.Min(255, 255 * Math.Pow(i / 255, 1 / Me.GrayRStretch)), 0)
Next

Combination of both:
A)
For counter = 0 To 255
finalR(counter) = gammarangeR(Math.Floor(newrangeR(counter) + 0.5))
Next

Output:
A)
For counter = 0 To Me.OriginalUnsizedStream.Length - 1 Step 4
rgbValues(counter + 2) = Math.Floor(finalR(Me.OriginalUnsizedStream(counter + 2)) + 0.5)
Next

I didn't applied any dithering. I am going to read your article in while.

Best regards,
Roberto
Logged

#### lfeagan

• Full Member
• Offline
• Posts: 196
##### Re: Linear and Gamma Correction - Posterizing Question
« Reply #3 on: September 26, 2012, 12:23:52 PM »

Thanks for the nice info Sareesh.
Logged
Lance

Nikon: D700, D800E, PC-E 24mm f/3.5D ED, PC-E 45mm f/2.8D ED, PC-E 85mm f/2.8D, 50mm f/1.4G, 14-24 f/2.8G ED, 24-70 f/2.8G ED, 70-200 f/2.8G ED VR II, 400mm f/2.8G ED VR
Fuji: X-Pro 1, 14mm f/2.8, 18mm f/2.0, 35mm f/1.4

#### rcolombari

• Newbie
• Offline
• Posts: 4
##### Re: Linear and Gamma Correction - Posterizing Question
« Reply #4 on: September 26, 2012, 03:31:14 PM »

Premise: I cannot work easily in VB with 48bpp images so I have to live with 24bpp.
Basically, even if an image is 48bpp VB transform it in a 24bpp one.
_____________________________

Anyway, I have been partially (60/70%) able to get rid of posterization in the following way.

I created 3 look-up-tables (one for each channel) that I used to transform from 24bpp RGB to 48bpp RGB.
I created other 3 look-up-tables (one for each channel) that I used to transform from 48bpp RGB to 24bpp RGB
I did it in this way:

From 24bpp to 48bpp:

c1r = 12.92 * 65535.0
c1g = 12.92 * 65535.0
c1b = 12.92 * 65535.0

For i = 0 To 65535
rr = i / 65535.0
rg = i / 65535.0
rb = i / 65535.0
If (1.055 * rr - 0.055 <= 0) Then
rr = c1r * rr
lut48to24r(i) = rr >> 8
Else
rr = (1.055 * rr - 0.055) * 65535.0
lut48to24r(i) = rr >> 8
End If
If (1.055 * rg - 0.055 <= 0) Then
rg = c1g * rg
lut48to24g(i) = rg >> 8
Else
rg = (1.055 * rg - 0.055) * 65535.0
lut48to24g(i) = rg >> 8
End If
If (1.055 * rb - 0.055 <= 0) Then
rb = c1b * rb
lut48to24b(i) = rb >> 8
Else
rb = (1.055 * rb, fb - 0.055) * 65535.0
lut48to24b(i) = rb >> 8
End If
Next[/left]

Linear Stretching and Gamma Correction on 48bpp

From 48bpp to 24bpp:

For i = 0 To 65535
Dim j As Integer = 1

While lut48to24r(i) = lut48to24r(i + j) And i + j <= 65535
cumr = cumr + ((i + j) / 100)
j += 1
If i + j > 65535 Then Exit While
End While
cumr = cumr + (i / 100)
lut24to48r(lut48to24r(i)) = Math.Floor((100 * cumr / (j + 1)) + 0.5)
k = k + 1
i += j - 1
cumr = 0
Next

For i = 0 To 65535
Dim j As Integer = 1

While lut48to24g(i) = lut48to24g(i + j) And i + j <= 65535
cumg = cumg + ((i + j) / 100)
j += 1
If i + j > 65535 Then Exit While
End While
cumg = cumg + (i / 100)
lut24to48g(lut48to24g(i)) = Math.Floor((100 * cumg / (j + 1)) + 0.5)
k = k + 1
i += j - 1
cumg = 0
Next

For i = 0 To 65535
Dim j As Integer = 1

While lut48to24b(i) = lut48to24b(i + j) And i + j <= 65535
cumb = cumb + ((i + j) / 100)
j += 1
If i + j > 65535 Then Exit While
End While
cumb = cumb + (i / 100)
lut24to48b(lut48to24b(i)) = Math.Floor((100 * cumb / (j + 1)) + 0.5)
k = k + 1
i += j - 1
cumb = 0
Next

Posterization is now acceptable but performances went down. I need to enhance the above code.
I will try to implement as well dithering.

Regards,
Roberto Colombari

Logged

#### LenR

• Full Member
• Offline
• Posts: 162
##### Re: Linear and Gamma Correction - Posterizing Question
« Reply #5 on: September 26, 2012, 04:01:34 PM »

... now where did I put that Budweiser?
Logged

#### rcolombari

• Newbie
• Offline
• Posts: 4
##### Re: Linear and Gamma Correction - Posterizing Question
« Reply #6 on: September 26, 2012, 04:09:02 PM »

?
Logged

#### lfeagan

• Full Member
• Offline
• Posts: 196
##### Re: Linear and Gamma Correction - Posterizing Question
« Reply #7 on: September 26, 2012, 10:06:34 PM »

Yikes! I haven't seen VB code for nearly 15 years. Good luck with your performance improvements.
Logged
Lance

Nikon: D700, D800E, PC-E 24mm f/3.5D ED, PC-E 45mm f/2.8D ED, PC-E 85mm f/2.8D, 50mm f/1.4G, 14-24 f/2.8G ED, 24-70 f/2.8G ED, 70-200 f/2.8G ED VR II, 400mm f/2.8G ED VR
Fuji: X-Pro 1, 14mm f/2.8, 18mm f/2.0, 35mm f/1.4

#### Sareesh Sudhakaran

• Sr. Member
• Offline
• Posts: 546
##### Re: Linear and Gamma Correction - Posterizing Question
« Reply #8 on: September 26, 2012, 11:00:18 PM »

You're welcome, Lance!
Logged
Get the Free Comprehensive Guide to Rigging ANY Camera - one guide to rig them all - DSLRs to the Arri Alexa.

#### Sareesh Sudhakaran

• Sr. Member
• Offline
• Posts: 546
##### Re: Linear and Gamma Correction - Posterizing Question
« Reply #9 on: September 26, 2012, 11:02:28 PM »

Yes, the last time I used VB, too, was in 1999!

Roberto, just a suggestion, but have you tried Python? Python's list based system is brilliant for the kind of iterations involved in large data streams. This is why it is used in programs like Nuke, etc.

E.g., the entire for-else-else system takes 10s of lines in VB, but only 1 line in Python. It's poetry for image processing. The biggest advantage is it has excellent math support, unlike VB.