dnn2pic のソースコード

#!
# coding: utf-8
# Copyright (C) 2015, 2017 TOPS SYSTEMS
### @file dnn2pic.py
### @brief DNN results to picture utility
###
### DNNログファイルから情報を取り出して
### ファイルから読み込んだ別画像に重ねた画像ファイルにして出力する
### Contact: izumida@topscom.co.jp
###
### @author: M.Izumida
### @date: January 4, 2017
###
# Original: dump2pic.py April 21, 2015
# dnn2pic.py v01r01   January 4, 2017
# Written for Python 2.7 (NOT FOR 3.x)
#=======================================================================
# インポート宣言
import sys
import re
import argparse
import os
from datetime import datetime
from PIL import Image, ImageDraw
#=======================================================================
# バージョン文字列
versionSTR = "dnn2pic.py v01r01 Tops Systems (pgm by mpi)"
#=======================================================================
# 共通サブルーチン
#-------------------------------------------------------------------
def errPrint(mes):
    """errPrint.

    エラー出力へのメッセージ表示
    後の始末はその後で別に書くこと
    """
    sys.stderr.write(mes)
    sys.stderr.write('\n')

#-------------------------------------------------------------------
def stdExceptionHandler(mes):
    """standard Exception Handler.

    エラーメッセージを送出し、デバッグのための情報を出力する
    """
    errPrint("Exception Captured: " + str(mes))
    errPrint("0:" + str(sys.exc_info()[0]))
    errPrint("1:" + str(sys.exc_info()[1]))
    errPrint("2:" + str(sys.exc_info()[2]))

#-------------------------------------------------------------------
def tryIntParse(st, dval, radix=10):
    """try Parse string to Integer

    文字列stをパースして整数化できれば値を返す、できなければデフォルト値dvalを返す
    """
    try:
        work = int(st, radix)
    except:
        return dval
    return work

#=======================================================================
# 解析オプション クラス
class Options:
    """Options Class.

    グローバルオプションを保持するクラス
    """
    pass

#=======================================================================
# LOGファイルリーダクラス
[ドキュメント]class logReader: """LOG File Reader Class. insPic2dnn.pyが出力するLOGファイルを読み取って リストとして記憶するクラス """ #-------------------------------------------------------------------- def __init__(self, ifnam): """LOG File Reader Constructor コンストラクタ """ self.iFname = ifnam #データ格納テーブル # 0: 画像ファイル名 # 1: オリジナル sx位置 # 2: オリジナル sy位置 # 3: オリジナル ex位置 # 4: オリジナル ey位置 # 5: DNN判定結果 (0/1/2) self.table = [] # self.tablePTR = 0 # self.debug = False self.verbose = False #--------------------------------------------------------------------
[ドキュメント] def read(self): """read method ファイルから行をリードして処理するメソッド """ try: with open(self.iFname, 'r') as f: for line in f: self.rLine(line) except: stdExceptionHandler("ERROR: in file reading = " + self.iFname) return False return True
#--------------------------------------------------------------------
[ドキュメント] def rLine(self, lin): """Read Line method 読み取った1行を処理するメソッド """ p0 = re.match('([a-zA-Z0-9_\.]+) : ([0-9]+), ([0-9]+), ([0-9]+), ([0-9]+) => ([0-9]+)', lin) if p0: work = [] work.append(p0.group(1)) work.append(tryIntParse(p0.group(2), 0)) work.append(tryIntParse(p0.group(3), 0)) work.append(tryIntParse(p0.group(4), 0)) work.append(tryIntParse(p0.group(5), 0)) work.append(tryIntParse(p0.group(6), 0)) self.table.append(work) return
#--------------------------------------------------------------------
[ドキュメント] def dumpTable(self): """dump table テーブルのダンプ出力。ベリファイ用。 """ for item in self.table: if len(item) > 6: fnam = item[0] sx = item[1] sy = item[2] ex = item[3] ey = item[4] sel = item[5] print "{0} : {1}, {2}, {3}, {4} => {5}".format(fnam, sx, sy, ex, ey, sel)
#======================================================================= # イメージファイルリーダライタ クラス
[ドキュメント]class ImageFileRWriter: """Image File Reader/Writer Class. イメージファイルを読み込み、LOGファイルにしたがって加工した後 ファイルに書き戻すためのクラス """ #-------------------------------------------------------------------- def __init__(self, ifnam, ofnam, dlis, mag): """Image File Reader/Writer Constructor コンストラクタ """ self.iFname = ifnam self.oFname = ofnam self.drawList = dlis self.mag = mag #--------------------------------------------------------------------
[ドキュメント] def load(self): """Image File Reader イメージファイルのリーダ """ try: self.im = Image.open(self.iFname) except: stdExceptionHandler("Error: reading image file = " + self.iFname) return False return True
#--------------------------------------------------------------------
[ドキュメント] def save(self): """Image File Writer イメージファイルのライタ """ try: self.im.save(self.oFname) except: stdExceptionHandler("Error: writing image file = " + self.oFname) return False return True
#--------------------------------------------------------------------
[ドキュメント] def draw(self): """Drawing image method リストに従ってイメージを描く """ drObj = ImageDraw.Draw(self.im) for item in self.drawList: if len(item) < 6: continue sx = item[1] * self.mag sy = item[2] * self.mag ex = item[3] * self.mag ey = item[4] * self.mag sel = item[5] color = (128, 128, 128) width = 4 if sel == 2: color = (255, 0, 0) elif sel == 1: color = (0, 0, 255) drObj.line((sx, sy, ex, sy), color, width) drObj.line((sx, sy, sx, ey), color, width) drObj.line((ex, sy, ex, ey), color, width) drObj.line((sx, ey, ex, ey), color, width)
#======================================================================= # メインプログラム def main(): """main. メインプログラム """ #----------------------------------------------------------------------- # コマンドラインオプション処理 # parser = argparse.ArgumentParser(description='dnn2pic DNN results imager.') parser.add_argument('--ORG', nargs=1, help='Specify Original picture file.') parser.add_argument('--LOG', nargs=1, help='Specify LOG file.') parser.add_argument('--OUT', nargs=1, help='Specify OUTPUT picture file name.') parser.add_argument('--MAG', nargs=1, help='Specify Magnification(default=1).') parser.add_argument('-d', dest='debug', help='Debug mode, print debug information.', action='store_true', default=False) parser.add_argument('-v', dest='verbose', help='Verbose mode.', action='store_true', default=False) parser.add_argument('-V', dest='VERSION', help='Show Version, then exit', action='store_true', default=False) args = parser.parse_args() #----------------------------------------------------------------------- # Version 表示 # print versionSTR if args.VERSION: sys.exit(0) #----------------------------------------------------------------------- # ファイル名処理 # if args.ORG is None: orgFname = 'image001.png' else: orgFname = args.ORG[0] if not os.path.isfile(orgFname): errPrint('ERROR: Original picture file, NOT EXIST.') sys.exit(1) if args.LOG is None: logFname = 'test.log' else: logFname = args.LOG[0] if not os.path.isfile(logFname): errPrint('ERROR: LOG file, NOT EXIST.') sys.exit(1) if args.OUT is None: outFname = 'imageOut.png' else: outFname = args.OUT[0] #----------------------------------------------------------------------- # パラメータ処理 if args.MAG is not None: mag = tryIntParse(args.MAG[0], 1) else: mag = 1 #----------------------------------------------------------------------- # 実処理 # print "-"*50 log = logReader(logFname) if not log.read(): sys.exit(1) if args.verbose: log.dumpTable() img = ImageFileRWriter(orgFname, outFname, log.table, mag) if img.load(): img.draw() if not img.save(): sys.exit(1) #異常終了 else: sys.exit(1) #異常終了 today = datetime.today() print today.strftime("FINISH: %Y/%m/%d %H:%M:%S") #----------------------------------------------------------------------- # 正常終了 # sys.exit(0) #======================================================================= # メインプログラムの起動 if __name__ == "__main__": main()