All-About調査室 Annex

ふと湧いた疑問や巷を漂うウワサを全部アバウト~に調査・検証
<OCNから漂着 流浪の調査室>

12bit RAWでは露出マージンは無いと思えっ!

2014-12-24 19:09:30 | RAWをいぢるっ!

14bit RAWでは現像時に+1EV露出補正した程度なら、
まだ色調調整出来る程度の階調余裕が十分あることを前回示した。
では、12bit RAWではどうなのか?

使用VBAプログラムは後回しに、結果から紹介する。
30x30pixを1ブロックとしてRGB同値で0~4095の全階調段階を螺旋状に
12bitのNEFに書き込んで、これをPictureNX-DでPictureStyle=ニュートラル、
ホワイトバランス=晴天で露出補正なしで現像したものは下のようになった。(1/8縮小)

同様に露出補正+1EVでも現像し、前回の14bit RAWの時と同様に、
それぞれのRGBヒストグラムで階調が70~89と110~129の20階調段階の範囲の
ピクセル数を調べて、階調段階数の20とブロックのピクセル数の900で割り
それぞれの階調範囲での、8bit画像1階調段階あたりの平均RAW階調数とした。


このカメラではRもさることながら、BもGに対して感度がかなり低い。
晴天ホワイトバランスではその補正のためにBでもかなり階調が消費されている。

12bit RAWでは露出補正ナシならば十分色調補正できるが、
白トビを嫌ってあらかじめアンダー露出で撮影して、現像時にプラス補正で適正化する
というワザは、階調余裕を考慮するとほぼ無理ということになる。

なお、RAWファイルへのパターン書き込みVBAプログラムは・・・

Private Type Temp_Byte
    TB(1) As Byte
End Type

Private Type Int_Data
    ID As Integer
End Type
Sub GraySpiral_12bit()

Dim DataMap(63, 63) As Integer
Dim LineIData() As Integer
Dim LineBData() As Byte
Dim MI As String * 2
Dim FType As String * 3
Dim St_Offset As Long, Start_Ad As Long
Dim Y_Step As Long, Data_Ad As Long
Dim X As Integer, Y As Integer
Dim N As Integer
Const End_N As Integer = 4095
Dim S As Integer, W As Integer

'for Change Order
Dim A As Int_Data
Dim B As Temp_Byte
Dim C As Byte

Folder$ = Range("B2").Value
File$ = Range("B3").Value
Open Folder$ & "\" & File$ For Binary As #1
Get #1, , MI
Close #1
If MI <> "MM" And MI <> "II" Then End
FileCopy Folder$ & "\" & File$, Folder$ & "\GSp_" & File$
FType = Right(File$, 3)
If FType = "NEF" Or FType = "nef" Then
    BT = 1.5
    ReDim LineBData(2879)
Else
    BT = 2
    ReDim LineIData(1919)
End If

File$ = Folder$ & "\GSp_" & File$

Sr_Width% = Range("B5").Value   '←センサ横Pix数
Sr_Height% = Range("B6").Value  '←センサ縦Pix数
St_Offset = Range("B7").Value   '←StripOffset
Offset_X% = (Sr_Width% - 1920) \ 2
Offset_Y% = (Sr_Height% - 1920) \ 2
Y_Step = Sr_Width% * BT
Start_Ad = St_Offset + Y_Step * Offset_Y% + ((Offset_X% * BT) \ 2) * 2

X = 31
Y = 31
N = 0
S = 1
W = 1

DataMap(X, Y) = N
Do
    For K% = 1 To W
        N = N + 1
        If N > End_N Then Exit Do
        X = X + S
        DataMap(X, Y) = N
    Next K%
    For K% = 1 To W
        N = N + 1
        If N > End_N Then Exit Do
        Y = Y + S
        DataMap(X, Y) = N
    Next K%
    W = W + 1
    S = -1 * S
Loop

If FType <> "NEF" And FType <> "nef" And MI = "MM" Then
    For X = 0 To 63
        For Y = 0 To 63
            GoSub Change_Order
        Next Y
    Next X
End If

On Error GoTo Retry
Write_Data:
Y = 0
While Y < 1920
    If FType <> "NEF" And FType <> "nef" Then
        For X = 0 To 1919
            LineIData(X) = DataMap(X \ 30, Y \ 30)
        Next X
    Else
        For X = 0 To 2877 Step 3
            LineBData(X) = DataMap(X \ 45, Y \ 30) \ 16
            LineBData(X + 1) = (DataMap(X \ 45, Y \ 30) Mod 16) * 16 _
                              + DataMap((X + 1) \ 45, Y \ 30) \ 256
            LineBData(X + 2) = DataMap((X + 1) \ 45, Y \ 30) Mod 256
        Next X
    End If
    Range("B4").Value = "Writing " & Y
    Do
        Data_Ad = Start_Ad + Y_Step * Y
        Open File$ For Binary As #1
        If FType <> "NEF" And FType <> "nef" Then
            Put #1, Data_Ad + 1, LineIData()
            'Offset値は0~、VBのアクセスアドレスは1~
        Else
            Put #1, Data_Ad + 1, LineBData()
        End If
        Close #1
        Y = Y + 1
    Loop While Y Mod 30 > 0
Wend

Range("B4").Value = "Finish"
Range("A1").Select
Exit Sub

'***** Sub-Routine ****************
Change_Order:
'Big Endianファイルの場合にデータのバイトオーダを入れ替える
    A.ID = DataMap(X, Y)
    LSet B = A
    C = B.TB(0)
    B.TB(0) = B.TB(1)
    B.TB(1) = C
    LSet A = B
    DataMap(X, Y) = A.ID
Return

'------
Retry:
'FileCopy未完了で失敗した時はリトライする
    Close #1
    If Err.Number <> 75 Then
        Range("B4").Value = "Error #" & Err.Number
        Exit Sub
    End If
    DoEvents
    Err.Clear
Resume Write_Data

End Sub

これに以下のデータ記述欄を作って実行する。
(データの記入方法や非圧縮RAWだけしか扱えないのは14bitの時と同じ)
ワークシート上にボタンを作ってマクロ登録しておくとプログラム起動が楽になる

なお、プログラムでは対象ファイルの素性はチェックしていないので、
12bit非圧縮RAWかどうかは使う側が確認する必要がある。
(元ファイルを「GSp_」から始まるファイル名でコピーして使うので、
元ファイルを破壊することは無いのだが・・・)
また、DNGの非圧縮では12bitデータを2Byte(16bit)整数値で、ごく普通に保存する。
・・・なので上位4bitは常にALLゼロのムダ領域が生じるのに対して、
NEFの12bit非圧縮のデータ保存は2つの12bitデータ(計24bit)を3Byteの領域に
3個のByteデータとして格納する、特殊な形式を使用しているのが普通である。
プログラムでは対象ファイルの拡張子がNEFか否かだけで、
この保存方法を切り替えている。
万一、別ルールの保存方法を使うNEFがあったら、結果は予定外のものになる。
またDNGに関して(14bitRAWでも同じなんだけど)、Foveonセンサーなど
非ベイヤー配列素子から作られたRAWを変換したDNGでも予定外の結果になるだろう。
(非ベイヤー配列素子のRAWはいぢったことが無いので、どうなるかはわからない)

参考:
12bit RAWに二つのデータ値1234、3456が書き込まれる場合
これらのデータを16進数で表現すると4D2、D86となり(12bitでは最大16進数でFFF)
これをByte(16進数2桁)ごとにファイル格納されて行く



最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。