省型旧形国電の残影を求めて

戦前型旧形国電および鉄道と変褪色フィルム写真を中心とした写真補正編集の話題を扱います。他のサイトでは得られない、筆者独自開発の写真補正ツールや補正技法についても情報提供しています。写真補正技法への質問はコメント欄へどうぞ

良い写真が撮れなかった飯田線クモハ51200 (蔵出し画像)

 こちらはクモハ51200です。この車はなかなか良い形式写真が撮れず、非常に心残りだった車です。ただ最後の最後、1983年の6月に訪問した時に、伊那松島区で運用とダイヤを確認して、ここならうまい形式写真が撮れそうだととある駅で待ち構えていたら、別の車が... 急遽故障で運用を外れたのでした... 嗚呼!

f:id:yasuo_ssi:20220322173046j:plain

クモハ51200 (静ママ) 1975.5 飯田駅

 上の写真は本車との最初の遭遇でした。

f:id:yasuo_ssi:20220322165912j:plain

クモハ51200 (静ママ) 1979.8 伊那松島機関区

 2-4位側です。ご覧のように側面サボ受けが他車とは異なり、幕板についています。横須賀線時代は側面サボ受けはなく、そのあと北松本に転属し、その後伊那松島と北松本で何度も行き来をしたようなので、大糸線仕様のようです。ただその後長く伊那松島にいたにもかかわらず、移設されませんでした。

f:id:yasuo_ssi:20220322165958j:plain

クモハ51200 (静ママ) 1977.7 伊那松島機関区

 頭が隠れていますが1-3位側です。

f:id:yasuo_ssi:20220322170106j:plain

クモハ51200 (静ママ) 1979.8 伊那松島機関区

f:id:yasuo_ssi:20220322170154j:plain

クモハ51200 (静ママ) 1979.8 伊那松島機関区

 前面幌枠は原形のままです。なお、前面運転台窓は末期はHゴム化されたようですが、私は写真が撮れませんでした。

f:id:yasuo_ssi:20220322170219j:plain

クモハ51200 (静ママ) 1978.1 豊橋駅

本車の車歴です。

1934.2.27 川崎車両製造 (モハ43002) → 1934.6.26 使用開始 大ミハ → (不明) 座席撤去 → 1948.11.24 座席整備 → 1950.2.17 更新修繕I 吹田工 → 1950.9.16 東チタ → 1955.7.18 更新修繕II 豊川分工 → 1960.4.20 東フナ → 1964.2.19 改造 大船工 (クモハ51200) → 1965.7.1 長キマ → 1966.5.27 静ママ → 1968.9.25 長キマ → 1969.9.28 静ママ → 1984.1.18 廃車 (静ママ) 

 本車は1934年にモハ43002として川崎車輌で製造されました。トップナンバーの43001は戦災廃車となっていますので、戦後まで残ったクモハ43の中では最も若番でした。

 戦後は元モハ51と交換で上京し横須賀線へ行きます。本車は偶数車であったこともあり、かなり後の方まで横須賀線で活躍しますが、そのため残念なことに1964年に3扉化され、クモハ51200となります。しかし最後までPS-11パンタグラフを維持しました。改造翌年、新性能化で横須賀線を離れ、大糸線の20m化要員として北松本に転属しますが、翌年伊那松島へ。しかし北松本と伊那松島で玉突きされた後、1969年以降15年間は飯田線北部を中心に活躍しました。あまり車輛の調子が良くなかったのかもしれません。しかし、1978年の豊橋区の80系化でも、MT-15を備えた不利な条件にもかかわらずなぜか生き残って飯田線旧形国電の最後まで使われました。

Linux上 GIMP2.10.x で Flatpak を使わずに Python-fu を有効にする

 以前、LinuxGIMP をインストールするときに、Flatpak を使うと簡単に Python-fu を復活させることができると書きました。しかし、Flatpak で動くアプリケーションは、サンドボックスの中で動くので、他のアプリケーションとの連携が難しくなるとの指摘がされています。

discuss.pixls.us こちらのディスカッションで指南されているのは、GIMP起動前に、ラウンチャープログラムを起動させてからGIMPを起動させてPython-fu を復活させるという方法です。

以下のサイトに行き、

github.comgimp-python2-overlay-launcher-ubuntu22.04.AppImage をダウンロードします。これを適当なフォルダに移動します。

 そして、GIMPを使用する前に、このラウンチャーを起動してから GIMP を起動すると、apt を使ってGIMPをインストールしたとしても、Python-fu のサポートが復活するということです。

 このラウンチャーに対し、リンクを作ってメニューから起動できるようにすると便利でしょう。

 以下にビデオによるインストラクションもあります(ただし英語)。

www.gimp-forum.net

 

PlayOnLinux を使ってみる

 Wine を使うと、古いバージョンなら Microsoft Office も動くという話をネットで見かけました。手持ちに、以前使っていたけれども今パソコンから外している Office 2010 があるので試しに Wine 上でインストールを試したところ、見事に途中でコケました。

 まあ、そんなにうまい話が転がっているわけはないな、と思っていましたが、また検索を掛けてみると、Play on Linux という Wine のフロントエンドプログラムを使うと、インストールできるというような情報があります。ただ、日本語環境で Play on Linux を使うには、単純にインストールしただけではだめなようです。以下に、日本語環境における Play on Linux のインストールの仕方の指南がありましたので、それに従ってインストールします。

zenn.dev

 要は、日本語翻訳ファイルに問題があり、以下からダウンロードして入れ替えればよい、ということです。

github.com 上の記事には、「どうか不整合が起きませんようにと手を合わせながらPlayOnLinuxを起動します」とありますが、インストールボタンを押して対応ソフトウェアを検索する際 % 表示が出れば OK です。永遠にくるくる回って終わらない場合は、 % 表示が出ません。ただ、初回検索をかけるときはかなり長時間かかりますので、ネット、マシン環境にもよると思いますが、30〜40分ぐらいは放置してください。一旦データが取得できれば、すぐ対応ソフトウェアが検索できるようになります。検索窓からキーワードを入れて以下のように検索してください。

 

PlayOnLinux のインストールメニュー

 ちなみに、以下のサイトに PlayOnLinux の対応ソフトウェアのリストがあります。

www.playonlinux.com

 それから、Microsoft Office 2010 をインストールする方法は、以下のインドの方のビデオにありました。なお、インストールには 32 bit版を使って下さい。64 bit 版は非対応です。

www.youtube.com PlayOnLinux だけではなく、winbind もインストールする必要があるようです。

sudo apt install winbind

でインストールします。winbind とは WindowsActive Directory と情報をやり取りするのに必要なプログラムのようです。

 なお、これでインストールを試みたところ、Wine 3.03 が予めインストールしておいた Wine と別にインストールされます。

 ただ、インストールすると、一つはWinetricks が設定されていないせいか、インストーラーの一部の文字が文字化けします。オプションを選択するときは判じ物です。一旦Windows上でインストーラーを走らせ、途中経過を画面キャプチャしておいたほうが良いかもしれません。さらに "Error in POL_Shortcut" というようなエラーメッセージが出ます。とりあえず無視して進むとインストールが終わります。

 途中でエラーメッセージは出ましたが、とりあえず起動してみると起動できました。なお、PlayOnLinuxMicrosoft Office 2016 まで対応しています。PlayOnLinux は、Wine で使えるようにするための複雑な設定を色々代行してくれるようです。またおそらくソフトウェアによっては、最新版の Wine ではむしろ動かない、というようなことがあるのかもしれません。

 なお、PlayOnLinux を使ってインストールすると、既存の Wine とは別の場所にプログラムがインストールされます。ホームディレクトリの下に、.PlayOnLinux というディレクトリが作成され、その下にインストールされます。 ./PlayOnLinux/winprefix/ソフトウェア名/drive_c というディレクトリが作成され、その下にソフトウェアごとに仮想の C ドライブが作成され、その下にソフトウェアの本体がインストールされます。 おそらくソフトウェアごとに、別のバージョンの Wine & 環境を提供する必要性からと思われます。PlayOnLinux を使うのはあくまで最新版 Wine で素直に動かない場合に限定したほうが良いようです。

 インストールした Office ですが、今私の環境で iBus を使っているためなのか、ちょっと日本語入力が不便です。Excel や Power Point はさほど問題がありませんが、Word でかなり入力にタイムラグが出ます。とても常用する気にはなれません。基本、Libre Office で文書を作成し、互換性確保のための最後の整形に Word を使うという使い方になるかと思います。

ImageJ / Python プログラミング Tips: 画像 bit 深度・最大値変換サンプルプログラム

 先日、ImageJ上における 32bit 画像の扱いについて記事を書きましたが、それを基に、画像の bit 深度を変換したり、32bit画像の場合、最大値を変更したりするサンプルプログラムを書いてみました。意図通りちゃんと変換してくれます。

 

---------------

# Converting image bit depth and max value
# (c) 2023 Ohnishi, Yasuo
from ij import IJ, ImagePlus
from ij import WindowManager as WM
from ij.io import DirectoryChooser, OpenDialog
from ij.plugin import ChannelSplitter, Duplicator
from ij.process import ImageConverter
from ij.gui import GenericDialog
from loci.plugins import BF
import os
import sys
from org.python.core import codecs
codecs.setDefaultEncoding('utf-8')

def selectChannel(): 
    # dialog of selecting target channel for mask upper & lower threshold
    gd = GenericDialog("Channel Selection")
#    scolorCh = ["Lightness", "Luminosity", "Red","Green","Blue"]
    scolorCh = ["Red","Green","Blue"]
    gd.addChoice("Select Target Channel", scolorCh, scolorCh[0])
    gd.showDialog()

    colorCh =  gd.getNextChoice()
    if gd.wasCanceled():
        colorCh =  "None"

    return str(colorCh)
#--
def inputParm(Mode, L_Max): 
    # dialog of input parameters
    gd = GenericDialog("Input Parameters")
    gd.addMessage("Original Image Bitdepth: " + Mode + "  Max Lightness: " + str(L_Max))
    imageFormats = ["8-bit","16-bit","32-bit"]
    gd.addChoice("Select Convert Format", imageFormats, imageFormats[0])
    maxValues = ["1.0","256","65535","16777215"]
    gd.addChoice("Select Max Value (only available in 32bit)", maxValues, maxValues[2])

    gd.showDialog()

    imageFormat =  gd.getNextChoice()
    maxValue =  gd.getNextChoice()
    if gd.wasCanceled():
        imageFormat =  "None"
        maxValue =  "None"
    if Mode == "8-bit" and imageFormat == "16-bit":
        multiplyFactor = 256
    elif Mode == "8-bit" and imageFormat == "32-bit":
        multiplyFactor = float(maxValue) / 255
    elif Mode == "16-bit" and imageFormat == "32-bit":
        multiplyFactor = float(maxValue) / 65535
    else:
        multiplyFactor = 1.0

    return str(imageFormat), multiplyFactor

#--
window = WM.getActiveWindow()
if not window:
    od = OpenDialog("Choose a file")
    folder = od.getDirectory()
    filename = od.getFileName()
    if filename:
        path = folder + filename
        IJ.log(path)
        IJ.log(folder)
        IJ.log(filename)
# Always Open file with Bio-format Plugin
        imps = BF.openImagePlus(folder + filename) 
        imp0 = imps[0] #imp0: Original Image 
        imp0.show()
    else:
        IJ.showMessage("File is not selected.")
else: # target image is already open
    imp0 = IJ.getImage()
    imagename = imp0.getTitle()
    try:
        folder = imp0.getOriginalFileInfo().directory
    except:
        folder = IJ.getDirectory("Output_directory")
# get number of channels (Mono or RGB?)
stackSize = imp0.getStackSize() # stackSize=1: Mono / 3: RGB
# get bitdepth
bitdepth = imp0.getBitDepth()
if bitdepth == 8:
    Mode = "8-bit"
elif bitdepth ==16:
    Mode = "16-bit"
elif bitdepth ==32:
    Mode = "32-bit"
# get Max value
L_Max = imp0.getProcessor().getMax()

if stackSize > 1:
    colorch = selectChannel()
    impsCh = ChannelSplitter.split(imp0) #Channel Splitting of imp0
    if colorch == "Red":
        imp1 = impsCh[0]
    elif colorch == "Green":
        imp1 = impsCh[1]
    elif colorch == "Blue":
        imp1 = impsCh[2]
    elif colorch == "None":
        sys.exit()
else:
    imp1 = Duplicator().run(imp0)
imp1.show()
imp0.hide()
imageFormat, multiplyFactor = inputParm(Mode, L_Max)
if imageFormat == "8-bit":
    ImageConverter(imp1).convertToGray8()
elif imageFormat == "16-bit":
    ImageConverter(imp1).convertToGray16()
elif imageFormat == "32-bit":
    ImageConverter(imp1).convertToGray32()
imp1.getProcessor().multiply(multiplyFactor)
if L_Max > 65536:
    L_Max = 16777215.999
elif L_Max > 256:
    L_Max = 65535.999
elif L_Max > 1.0:
    L_Max = 255.999
else:
    L_Max = 1.0
maxDispRange = L_Max * multiplyFactor
imp1.setDisplayRange(0.0, maxDispRange)
imp1.getProcessor().setLut(None)
imp1.updateAndDraw()
imp0.close()

---------------

 def selectChannnel でチャンネル選択ダイアログを、def inputParm でパラメータ入力ダイアログを定義しています。

 このプログラムを ImageJ 上で走らせるには、File → New → Script で新しいスクリプトエディタを開いて、そこに上の内容を貼り付けて走らせてください。言語は当然 Python です。

 動かすと、まずファイル選択ダイアログが出ますので、読み込むファイルを選択します。次に、チャンネル指定ダイアログが出るので、

チャンネル指定ダイアログ

 Red, Green, Blue のうちどれかを選びます。なお、モノチャンネルのグレースケール画像では以上のダイアログは表示されません。

 チャンネルを選択すると、下記のように変換指定ダイアログが出ます。変換指定ダイアログの上の部分に、現在の画像のフォーマット (bit深度及び値の最大値) が表示されます。表示が緑になっているのは、Green チャンネルを選択したので、緑のLUTがかかっているためです。

変換指定ダイアログ

 そしてその下の部分で、変換するフォーマット (8-bit, 16-bit, 32-bit のいずれか)、および変換する最大値 (1.0, 256, 65535, 16777215 のいずれか) を選択します。但し、最大値の変換は、32-bit を選んだときのみに有効で、8-bit を選んだ場合は 255, 16-bit の場合は 65535 に最大値は自動的に決定されます。

 これを選んでOKボタンを押すと、指定されたフォーマットに画像が変換されます。プログラム的には、imageFormat という変数に変換先の bit 深度が指定されていすので、それをもとに、ImageConverter を使って bit 深度を変更します。さらに multiplyFactor という変数に、ユーザの指定に従って、明度値を変更する係数を計算して取得し、画像の明度値に multiplyFactor を掛けて変更します。それと同時に、bit 深度や明度の最大値を変換したときに、真っ黒になったり真っ白になるのを防ぐために、setDisplayRange メソッドを使って表示が変わらないようにしました。そのため、変換しても特に見た目は変わりません (但し、その際にLUTを外すので、チャンネルの色は消えます)。しかし以下のようにヒストグラムを取ってみると、値が変換されているのが分かります。

変換後の画像のヒストグラムを取って値が変換されているのを確認

 前回、setDisplayRange メソッドで、表示する明度範囲を調節するのではないかと書きましたが、その通りでした。これで値を指定することで、どんな値に変換しようが見た目を変わらずに維持することができます。

--------------

[関連記事]

yasuo-ssi.hatenablog.com

 

yasuo-ssi.hatenablog.com

yasuo-ssi.hatenablog.com

 

 

クモハ11117が解体?

 最近、拙ブログのクモハ11117の記事のアクセス数が急に増えました。ひょっとしてと思って検索してみると以下のような記事が....

ameblo.jp

 どうなるのかわかりませんが、コロナ禍でJR西日本の経営事情もよくないので、あまり楽観視はできないかと...

ImageJ / Python プログラミング Tips: ImageJ Fiji 独自の API があった

 ImageJ の Generil Dialog の書き方の情報を色々検索しているうちに、ImageJ には Fiji ディストリビューション独自の API が存在することに気づきました。Fiji で使われている ImageJ は実は ImageJ そのものではなく、ImageJ2 というプログラムです。ImageJ2 は ImageJ との 100% 下位互換性を確保しつつ、さらにプラスアルファの機能を加えた派生プログラムです。本家の ImageJ も進化しているので、ImageJ2 は ImageJ の後継という訳ではありません。

 とはいえ、今まで ImageJ2の独自機能を使っていたわけではないので、単に ImageJ 本家だと手動でインストールや設定を加えなければならないライブラリやマクロを、あらかじめ便利にプレインストールしてくれる、単なるディストリビューション・パッケージぐらいの認識でした。

 ところが、Generic Dialog の機能に関する情報を漁っているうちに、Fiji 独自の API があることに気づきました。

 その一覧が以下のページです。Fiji 拡張パッケージの一覧があります。

javadoc.scijava.org 中には、loci.plugins など 追加プラグインを入れれば、本家 ImageJでも使えるパッケージもあるようですが...

 

 Generil Dialog にも拡張があります。

javadoc.scijava.org

javadoc.scijava.org

 多分、パッケージ名のどこかに fiji がついているものが、Fiji 独自のパッケージのようです。それ以外にもあるかもしれませんが...

 これから何か使えるものがないか見てみるつもりです。

ImageJ / Python プログラミング Tips: ImageJにおける32bit画像の扱い

 今まで ImageJ上で32bit画像を扱うことがなかったのでよく分からなかったのですが、プログラミング上の必要があり、今回いろいろと調べてみました。

 まず、以前にも書きましたが、16bit以上の画像の場合、1枚のImageProsessorには1チャンネルの画像しか収容できません。そしてRGBフルカラー画像の場合は、RGB、3つのチャンネルに関する3枚のImageProcessorを持ったスタック構造のImagePlusとして扱われます。これをTIFFファイルに落とすと、RGBの3ページを持ったTIFFファイルとして保存され、ImageJのみが読める特有のタグ情報に、チャンネル識別情報が記録されます。このファイルを再度ImageJで読み込むとRGBフルカラー画像として表示できますが、他の画像処理ソフトでは、ImageJ特有のタグ情報が読めないので、3ページのグレースケール画像を持ったTIFFファイルとしか読めません。したがってこのTIFFファイルをフルカラー画像として表示させるには、RGB合成を当該画像処理ソフト上でやり直す必要があります。

 ImageJ上の32bit画像上での画像データは、正負符号付(Signed)の浮動小数点データとなります。これはどういうことを示すかというと、負の値を取ることができるとともに、最大値も固定されない、ということです。ですので、0~16,777,216のデータであってもよいし、0~1.0のデータでもあったもよい、はたまた-1.0~+1.0のデータであってもよいということです。ともあれ有効桁数は32 bit になります。
 ちなみに、32bit TIFFデータを0~1.0の形で保存したものであっても、0~16,777,215の形で保存したものであっても、いずれも同じように読めます。ただし、ImageJ上で、0~16,777,215のデータを、最大値16,777,216で割り、0~1.0のデータに直した場合、表示上は真っ暗になってしまいます。これをTIFFデータに保存しなおし、再度読み込みなおしても真っ暗のままです。しかし、ImageJで0~1.0の形で保存した32bit TIFF ファイルをGIMPで読み込み、GIMP上で再度32bit TIFF として保存しなおしたものを ImageJで読むと、正しく表示されるので、TIFFファイルのどこかに表示できる明度の最大値・最小値を記したタグ情報があり、それを基に ImageJ 上で表示の仕方を決めているものと思われます。そしてGIMPで保存しなおしたときにその表示明度範囲データを更新するので、GIMPで保存しなおすと、画像データを変換前と同じように表示できるようになるものと思われます。ただそのタグ情報は、あくまで表示の仕方のみを決めているのであって、データ上の扱いを制約するものではないと思われます。

 なお、ImageJ の API 上、8, 16 bit の画像を 32 bit 画像に変換するには、

ImageConverter(imagePlus).convertToGray32()

 を使うか、もしくは、ImageProcessor に対して、

convertToFloatProcessor()

 メソッドを使います。

 また、ImageJ の UI 上から変換するときは、

Image の Type 変換

メニューの [Image] → [Type] → [32 bit] を選択します。

 なお、8bitや16bitの画像を32bitに変換したとしても、画像データは全く変わりません(これは、8 bit画像を 16 bit 画像に変換しても同じ。一方 bit 深度を落として変換する場合は、bit 深度に合わせて最大値を落として自動調整)。この点は、GUI上で変換しても、プログラムからAPIを使って操作しても同じです。例えば、0~65535の16bitデータを32bitに変換しても、0~65535のままです。このデータを0.0~1.0に変えたければ、さらに65535で割るという操作が必要です。また計算上、マイナスの値になっても、正負符号付なので、そのままマイナス値のデータは保持されます。

 なお、データを0.0 ~ 1.0 の小数浮動点データに直したときに、ImageJ 上で真っ暗に表示されてしまうことに対する対策ですが、明度の表示させる最小値・最大値の範囲を指定するには ImageJ の API ですと、ImagePlus に、setDisplayRange​(double min, double max) というメソッドがありますので、これを使うのではないかと思われます(確認済み)。UI 上からは表示すべき明度範囲を指定するメニューは見当たらないようです(見逃しているかもしれません)。ImageJ は、まだまだ 8 bit データを扱うことを前提としている部分が多いので、この辺りは今後改善されるのかもしれません。

--------------

関連記事

yasuo-ssi.hatenablog.com

yasuo-ssi.hatenablog.com

yasuo-ssi.hatenablog.com