Ad
Ad
Ad
Pages: [1]   Bottom of Page
Print
Author Topic: Linear and Gamma Correction - Posterizing Question  (Read 1931 times)
rcolombari
Newbie
*
Offline Offline

Posts: 4


« on: September 26, 2012, 09:32:45 AM »
ReplyReply

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 Offline

Posts: 547


WWW
« Reply #1 on: September 26, 2012, 10:14:36 AM »
ReplyReply

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 Offline

Posts: 4


« Reply #2 on: September 26, 2012, 10:21:18 AM »
ReplyReply

Hi  Sareesh,
thanks for your reply.

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 Offline

Posts: 208



« Reply #3 on: September 26, 2012, 11:23:52 AM »
ReplyReply

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 Offline

Posts: 4


« Reply #4 on: September 26, 2012, 02:31:14 PM »
ReplyReply

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 Offline

Posts: 139



« Reply #5 on: September 26, 2012, 03:01:34 PM »
ReplyReply

... now where did I put that Budweiser?
Logged
rcolombari
Newbie
*
Offline Offline

Posts: 4


« Reply #6 on: September 26, 2012, 03:09:02 PM »
ReplyReply

?
Logged
lfeagan
Full Member
***
Offline Offline

Posts: 208



« Reply #7 on: September 26, 2012, 09:06:34 PM »
ReplyReply

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 Offline

Posts: 547


WWW
« Reply #8 on: September 26, 2012, 10:00:18 PM »
ReplyReply

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 Offline

Posts: 547


WWW
« Reply #9 on: September 26, 2012, 10:02:28 PM »
ReplyReply

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.

Anyway, I'm reading your code now. Thank you for sharing it.
Logged

Get the Free Comprehensive Guide to Rigging ANY Camera - one guide to rig them all - DSLRs to the Arri Alexa.
Pages: [1]   Top of Page
Print
Jump to:  

Ad
Ad
Ad