Google Cloud Vision API で手書きのモデル図からデータを抽出する

Google Cloud Vision API は Google が提供する機械学習モデルを利用して、画像から有益な情報を抽出するインターフェースです。

このAPIを利用して、手書きのモデル図からデータを抽出してみました。

手書きのモデル図

抽出した結果は以下のとおり。

18.8m
M = 100.0
A= 123,4
10.3m
M=200.0
A =567.8
6.3m M. = 300.0
A=9876.5
4.2mM = 300.0
thrin KH = 1000.0
INPUT-SS1 TA KR=2000.0

バネの記号図がなにやら意味不明な単語になっていますが、どうやら記号を無理やり文字に変換しようとしているようで、このあたりはチューニングが必要ですが基本的なデータはしっかり抽出できています。

データを整理して自社サーバなどの解析エンジンにデータを投げれば手書きモデル図から解析を実行するということが可能になりそうです。

Pythonソースは以下のサイトを参考にさせていただきました。
https://www.g104robo.com/entry/google-cloud-vision-api

Python + seleniumでWebシステムを自動化する

Webシステムの入力を自動化したいというお話を頂いたので調べました。
基本的な要素にアクセスすることは勿論のこと、2段階認証も通過できそうです。

import time
from selenium import webdriver

driver = webdriver.Chrome('実際にwebdriverがある場所/chromedriver')
driver.get('https://www.google.com/')
time.sleep(5)
search_box = driver.find_element_by_name("q")
search_box.send_keys('netdxf')
search_box.submit()
time.sleep(5)
driver.quit()
実際の動作動画

Pyfemap(Femap API)でNastranのf06を読込む

PythonからFemapのAPIに接続するパッケージ、PyFemapを使用して標準入力からf06ファイル名を受け取り、Femapのアウトプットセットに読込みます。
dirコマンドと組み合わせれば一度に大量の解析結果を読込むことができます。
アウトプットセットのタイトルはf06のファイル名としていますが、他の情報と組み合わせれば自由に設定できます。

# coding: utf—8

import pythoncom
import Pyfemap
from Pyfemap import constants
Import sys
import os

def main():
    existObj = pythoncom.connect(Pyfemap.model.CLSID)
    app = Pyfemap.model(existObj)

    OutSet = app.feOutputSet

    lines = sys.stdin.readlines()

    for f in lines:
        f = f.strip()
        OID = OutSet.NextEmptyID()
        absf = os.path.abspath(f)
        print(absf)
        rc = app.feAppMessage(0,'Python API MSC f06 Read Started ' + absf)
        rc = app feFiIeReadNastranResuIts(0,absf)
        OutSet.Get(OID)
        OutSet.title = os.path.basename(f)
        OutSet.Put(OID)

if __name__ == '__main__':
    main() 

PythonでCSVファイルをExcelに変換する

PyhtonでExcelファイルのシートをCSVに出力する」の逆です。

# coding: utf-8

import sys
import os
import csv

import openpyxl as px
from openpyxl.utils.cell import coordinate_from_string, column_index_from_string
from openpyxl.utils import get_column_letter, column_index_from_string

def main():

    args = sys.argv

    exf = ''
    csvf = ''
    sheet = ''
    add = 'A1'

    if len(args) < 2:
        print ('USAGE : csv2excel -csv CSVFILE -excel EXCELFILE -sheet SHEETNAME [-address A1]')
        sys.exit()

    for i in range(len(args)):
        if args[i] == '-excel':
            exf = args[i+1]
        if args[i] == '-csv':
            csvf = args[i+1]
        if args[i] == '-sheet':
            sheet = args[i+1]
        if args[i] == '-address':
            add = args[i+1]

    csvfilepath = os.path.abspath(csvf)
    if os.path.exists(csvfilepath) == False:
        print ('!!!ERROR!!! CSV FILE', csvf , ' is not found')
        sys.exit()

    if exf == '':
        exf = csvf + '.xlsx'
    if sheet == '':
        [sheet,ext] = os.path.splitext(csvf)

    exfilepath = os.path.abspath(exf)
    if os.path.exists(exfilepath) == False:
        bk = px.Workbook()
        sh = bk.active
        sh.title = sheet
    else:
        bk = px.load_workbook(exfilepath)
        flg = 0
        for sh in bk.sheetnames:
            if sh == sheet:
                flg = 1
                break
        if flg == 0:
            sh = bk.create_sheet(title=sheet)
        else:
            sh = bk[sheet]

    a = coordinate_from_string(add)
    startrow = a[1]
    startcol = column_index_from_string(a[0])

    print ('CSVFILE   : ', csvfilepath)
    print ('EXCELFILE : ', exfilepath)
    print ('SHEETNAME : ', sheet)
    print ('ADDRESS   : ', add ,"(",startrow,",",startcol,")")

    with open(csvfilepath) as fp:
        reader = csv.reader(fp, delimiter=',')
        irow = startrow
        for row in reader:
            icol = startcol
            for v in row:
                if str.isnumeric(v):
                    sh.cell(irow,icol).value = float(v)
                else:
                    sh.cell(irow,icol).value = v
                icol +=1
            irow += 1

    bk.save(exfilepath)

    print ('FINISHED')

if __name__ == '__main__':
    main()

PyhtonでExcelファイルのシートをCSVに出力する

openpyxlを使用したCSV出力プログラムです。

# coding: utf-8

import sys
import os
import csv

import openpyxl as px

def main():

    args = sys.argv
    exf = ''
    csvf = ''
    sheet = ''

    if len(args) < 2:
        print ('USAGE : excel2csv -excel EXCELFILE -csv CSVFILE -sheet SHEETNAME')
        sys.exit()
 
    for i in range(len(args)):
        if args[i] == '-excel':
            exf = args[i+1]
        if args[i] == '-csv':
            csvf = args[i+1]
        if args[i] == '-sheet':
            sheet = args[i+1]
  
    exfilepath = os.path.abspath(exf)

    if os.path.exists(exfilepath) == False:
        print ('!!!ERROR!!! EXCEL FILE', exf , ' is not found')
        sys.exit()

    bk = px.load_workbook(exfilepath, read_only=True, keep_vba=False)

    flg = 0
    for sh in bk.sheetnames:
        if sh == sheet:
            flg = 1
            break
  
    if flg == 0:
        print ('!!!ERROR!!! SHEET NAME', sheet , ' is not found')
        sys.exit()

    if csvf == '':
        csvf = exfilepath + '.' + sheet + '.csv'
    else:
        csvf = os.path.dirname(exfilepath) + '/' + csvf

    print ('EXCELFILE : ',exfilepath)
    print ('SHEETNAME : ',sheet)
    print ('CSVFILE : ',csvf)

    ws = bk[sheet]

    with open(csvf, 'w', encoding='utf-8') as fp:
        writer = csv.writer(fp)
        for cols in ws.rows:
            writer.writerow([str(col.value or '') for col in cols])

    print ('FINISHED')

if __name__ == '__main__': 
    main()

PythonからFemapのAPIに接続する

以下のサイトがとても参考になります。

https://community.plm.automation.siemens.com/t5/CAE-Simulation-Knowledge-Base/Writing-the-FEMAP-API-in-Python/ta-p/378038

FemapのAPIインターフェース、femap.tlbに接続するために先ずpywin32が必要です。
これを使って、femap.tlbからPyfemap.pyを作成し、これをimportしてfemapに接続します。

実際の接続は以下のとおりです。

import pythoncom
import Pyfemap
import sys

existObj = pythoncom.connect(Pyfemap.model.CLSID)
app = Pyfemap.model(existObj)

rc = app.feAppMessage(0,"Python API Example Started")



ezdxfで二つのDXFを重ね合わせる

PythonのパッケージにDXFを扱うezdxfというものがあります。
まず、このパッケージをつかって、簡単な線を描画してDXFを保存します。

import ezdxf

dwg = ezdxf.new('R2010')

msp = dwg.modelspace()  
msp.add_line((0, 0), (10, 0))  
dwg.saveas('line.dxf')

次に、この「line.dxf」を読み込んで新しく「test」というレイヤーを作成し、このレイヤーにもう一つ線を描画します。

import ezdxf

dwg = ezdxf.readfile("line.dxf")
msp = dwg.modelspace()

dwg.layers.new('test')
msp.add_line((0,-10), (10, 10), dxfattribs={'layer': 'test'})

dwg.saveas('line2.dxf')

「test」というレイヤーが作成され、それぞれのレイヤーに線が描画されています。

このやり方で、既存の図面に解析結果などを重ねるといったことが可能になります。

Jupyter Notebookはシミュレーション解析に有効か

こちらの記事を参考にPython絡みでJupyter Notebookを試してみました。

モデルの妥当性を検証するために、地震動の解析では実験や実際の観測記録によるシミュレーション解析が行われます。

実際の構造物と、設計裕度を考慮した設計時の解析モデルでは物理定数が違いますし、実際の状況を踏まえて設計時のモデルから様々なデータを変化させながらシミュレーションを行っていくことになります。

この「データを変化させながら解析する」ということに対してJupyter Notebookは有効ではないかと感じています。

データをどのように変化させたのか、その影響がどの程度であったのかなどを記述しながら解析を詰めていけることはとても有益です。

このプロダクトをクラウドで提供するGoogleのColaboratoryというサービスも存在します。

こちらには「機械学習集中講座」というコンテンツがあり、notebookの使い方を概観することができます。