目次

パラメータ操作

 GBCに使われているM64282には、8個のレジスタがあります。



 8個のレジスタへの設定値により、GBCの動作が変化します。

 これらのパラメータ設定と操作をまとめます。


register_0

 レジスタ0には、次の2つのパラメータが含まれます。  Zパラメータは、GBCが出力する電圧の基準を補正します。  ビットの組合わせと内容は、以下です。  Oパラメータは、GBCが出力する電圧に加えるオフセットを  指定します。この値の調整で、電圧範囲を上下させます。  6ビットのうち、O5が符号ビットで0にすると負の値になります。  1にすると正の値か0になります。  組み合わせは、以下です。

register_1

 レジスタ1には、次の3つのパラメータが含まれます。  Nパラメータは、エッジ強調を制御します。  VHパラメータは、垂直、水平等のエッジ検出モードを指定します。  組み合わせは、以下です。  エッジを指定すると、下記のように上下、左右で画像データが  クリップされます。  (Positiveは、通常の出力で比較のため左に描いています。)  Gパラメータは、センサー値を増幅する場合の利得  (=Gain)を指定します。  チップ内部には、フォトセンサーとアンプが含まれて  いるので、アンプ利得Gを設定するのがGパラメータ  です。  M64282は、人工網膜チップなので、利得は対数指定  になります。人間がもつ痛覚、圧覚等と同じように  対数での設定値になります。

register_2 register_3

 レジスタ2,3には、露光時間を決めるC0、C1パラメータが含まれます。  レジスタは、ともに8ビットですが、露光時間の分解能が異なります。  レジスタ3は、0〜255で、分解能が16マイクロ秒です。  128を設定すると、2,048マイクロ秒=2.048ミリ秒になります。  レジスタ2は、0〜255で、分解能が16マイクロ秒x256=4.096ミリ秒です。  レジスタ2、3は、マイクロ秒単位で時間を決め、  次のように設定します。   *(reg+2) = (exposure time) / 256 ;   *(reg+3) = (exposure time) % 256 ;

register_4 register_5 register_6

 レジスタ4、5、6には、各々P、M、Xパラメータが含まれます。  P、M、Xの3パラメータは、フィルタリングで利用します。  PとMの組み合わせは、下図を参照すると分かり易いでしょう。  Mパラメータの右についているN、E、W、SはNorth East West South  の略です。  点Pを中心に上下左右にある点の値に、数値を乗算して  (これを変調と呼びます)点Pの値を決めます。  エッジ強調とエッジ拡張では、得られる画像が異なります。  Xパラメータは、エッジ拡張のときに、Mパラメータに代わって利用されます。  組み合わせは、次のようになります。  7通りの組み合わせがあります。 (エッジ拡張)   垂直エッジ拡張では、画面の上下と下のみの拡張ができます。   このときは、画像として有効なピクセル数とライン数は    128ピクセルx121ライン    128ピクセルx123ライン   となります。    128ピクセルx121ラインの場合は、注目点の上下2点    のピクセル値の平均を、注目点のピクセル値から減算します。    さらにエッジ強調の係数α(レジスタ7で設定する値)を乗算    します。    128ピクセルx123ラインの場合は、注目点の下の点    のピクセル値を、注目点のピクセル値から減算します。   水平エッジ拡張では、画面の左右の拡張ができます。   このときは、画像として有効なピクセル数とライン数は    128ピクセルx123ライン   注目点の左右2点のピクセル値の平均を、注目点のピクセル値から   減算します。さらにエッジ強調の係数α(レジスタ7で設定する値)   を乗算します。   2次元拡張では、画面の上下左右の拡張ができます。   このときは、画像として有効なピクセル数とライン数は    128ピクセルx121ライン   注目点の上下左右4点のピクセル値の平均を、注目点のピクセル値   から減算します。さらにエッジ強調の係数α(レジスタ7で設定する値)   を乗算します。 (エッジ強調)   垂直エッジ強調では、注目点の上下2点のピクセル値の平均を   注目点のピクセル値から減算した値を求めます。   この値にエッジ強調の係数α(レジスタ7で設定する値)を乗算   し、注目点のピクセル値から減算します。   このときは、画像として有効なピクセル数とライン数は    128ピクセルx121ライン   水平エッジ強調では、注目点の左右2点のピクセル値の平均を   注目点のピクセル値から減算した値を求めます。   この値にエッジ強調の係数α(レジスタ7で設定する値)を乗算   し、注目点のピクセル値から減算します。   このときは、画像として有効なピクセル数とライン数は    128ピクセルx123ライン   2次元エッジ強調では、画面の上下左右の拡張ができます。   このときは、画像として有効なピクセル数とライン数は   2次元エッジ強調では、注目点の上下左右4点のピクセル値の平均を   注目点のピクセル値から減算します。この値に、エッジ強調の係数α   (レジスタ7で設定する値)を乗算し、注目点のピクセル値から減算   します。   このときは、画像として有効なピクセル数とライン数は    128ピクセルx121ライン

register_7

 レジスタ7には、次の3つのパラメータが含まれます。  Eパラメータは、エッジの強調と拡張に関係する数値を扱います。  E3ビットを0にすると、エッジ強調になります。  通常は0として、強調モードにしておきます。  エッジの強調と拡張では、以下の組み合わせで比率設定します。  Iパラメータは、ネガポジ反転で出力したい場合に1にします。  Vパラメータは、出力電圧の比較基準電圧を指定します。  Vパラメータで、比較基準電圧を指定すると、暗いときと  明るいときで、出力電圧が極端に異なる場合の補正が可能  になります。

パラメータ決定フロー

 8個のレジスタにパラメータを設定する値を決定するには  次の手順を踏めばよいでしょう。
  1. 露光時間指定
  2. ノーマルかネガポジ反転指定
  3. 受光感度設定
  4. エッジ強調かエッジ拡張指定
  5. 基準電圧指定
  6. オフセット電圧指定
 このフローに従っても、8個のレジスタに設定する値を正確に  決めるのは面倒な作業です。  そこで、数値の設定やモードを選択することで、設定値を生成  するTcl/Tkで動作するアプリを作成しました。  設定画面は、以下です。  ソースコードは、以下です。  判定処理が多いため長いですが、やっていることは単純です。 --------------------------------------------------------------------- #! /usr/local/bin/wish . configure -width 250 -height 250 wm title . "GBC parameters" ####################################### # set default file name and values ####################################### set theFileName "params" set tFileName $theFileName foreach i {0 1 2 3 4 5 6 7} { set Reg($i) 0 set dReg($i) "00000000" label .lblReg$i -textvariable dReg($i) } ####################################### # objects ####################################### label .lblParam -text "Parameters" label .lblHn -text "upper nibble" label .lblLn -text "lower nibble" label .lblCnt -text "Exposure time(us)" label .lblEmode -text "Edge" label .lblEdge -text "Edge direction" label .lblGain -text "Select Gain" label .lblGainL -text "Gain(dB) low" label .lblGainH -text "Gain(dB) high" label .lblEratio -text "Enhancement Ratio" label .lblInverse -text "Inverse" label .lblVref -text "Vref" label .lblOffsetS -text "Offset sign" label .lblOffset -text "Offset value(mv)" label .lblCal -text "Calibration" set fcount 0 entry .edtCnt -textvariable fcount spinbox .sbxValH -value {"0000" "0001" "0010" "0011" "0100" "0101" "0110" "0111" "1000" "1001" "1010" "1011" "1100" "1101" "1110" "1111"} spinbox .sbxValL -value {"0000" "0001" "0010" "0011" "0100" "0101" "0110" "0111" "1000" "1001" "1010" "1011" "1100" "1101" "1110" "1111"} spinbox .sbxEmode -value {"Enhancement" "Extraction"} spinbox .sbxEdge -value {"None" "Horizontal" "Vertical" "2 Dimension"} spinbox .sbxGain -value {"low" "high"} spinbox .sbxGainL -value {"14.5" "15.5" "17.0" "18.5" "20.0" "21.5" "23.0" "24.5" "26.0" "29.0" "32.0" "35.0" "38.0" "41.0" "45.5" "51.5"} spinbox .sbxGainH -value {"20.0" "21.5" "23.0" "24.5" "26.0" "27.5" "29.0" "30.5" "32.0" "35.0" "38.0" "41.0" "44.0" "47.0" "51.5" "57.5"} spinbox .sbxEratio -value {50 75 100 125 200 300 400 500} spinbox .sbxInverse -value {"Normal" "Inverse"} spinbox .sbxVref -value {"0.0" "0.5" "1.0" "1.5" "2.0" "2.5" "3.0" "3.5"} spinbox .sbxOffsetS -value {"Positive" "Negative"} spinbox .sbxOffset -from 0 -to 992 -increment 32 spinbox .sbxCal -value {"No" "Positive" "Negative"} .sbxValH configure -state readonly -width 4 .sbxValL configure -state readonly -width 4 .sbxEmode configure -state readonly -width 12 .sbxEdge configure -state readonly -width 10 .sbxGain configure -state readonly -width 10 .sbxGainL configure -state readonly -width 4 .sbxGainH configure -state readonly -width 4 .sbxEratio configure -state readonly -width 4 .sbxInverse configure -state readonly -width 10 .sbxVref configure -state readonly -width 4 .sbxOffsetS configure -state readonly -width 10 .sbxOffset configure -state readonly -width 6 .sbxCal configure -state readonly -width 10 button .btnSave -text "Save" -command { # create file name set theFileName [format "%s.txt" $tFileName] # open set fd_out [open $theFileName "w"] # save foreach i {0 1 2 3 4 5 6 7} { puts $fd_out [format "0x%02x ; %s" $Reg($i) $dReg($i)] } # close close $fd_out } button .btnSet -width 6 -text "Set" -command { # set register 0 set Reg(0) [get0Reg 0] set dReg(0) "[getBinary [expr $Reg(0) / 16]][getBinary [expr $Reg(0) % 16]]" # set register 1 set Reg(1) [get1stReg 0] set dReg(1) "[getBinary [expr $Reg(1) / 16]][getBinary [expr $Reg(1) % 16]]" # set register 7 set Reg(7) [get7thReg 0] set dReg(7) "[getBinary [expr $Reg(7) / 16]][getBinary [expr $Reg(7) % 16]]" } button .btnCSet -width 6 -text "set C" -command { set val [.edtCnt get] # tk_messageBox -type ok -message "$val" # separate set Reg(2) [expr $val % 256] set Reg(3) [expr $val / 256] # show set dReg(2) "[getBinary [expr $Reg(2) / 16]][getBinary [expr $Reg(2) % 16]]" set dReg(3) "[getBinary [expr $Reg(3) / 16]][getBinary [expr $Reg(3) % 16]]" } button .btnPSet -width 6 -text "set P" -command {setVal 4} button .btnMSet -width 6 -text "set M" -command {setVal 5} button .btnXSet -width 6 -text "set X" -command {setVal 6} button .btnExit -text "Exit" -command "exit" ####################################### # functions or procedures ####################################### proc get0Reg {x} { # set register 0 set val 0 # calibration set tmp [.sbxCal get] if { $tmp == "Positive" } { set val [expr $val + 128] } if { $tmp == "Negative" } { set val [expr $val + 64] } # offset set tmp [.sbxOffsetS get] if { $tmp == "Positive" } { set val [expr $val + 32] } set tmp [.sbxOffset get] set val [expr $val + ($tmp / 32)] # return $val } proc get1stReg {x} { set val 0 # Edge mode set tmp [.sbxEmode get] if { $tmp == "Extraction" } { set val [expr $val + 128] } # Edge direction set tmp [.sbxEdge get] if { $tmp == "Horizontal" } { set val [expr $val + 32] } if { $tmp == "Vertical" } { set val [expr $val + 64] } if { $tmp == "2 Dimension" } { set val [expr $val + 96] } # gain set tmp [.sbxGain get] if { $tmp == "low" } { set tmp [.sbxGainL get] if { $tmp == "15.5" } { set val [expr $val + 1] } if { $tmp == "17.0" } { set val [expr $val + 2] } if { $tmp == "18.5" } { set val [expr $val + 3] } if { $tmp == "20.0" } { set val [expr $val + 4] } if { $tmp == "21.5" } { set val [expr $val + 5] } if { $tmp == "23.0" } { set val [expr $val + 6] } if { $tmp == "24.5" } { set val [expr $val + 7] } if { $tmp == "26.0" } { set val [expr $val + 8] } if { $tmp == "29.0" } { set val [expr $val + 9] } if { $tmp == "32.0" } { set val [expr $val + 10] } if { $tmp == "35.0" } { set val [expr $val + 11] } if { $tmp == "38.0" } { set val [expr $val + 12] } if { $tmp == "41.0" } { set val [expr $val + 13] } if { $tmp == "45.5" } { set val [expr $val + 14] } if { $tmp == "51.5" } { set val [expr $val + 15] } } if { $tmp == "high" } { set tmp [.sbxGainH get] set val [expr $val + 16] if { $tmp == "21.5" } { set val [expr $val + 1] } if { $tmp == "23.0" } { set val [expr $val + 2] } if { $tmp == "24.5" } { set val [expr $val + 3] } if { $tmp == "26.0" } { set val [expr $val + 4] } if { $tmp == "27.5" } { set val [expr $val + 5] } if { $tmp == "29.0" } { set val [expr $val + 6] } if { $tmp == "30.5" } { set val [expr $val + 7] } if { $tmp == "32.0" } { set val [expr $val + 8] } if { $tmp == "35.0" } { set val [expr $val + 9] } if { $tmp == "38.0" } { set val [expr $val + 10] } if { $tmp == "41.0" } { set val [expr $val + 11] } if { $tmp == "44.0" } { set val [expr $val + 12] } if { $tmp == "47.0" } { set val [expr $val + 13] } if { $tmp == "51.5" } { set val [expr $val + 14] } if { $tmp == "57.5" } { set val [expr $val + 15] } } # result return $val } proc get7thReg {x} { # set register 2 set val 0 # Enhancement Ratio set tmp [.sbxEratio get] if { $tmp == 75 } { set val [expr $val + 16] } if { $tmp == 100 } { set val [expr $val + 32] } if { $tmp == 125 } { set val [expr $val + 48] } if { $tmp == 200 } { set val [expr $val + 64] } if { $tmp == 300 } { set val [expr $val + 80] } if { $tmp == 400 } { set val [expr $val + 96] } if { $tmp == 500 } { set val [expr $val + 112] } # Inverse set tmp [.sbxInverse get] if { $tmp == "Inverse" } { set val [expr $val + 8] } # Vref set tmp [.sbxVref get] if { $tmp == "0.5" } { set val [expr $val + 1] } if { $tmp == "1.0" } { set val [expr $val + 2] } if { $tmp == "1.5" } { set val [expr $val + 3] } if { $tmp == "2.0" } { set val [expr $val + 4] } if { $tmp == "2.5" } { set val [expr $val + 5] } if { $tmp == "3.0" } { set val [expr $val + 6] } if { $tmp == "3.5" } { set val [expr $val + 7] } # return $val } proc getBinary {x} { set res0 [expr $x / 8] set x [expr $x % 8] set res1 [expr $x / 4] set x [expr $x % 4] set res2 [expr $x / 2] set x [expr $x % 2] set res3 $x set result "$res0$res1$res2$res3" return $result } proc setVal {x} { global Reg dReg # get address set adr $x # get upper nibble set valH [.sbxValH get] # get lower nibble set valL [.sbxValL get] # calculate value set tmp [expr [getVal $valH] * 16 + [getVal $valL]] set Reg($adr) $tmp # show value as binary format set dReg($adr) "$valH$valL" } proc getVal {x} { # clear set result 0 # convert foreach e $x { set result [expr 2 * $result + $e] } # } ####################################### # window area placing ####################################### grid .lblParam -column 0 -row 0 grid .lblReg0 -column 0 -row 1 grid .lblReg1 -column 0 -row 2 grid .lblReg2 -column 0 -row 3 grid .lblReg3 -column 0 -row 4 grid .lblReg4 -column 0 -row 5 grid .lblReg5 -column 0 -row 6 grid .lblReg6 -column 0 -row 7 grid .lblReg7 -column 0 -row 8 grid .btnSave -column 1 -row 9 grid .btnExit -column 0 -row 11 grid .lblHn -column 1 -row 0 grid .lblLn -column 1 -row 1 grid .lblCnt -column 1 -row 3 grid .sbxValH -column 2 -row 0 grid .sbxValL -column 2 -row 1 grid .edtCnt -column 2 -row 3 grid .btnCSet -column 2 -row 4 grid .btnPSet -column 2 -row 5 grid .btnMSet -column 2 -row 6 grid .btnXSet -column 2 -row 7 grid .lblCal -column 3 -row 0 grid .lblOffsetS -column 3 -row 1 grid .lblOffset -column 3 -row 2 grid .lblEmode -column 3 -row 3 grid .lblEdge -column 3 -row 4 grid .lblGain -column 3 -row 5 grid .lblGainL -column 3 -row 6 grid .lblGainH -column 3 -row 7 grid .lblEratio -column 3 -row 8 grid .lblInverse -column 3 -row 9 grid .lblVref -column 3 -row 10 grid .sbxCal -column 4 -row 0 grid .sbxOffsetS -column 4 -row 1 grid .sbxOffset -column 4 -row 2 grid .sbxEmode -column 4 -row 3 grid .sbxEdge -column 4 -row 4 grid .sbxGain -column 4 -row 5 grid .sbxGainL -column 4 -row 6 grid .sbxGainH -column 4 -row 7 grid .sbxEratio -column 4 -row 8 grid .sbxInverse -column 4 -row 9 grid .sbxVref -column 4 -row 10 grid .btnSet -column 4 -row 11 ---------------------------------------------------------------------  Windows、UNIX、MacのどのOSでも動作します。 WindowsのDOS窓では、次のように入力します。 >wish85 gbcpara.tcl{enter}  露光時間は、数値で指定します。  パラメータP、M、Xは上位、下位の4ビットを決めてから  ボタンをクリックします。  パラメータは、Saveボタンのクリックでテキストファイル  params.txtに保存されます。

パラメータ設定例

 M64282の内部レジスタへのパラメータを設定例が、データシート  に掲載されていたので、紹介します。 Positive  (z1,z0)=(1,0)  基準電圧より大きい値の補正を加えるように指定。  N=0       エッジ強調のモード指定。  (vh1,vh0)=(0,0) 実際には、エッジ強調はしません。  E3=0       エッジ強調のモード指定。  I=0        通常出力(ネガポジ反転なし)。 Inverter  (z1,z0)=(1,0)  基準電圧より大きい値の補正を加えるように指定。  N=0       エッジ強調のモード指定。  (vh1,vh0)=(0,0) 実際には、エッジ強調はしません。  E3=0       エッジ強調のモード指定。  I=1        ネガポジ反転出力。 Horizontal Enhanced mode  (z1,z0)=(1,0)  基準電圧より大きい値の補正を加えるように指定。  N=0       エッジ強調のモード指定。  (vh1,vh0)=(0,1) 水平エッジモード指定。  E3=0       エッジ強調指定。  I=0        通常出力(ネガポジ反転なし)。 Horizontal Enhanced and Invert mode  (z1,z0)=(1,0)  基準電圧より大きい値の補正を加えるように指定。  N=0       エッジ強調のモード指定。  (vh1,vh0)=(0,1) 水平エッジモード指定。  E3=0       エッジ強調指定。  I=1        ネガポジ反転出力。 Horizontal Extened mode  (z1,z0)=(0,0)  基準電圧の補正なし。  N=0       エッジ強調のモード指定。  (vh1,vh0)=(0,1) 水平エッジモード指定。  E3=1       エッジ拡張指定。  I=0        通常出力(ネガポジ反転なし)。 Horizontal Extened and Invert mode  (z1,z0)=(0,0)  基準電圧の補正なし。  N=0       エッジ強調のモード指定。  (vh1,vh0)=(0,1) 水平エッジモード指定。  E3=1       エッジ拡張指定。  I=1        ネガポジ反転出力。 Vertical Enhanced mode  (z1,z0)=(1,0)  基準電圧より大きい値の補正を加えるように指定。  N=0       エッジ強調のモード指定。  (vh1,vh0)=(1,0) 水平エッジモード指定。  E3=0       エッジ強調指定。  I=0        通常出力(ネガポジ反転なし)。 Vertical Enhanced and Invert mode  (z1,z0)=(1,0)  基準電圧より大きい値の補正を加えるように指定。  N=0       エッジ強調のモード指定。  (vh1,vh0)=(1,0) 水平エッジモード指定。  E3=0       エッジ強調指定。  I=1        ネガポジ反転出力。 Vertical Extened mode  (z1,z0)=(0,0)  基準電圧の補正なし。  N=1       エッジ強調のモード指定。  (vh1,vh0)=(1,0) 水平エッジモード指定。  E3=1       エッジ拡張指定。  I=0        通常出力(ネガポジ反転なし)。 Vertical Extened and Invert mode  (z1,z0)=(0,0)  基準電圧の補正なし。  N=1       エッジ強調のモード指定。  (vh1,vh0)=(1,0) 水平エッジモード指定。  E3=1       エッジ拡張指定。  I=1        ネガポジ反転出力。 2 Dimension Enhanced mode  (z1,z0)=(1,0)  基準電圧より大きい値の補正を加えるように指定。  N=1       エッジ強調のモード指定。  (vh1,vh0)=(1,1) 2次元エッジモード指定。  E3=0       エッジ強調指定。  I=0        通常出力(ネガポジ反転なし)。 2 Dimension Enhanced and Invert mode  (z1,z0)=(1,0)  基準電圧より大きい値の補正を加えるように指定。  N=1       エッジ強調のモード指定。  (vh1,vh0)=(1,1) 2次元エッジモード指定。  E3=0       エッジ強調指定。  I=1        ネガポジ反転出力。 2 Dimension Extened mode  (z1,z0)=(0,0)  基準電圧の補正なし。  N=1       エッジ強調のモード指定。  (vh1,vh0)=(1,1) 2次元エッジモード指定。  E3=1       エッジ拡張指定。  I=0        通常出力(ネガポジ反転なし)。 2 Dimension Extened and Invert mode  (z1,z0)=(0,0)  基準電圧の補正なし。  N=1       エッジ強調のモード指定。  (vh1,vh0)=(1,1) 2次元エッジモード指定。  E3=1       エッジ拡張指定。  I=1        ネガポジ反転出力。 Positive  (z1,z0)=(1,0)  基準電圧より大きい値の補正を加えるように指定。  N=0       エッジ強調のモード指定。  (vh1,vh0)=(0,0) 実際には、エッジ強調はしません。  E3=0       エッジ強調のモード指定。  I=0        通常出力(ネガポジ反転なし)。 Negative  (z1,z0)=(0,1)  基準電圧より小さい値の補正を加えるように指定。  N=0       エッジ強調のモード指定。  (vh1,vh0)=(0,0) 実際には、エッジ強調はしません。  E3=0       エッジ強調のモード指定。  I=1        ネガポジ反転出力。 Vertical PM mode  (z1,z0)=(0,0)  基準電圧の補正なし。  N=0       エッジ強調のモード指定。  (vh1,vh0)=(0,0) エッジモード指定なし。  E3=0       エッジ強調指定。  I=0        通常出力(ネガポジ反転なし)。 Vertical Enhanced mode  (z1,z0)=(1,0)  基準電圧より大きい値の補正を加えるように指定。  N=0       エッジ強調のモード指定。  (vh1,vh0)=(1,0) 水平エッジモード指定。  E3=0       エッジ強調指定。  I=0        通常出力(ネガポジ反転なし)。 Vertical Extened mode  (z1,z0)=(0,0)  基準電圧の補正なし。  N=1       エッジ強調のモード指定。  (vh1,vh0)=(1,0) 水平エッジモード指定。  E3=1       エッジ拡張指定。  I=0        通常出力(ネガポジ反転なし)。 2 Dimension Enhanced mode  (z1,z0)=(1,0)  基準電圧より大きい値の補正を加えるように指定。  N=1       エッジ強調のモード指定。  (vh1,vh0)=(1,1) 2次元エッジモード指定。  E3=0       エッジ強調指定。  I=0        通常出力(ネガポジ反転なし)。 2 Dimension Extened mode  (z1,z0)=(0,0)  基準電圧の補正なし。  N=1       エッジ強調のモード指定。  (vh1,vh0)=(1,1) 2次元エッジモード指定。  E3=1       エッジ拡張指定。  I=0        通常出力(ネガポジ反転なし)。
目次

inserted by FC2 system