粗大メモ置き場

個人用,たまーに来訪者を意識する雑記メモ

GitHub ActionsとMarkdownで書類作成 ~ Asciidoc編~

概要

下記記事のGitHub Actions版だと思えば良いです。

ossyaritoori.hatenablog.com

下記に出来上がった書類のサンプルを載せます。

https://yoshiri.github.io/MarkdownToAsciidocToHTML_CI/sample.html

Markdownからの変換手法

ここではMarkdownで書いた文をAsciidocに変換します。

qiita.com

MarkdownからAsciidocへの変換はPandocとKramdocの2択があります。

  • Pandoc
    • 言わずとしれた万能変換ツール
    • 🙆数式などの変換がちゃんとしている
    • 🙅タイトルへの変換
  • Kramdoc
    • Asciidoctorの開発側が開発した変換ツール
    • 🙆章立てなどがきれいに変換される
    • 🙅数式や一部書式が正しく変換されない

ここではPandocを採用します。(数式の書きにくいドキュメントはありえないので。)

ここで,Pandocで用いるコマンドを下記に示します。(DockerコマンドなのでPandoc環境がある人は適当に読み替えてください)

wsl docker run --rm -v $(pwd):/data pandoc/core: sample.md --to asciidoctor -o sample_pandoc.adoc  --shift-heading-level-by=-1

引数の詳細などは下記を参照すると良いです。(本当は英語版サイトのほうがもっと良い。)

sky-y.github.io

変換前提のMarkdownの書き方について

基本的な書き方はうまいこと変換されますが,気をつけなければ行けないのは章立てです。

通常の書き方をすると下記のようになると思います。

# 1章
## 1-1節
## 1-2 節
# 2章
## 2-1節
### 2-1-1節
...

本記事で紹介する変換法を用いる場合文章は下記のように書くことを推奨します。 AsciidocのLevel1はHTMLのタイトル用であり,章がLevel2からスタートしていることに起因します。

# 文書タイトル
## 1章
### 1-1節
### 1-2 節
## 2章
...
このように一つずつずらす。

または,マークダウンで見た時に不格好になるのが気にならなければ下記のようにかくのも良いでしょう。

= 文書タイトル
## 1章
### 1-1節
### 1-2 節
## 2章
...
(上記は`--shift-heading-level-by=-1`のときの書き方)

理由は次で説明します。

--shift-heading-level-by=-1を用いた時の挙動について pandocで下記のようなマークダウンを変換した場合,レベルを1段下げます。

# 文書タイトル
## 1章
### 1-1節

下記のようにAsciidocでは=#のような役割を持ちます。

== 文書タイトル
=== 1章
==== 1-1節

これに対して--shift-heading-level-by=-1を引数に加えることでレベル下げをキャンセルできます。 できるのですがタイトルのブッキングを避けるために下記のような結果を生成します。

文書タイトル   <- 本当は"="から始まってほしい 
== 1章
=== 1-1節

これを避けるもっとも手っ取り早い方法は最初からタイトルの装飾を"#"から"="に書き換えて置くことです。

置換でタイトルの"#"を"="に変更

タイトルの装飾を"#"から"="に書き換えて置くことで上記の問題は解決しますが,Markdownでこれを書くのは面倒。

ということで,GithubなどのCIの時点でタイトルの装飾を変えれば良いです。

具体的には,sedコマンドを用いて 文章の最初に出てきた"# "のを"= "に変えます。(タイトルはほぼ文章の最初に来るはずなので)

コマンドはこちら。

sed -ie '0,/# / s/# /= /' sample.md

workflowの定義

サンプルリポジトリをおいておきます。

github.com

workflowは下記のような内容です。

# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run. 
on:
  # Triggers the workflow on push or pull request events but only for the master branch
  push:
    branches: [ master ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # asciidoc to html
  asciidoctor_job:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    name: Build AsciiDoctor
    steps:
    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
    - name: Check out code
      uses: actions/checkout@v2
    - name: Fix Title Level Issue
      run: sed -ie '0,/# / s/# /= /' sample.md
    - name: Markdown To Asciidoc
      uses: docker://pandoc/core:2.11
      with:
        args: -f markdown+east_asian_line_breaks sample.md --to asciidoctor -o sample.adoc --wrap=preserve --verbose  --shift-heading-level-by=-1
    # Output command using asciidoctor-action
    - name: Build AsciiDoc step
      id: documents
      uses: Analog-inc/asciidoctor-action@master
      with:
        shellcommand: "asciidoctor sample.adoc -r asciidoctor-diagram -a allow-uri-read -a data-uri -a toc=left" 
    # Use the output from the documents step
    - name: move deploy files
      run: |
        mkdir build/
        mv sample* build/
        ls build
    - name: deploy
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./build
        publish_branch: gh-pages

以上!

GitHub ActionsとMarkdownで静的サイト作成 ~ mkdocs-material 編~

目的

Markdownで書いた文書を静的サイトとしてまとめ上げたい。 そしてそのままそれを本番の文章として提出しちゃいたい。

なお,前回の記事はこちら。

ossyaritoori.hatenablog.com

要求:

  • 検索機能つきの静的なサイトが生成される
  • 表現が豊か(数式・図表・Admonitionなど)
  • PDFに出力可能

超参考になるサイト:

in-neuro.hatenablog.com

ここから,mdbook, (gitbook), mkdocsあたりを試していこうと思います。

mkdocs-material

Pythonで動く静的サイト作成手法mkdocsのmaterialというテーマ。

github.com

f:id:ossyaritoori:20210212170139p:plain
見た目はこんなかんじ。

Pros and Cons

  • 🙆Pros
    • 表現力が豊か(数式,PlantUML,Admonitionなど)
    • 日本語検索にデフォルトで対応
    • cssのカスタムテンプレートなどの数が多い
  • 🙅Cons
    • サーバーを立てないと検索窓が立たない(Github Actionsでは無問題)
    • 拡張機能が多く管理が面倒

機能性・拡張性では今の所mdbookよりも良さそうです。

Dockerを用いた動作

多くの人が入れているであろうPython環境で動くので自前でも動かせますが,Dockerイメージもあります。 自分はWSLでやっていますが,Docker for windowsの場合は適宜`pwd`”%CD%”にするなど置き換えてください。

とりあえず動かす分にはsquidfunk/mkdocs-materialが多く使われている感じがします。

hub.docker.com

  • 初期化
wsl docker run --rm -v `pwd`:/book/ squidfunk/mkdocs-material init
  • build
wsl docker run --rm -v `pwd`:/book/ squidfunk/mkdocs-material build

ざっくり生成されるファイル・フォルダを説明すると

  • book.toml : 書式や署名などを指定する
  • src/ : 文書のソースを置く場所
    • SUMMARY.md : リスト形式で文章のネスト構造を指定する
    • xxx.md: 本体の文章
  • book/ : 生成されたサイトがここに格納される。文章へはindex.htmlにアクセス。

Github Actionsを用いたドキュメントのHost

ひとまずテストプロジェクトを立ててみました。

github.com

なお,拡張機能をいろいろ盛り込んだので動作検証用のossyaritoori/mkdocs-materialにてイメージを公開しました。

したがって,実行コマンドは下記のような感じになります。

docker run --rm -v `pwd`:/docs ossyaritoori/mkdocs-material build

ファイル構造

ファイル構成はこんなかんじです。

mkdocsTest
├── .github
│  └── workflow
│     └── mkdocs.yml
│
├── mkdocs.yml # book setting
└── docs # Source folder
   ├── index.md # For top page (Not neccesary)
   └── < other .md files >

.github以下のActionsについて

Actionの流れは

  • ファイルをCIサーバーにUpload
  • build
  • docs以下をgh-pagesに展開

としました。

name: deploy mkdocs
on:
  push:
    branches:
      - main
      - master

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - name: Check out code
        uses: actions/checkout@v2
      # Prepare Python package
      - uses: actions/setup-python@v2
        with:
          python-version: 3.x
      - run: pip install mkdocs-material
      - run: pip install plantuml-markdown python-markdown-math mdx_truly_sane_lists mkdocs-git-revision-date-localized-plugin mkdocs-add-number-plugin
      # deploy
      - run: mkdocs gh-deploy --force

gh-pagesの設定

上記のFlowではgh-pagesブランチに生成物をUploadしています。

gh-pagesの設定は「設定」→「一般」から下記の項目で

f:id:ossyaritoori:20210212163623p:plain
一般の項から

TODO・その他

GithubActionについて

面倒でそのままpipを手打ちしていますがRequirement.txtとかを書いてそこからインストールしたほうが良さそうです。 Dockerfileもそれに準拠して書かないとなぁとは思っています。

PDF生成

こんな感じのPDFが拡張機能によって作れます。

github.com

インストール後,CSSファイルをコンパイルして作成することでそれっぽくできます。

ただ,日本語が文字化けしてしまったのでそのあたりはCSSを調整してみないと,といった感じです。

GitHub ActionsとMarkdownで静的サイト作成 ~ mdbook 編~

目的

Markdownで書いた文書を静的サイトとしてまとめ上げたい。 そしてそのままそれを本番の文章として提出しちゃいたい。

要求:

  • 検索機能つきの静的なサイトが生成される
  • 表現が豊か(数式・図表・Admonitionなど)
  • PDFに出力可能

超参考になるサイト:

in-neuro.hatenablog.com

ここから,mdbook, (gitbook), mkdocsあたりを試していこうと思います。

mdbook

開発が終了したGitbook v1のRust版後継です。

f:id:ossyaritoori:20210212165401p:plain
こんなかんじの見た目になります。

Pros and Cons

  • 🙆Pros
    • 動作が軽量。コンパイルが早い。
    • サーバを建てずともサイトの検索機能が動作する
  • 🙅Cons
    • 現状日本語検索に対応する気があまりなさそう…
    • 発展途上なので現状表現力は他の手法に劣る。

Dockerを用いた最小動作

Rust環境を建てても良いですが,Dockerで開発するのが無難です。 自分はWSLでやっていますが,Docker for windowsの場合は適宜`pwd`”%CD%”にするなど置き換えてください。

github.com

  • 初期化
wsl docker run --rm -v `pwd`:/book/ peaceiris/mdbook init
  • build
wsl docker run --rm -v `pwd`:/book/ peaceiris/mdbook build

ざっくり生成されるファイル・フォルダを説明すると

  • book.toml : 書式や署名などを指定する
  • src/ : 文書のソースを置く場所
    • SUMMARY.md : リスト形式で文章のネスト構造を指定する
    • xxx.md: 本体の文章
  • book/ : 生成されたサイトがここに格納される。文章へはindex.htmlにアクセス。

Github Actionsを用いたドキュメントのHost

ひとまずテストプロジェクトを立ててみました。

github.com

ファイル構造

ファイル構成はこんなかんじです。

mymdBook_Test
├── .github
│  └── workflow
│     └── mdBook.yml
│
├── book.toml
└── src
   ├── chapters
   │  ├── introduction.md
   │  └── <other .md files>
   └── SUMMARY.md

.github以下のActionsについて

Actionの流れは

  • ファイルをCIサーバーにUpload
  • build
  • book以下をgh-pagesに展開

としました。

name: github pages

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v2

      - name: Setup mdBook
        uses: peaceiris/actions-mdbook@v1
        with:
          mdbook-version: '0.4.6'
          # mdbook-version: 'latest'

      - run: mdbook build

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./book

gh-pagesの設定

上記のFlowではgh-pagesブランチに生成物をUploadしています。

gh-pagesの設定は「設定」→「一般」から下記の項目で

f:id:ossyaritoori:20210212163623p:plain
一般の項から

TODO・その他

  • ちょっときになる点
    • 左のTitleが折り畳めない
  • PDF生成とか試しておきたい。

Splatoon2で表示される文字をフォントから学習してTesseraactでOCRする

概要

  • Splatoon2の録画の動画からカウントや時間,スペシャルなどの情報を抽出するためにOCRを行う
  • コンテンツ
  • TesseraactとjTessBoxEditorを用いてSplatoon2のフォントを学習
  • pyocrを用いて画像から文字領域を抽出の上,OpenCVを用いて下処理・描画

背景

突然ですがIkaLogというツールを皆さんご存知でしょうか。 詳細は下記のスライドに任せますが,Splatoon1の時にプレイ画面を解析して試合の詳細な流れを記録するツールです。

www.slideshare.net

具体的には,ステージ名などの基本情報から敵味方の生存状況のタイムライン,スペシャルやカウントの進みなど多岐にわたる解析が可能だったようです。

f:id:ossyaritoori:20201224010459p:plain
上記SlideShareから引用。こんな感じのデータがとりたい。

自分もスプラプレーヤーとして試合の流れなどの情報を一度整理したいと思い今回のツールを個人開発してみようと思い立つに至りました。

目指すところ

  • Splatoon2のプレイ動画をHDMI経由のストリーミングか動画ファイル形式で受け取る
  • 動画情報から「敵味方の生存状況」,「スペシャル状況」,「カウント情報」を抽出する。

筆者の開発環境

参考までに筆者の開発環境を載せます。言語はPythonで重要なパッケージは以下のとおりです。

  • Windows10 Home, Python3.6 in Anaconda
    • OpenCV 3.4
    • Tesseract 5.0 alpha
    • pyocr 0.7.2

の上で動かすことを前提にしています(古くてごめん)。

OCR環境を整えてSplatoon2のフォントを学習する

本章ではまず,環境を整えてSplatoon2のフォントを学習するところからやっていきます。

ここでは下記の記事が大変参考になるので是非一読をおすすめします。というか細かい部分は下記を参照してください。

www.tdi.co.jp

TesseractとPyOCR環境のインストール

Python上で学習を動かせるように環境を設定します。詳しくはこちらに任せるとして勘所だけ書いておきます。

  • Python OCR環境のインストール
    • Tesseractのインストール
      • ここから最新版5.0alphaをインストール
      • 「Additional language data (download)」から「Japanese」を選択すると捗る
      • 環境変数Pathにインストール先フォルダを指定。(私の場合はC:\Program Files\Tesseract-OCR
    • pyocrのインストール
      • pip install pyocrで問題ない(できることならcondaで入れたかった…)
  • インストール後の確認
    • 設定の反映には再起動が必要

インストール確認には下記のコマンドを実行してください。

import pyocr
tools = pyocr.get_available_tools()

for tool in tools:
    print(tool.get_name())

出力にTesseract (sh)が入っていれば成功です。

学習用ツールjTessBoxEditorのインストール

次に,フォントを新たにTesseractに学習させる時に使えるGUIツールをインストールします。

成功すれば下記のような画面が出てくるはずです。(画像出典: https://www.tdi.co.jp/miso/tesseract-ocr

https://www.tdi.co.jp/miso/wp-content/uploads/2018/07/iTessBoxEditor_01-660x365.png

Splatoon2のフォントをDLしてくる

Tesseractに新たに文字を学習させるには文字のフォントが必要なのですがSplatoon2任天堂オリジナルフォントで2次配布されていません。

フォントの製作は最も苦労するパートのハズですが,ここでは海外有志が作成したと思われるSplatフォントを用います。

candyfonts.com

インストールするにはDLしたttfファイルをC:\Windows\Fonts\にコピーします

(上記フォルダにないとjTessBoxEditorが認識しなかったため。)

f:id:ossyaritoori:20210102022733p:plain
こうなっているはずです。

Splatoon2のフォントを学習する

  • 学習用フォントファイルの作成
    • iTessBoxEditorを起動し、「TIFF/Box Generator 」タブを開く。
    • 上図(1)に学習済み言語を表す英字を入力。(これは後で言語として選択する時に使うもので自分で決めます。三文字を使うことが多いですが今回は「spl2」としておきます。)
    • 上段の位置から「Splatフォント」を指定
    • 学習したい文字を打ち込む。(打ち込んだ文字のみを学習する仕様のようです。下図では数値だけを学習する例を見せています。)
    • Generateを押してboxファイルを作成する。

f:id:ossyaritoori:20210102113821p:plain
Splatフォントの数値を学習した時

上記をすべて実行すると下記のようなファイル群が生成されるので後の工程のために任意のフォルダに移動すると良いです。

f:id:ossyaritoori:20210102194646p:plain
Generateを押して生成されるファイル

今回は数値のみを学習したsplというboxファイル,カタカナ文字を学習するspl2というboxファイルを作成しました。

カタカナの学習の五十音は下記のサイトからコピペしてきました。(本来は頻出の単語なども学習するっぽい(要検証)なので,スプラ2で使われる文字列などを学習したほうが良さそうです。)

note.pandako.com

学習の実行

こちらも上記文献の引用です。

  • iTessBoxEditorでの学習の実行。まず「 Trainer 」タブを開く
    • Traininig Data(1):上記で生成したファイル「spl2.splatfont2.exp0.box」を選択。
    • Language(2):「spl2」と入力。
    • Training Mode(3):「Train with Existing Box」を選択。
    • Run(4)を実行し,** Moving generated traineddata file to tessdata folder ** (改行) ** Training Completed **のメッセージが出たら完了。
  • 生成されたファイルspl2.traineddataをTesseractの環境にコピー
    • 自分の場合は,Programfiles以下のC:\Program Files\Tesseract-OCR\tessdataに環境が合ったのでそこにコピー。

https://www.tdi.co.jp/miso/wp-content/uploads/2018/07/iTessBoxEditor_train_01-660x365.png

ここまでで完了。

結果だけ欲しい人用

上記の経緯は結局,「Tesseraactで使えるスプラトゥーンの文字フォント学習ファイルを生成」しているだけなので端的に結果のファイルをDLしてコピーできれば良いです。

とりあえず私が雑に作ったものを以下に載せます。

Splatoon2のカタカナを学習したフォントファイル。(Tesseract用)spl.train…

参考までに,似たようなことをやっている方として下記のような記事があります。

qiita.com

OpenCVとPILを用いてOCR結果を表示

Pythonのpyocrモジュールを用いてOCR結果を取得して図示するところまでやります。

image_to_stringという関数を用いるのですが大体下記2つについて書きます。

  • OpenCVで画像を読み込んでOCR結果を得るところまで
  • OCR結果をBoundingBoxとテキストで表示するところまで

PyOCRのimage_to_stringでOCRする

とりあえず初めて使うパッケージは公式ドキュメントを見よというのが鉄則なんですが全然検索の上位に出てこないので結構キレそうになります。

一応まともそうなのは下記でしょうか。

gitlab.gnome.org

また,下記の記事なども参考にしました。

blog.machine-powers.net

私が使った関数は

tool.image_to_string( <PIL image>, lang="spl2",builder=pyocr.WordBoxBuilder())

というものです。

引数についての説明は以下の通り。

  • tool:pyocr.get_available_tools()にリストで入っている一要素。今回はtool = pyocr.get_available_tools()[0]でOK。
  • Image :cv2(numpy)の画像ではなくてPILのImage形式で入れる
  • lang:使用する検出言語。日本語なら”jpn”,英語なら”eng”,今回はカタカナを認識するので先程学習した”spl2”を用いる
  • builder:どのような出力を吐き出すかを変更できる。今回は位置と単語と確信度を抽出できるpyocr.WordBoxBuilder()を使用。

特にPILのImage形式で入れなければ行けないのがだるいためcv2とPILとの変換関数を用意する必要があります。

ということで変換を含めた関数ファイルは下記の通り。

import pyocr
import cv2
import numpy as np
import pyocr.builders
import matplotlib.pyplot as plt
from PIL import Image, ImageDraw, ImageFont

def cv2pil(image):
    ''' OpenCV型 -> PIL型 '''
    new_image = image.copy()
    if new_image.ndim == 2:  # モノクロ
        pass
    elif new_image.shape[2] == 3:  # カラー
        new_image = cv2.cvtColor(new_image, cv2.COLOR_BGR2RGB)
    elif new_image.shape[2] == 4:  # 透過
        new_image = cv2.cvtColor(new_image, cv2.COLOR_BGRA2RGBA)
    new_image = Image.fromarray(new_image)
    return new_image

def extract_imageboxes(img,lang_setting="jpn",tool = tool, builder = pyocr.builders.WordBoxBuilder(),):
    """ 
    img: opencv img
    lang: language setting
    builder
    """
    LineBoxes = tool.image_to_string(cv2pil(img),lang_setting, builder = builder)
    res = {}
    for lb in LineBoxes:
        dic = {}
        dic["position"] = lb.position
        dic["confidence"] = lb.confidence
        res[lb.content] = dic
    return res

返り値として,検出した文字列をKeyにした辞書型オブジェクトの辞書を返します。 使用例は後ほど。

PyOCRの検出結果を描画する

PyOCRで検出した結果,「テキスト」,「BoundingBox」,「確信度」が帰ってくるのでこれを可視化します。

具体的には下記の画像のようにします。

  • 日本語テキストを書き込む
  • BoundingBoxを書き込む
  • 確信度によって色を変える

f:id:ossyaritoori:20210103005333p:plain
赤い線がBoundingBoxで文字が検出結果。小文字を教えていないので”ッ”の検出には失敗していますがあらかた読めています。

OpenCV画像に日本語テキストを書き込む

簡単のように見えて一番だるい作業でした。下記の記事を改変して作業しています。

qiita.com

下記改良版においては一度画像をPILに変換してからPILの関数を用いて書き込んでいます。

gist.github.com

これらの機能のまとめ

以上の

  • extract_imageboxes:OCR情報抽出
  • cv2_putJPText:日本語書き込み関数

の2つと色変換の関数を加えて画像を直接加工するshowWordBoxesAndText関数を作りました。

def hsv_to_rgb(h, s, v):
    bgr = cv2.cvtColor(np.array([[[h, s, v]]], dtype=np.uint8), cv2.COLOR_HSV2BGR)[0][0]
    return (int(bgr[2]), int(bgr[1]), int(bgr[0]))

def showWordBoxesAndText(img,showimg=None,lang_setting = "jpn"):
    """
    opencv画像を元にpyocrで読んだテキストをBoundingBoxと一緒に書き込む。赤味が強いほど確信度が高い。
    """
    imgshow = img.copy() if showimg is None else showimg.copy()
    dics = extract_imageboxes(img,lang_setting)
    print(dics) # 一応結果が見たいのでShowしている
    #fontpath ='C:\Windows\Fonts\MEIRYOB.TTC' # メイリオを指定する場合。Windows10 だと C:\Windows\Fonts\ 以下にフォントがあります。
    
    
    for dic in list(dics.keys()):
        if len(imgshow.shape) == 2:
            fontcolor = int(2.55 * dics[dic]["confidence"])
        else:# color image
            fontcolor = hsv_to_rgb(2 * dics[dic]["confidence"],255,255)
        text = dic 
        
        cv2.rectangle(imgshow, dics[dic]["position"][0], dics[dic]["position"][1], fontcolor) 
        cv2_putJPText(imgshow,text ,dics[dic]["position"][0],fontScale=15,color= fontcolor,mode=1)
    return imgshow

その他コツ

いくつかのサンプルを試した結果下記のようなことが言えそうです。

  • 大きな画像ほど文章抽出が困難になるのでなるべく読みたい文字に対して領域を小さく区切って検出する
  • 文字が白いなどの付加情報があるなら事前に色や輝度でマスクすると捗る
  • 確信度(Confidence)でフィルタリングするのは雑音除去に有用だが稀に半角スペースが高い信頼度で検出されるので弾く必要がある
    • 具体例:{' ': {'position': ((0, 0), (0, 151)), 'confidence': 95}}みたいなかんじ。

他にも傾向などありましたら聞きたいです。

適用結果とその比較

ということで,上記の関数を使って抽出してみました。 比較として,デフォルトでDLできる日本語検出”jpn”と今回学習したスプラトゥーン2のカタカナフォント”spl2”を指定した際の違いをお見せします。

スペシャル情報

まず,スペシャルの文字列を検出したときですが,

デフォルトの”jpn”で検出した結果 学習した”spl2”で検出した結果
f:id:ossyaritoori:20210103010611p:plain f:id:ossyaritoori:20210103005333p:plain

このように完璧ではないですが欲しい情報に近いものが得られました。(実際スペシャルを知りたいだけなのでこれくらいならその他文字列との距離を取れば余裕で分類できそうです。)

試合時間・カウント

試合時間は中央の固定領域にあるので領域指定して抜き出せば簡単に呼べます。 この数値に限って言えば,別に英語のOCRでも正しく検出出来ました。

デフォルトの”jpn”で検出した結果 学習した”spl”で検出した結果("eng"でも同様の結果)
f:id:ossyaritoori:20210103011821p:plain f:id:ossyaritoori:20210103011719p:plain

一方でカウントは簡単かと思いきや,下記のように広い領域では何も検出できませんでした。

f:id:ossyaritoori:20210103011959p:plain
検出結果(何も検出できなかったので何も書かれていない)

白い領域を抽出後,下記程度に範囲を絞って下の画像のレベルまで情報を整理してようやく正しく検出が出来たのでそのあたりはちょっと調整が必要そうです。

f:id:ossyaritoori:20210103012107p:plain

ルール名・タイトル

ルール名も精度が悪いです。これは比較的簡単な理由で,ルールのフォントは学習したフォントとは若干違うからです。 この辺を改善しようとすると学習器のチューニングが必要ですが,4つのルールを分類出来さえすればいいのでうまいこと距離を導入できればなんとかできそうです。

デフォルトの”jpn”で検出した結果 学習した”spl”で検出した結果("eng"でも同様の結果)
f:id:ossyaritoori:20210103012527p:plain f:id:ossyaritoori:20210103012215p:plain

おわりに

ということで,PyOCRとTesseractを用いてスプラトゥーン2の画面情報を読み取ろうという記事でした。

本当はアドベントカレンダーに載せようと思っていたのですがあまりにも諸エラーや記事の執筆に時間がかかってしまったため遅刻&中途半端な記事になりました。すいません。

他にもスプラ愛好家として以前,Splathon2で散々言われている編成などの「勝ちにつながる要素」を定量的に解析しようというのをやっていたりして,今中途半端になっているのでそちらもうまいこと計画して進めて行きたい所存です。

ossyaritoori.hatenablog.com

TODO

やりたいことはあるのですが1月は結構仕事が忙しそうなのでしばらくまた休眠するかもしれません…

  • 一連のコードを整理して公開
  • 記事のブラッシュアップ
  • 検出した結果を元に動画から一通り情報を抜いてみる
    • 適切な距離を定義して検出単語を分類
    • 前処理とかも含めたコードの整理
  • 頻出な単語を学習することで検出精度の向上?
  • プロジェクトを進める

超余談:Gistにバイナリを上げる方法

バイナリはドラッグアンドドロップ出来ないので無理だと思っていたがどうやら下記の方法で普通にアップできます。結構面倒ですがまぁヨシとします。

  • 適当なGistを建てる
  • URLをコピってClone
  • バイナリを追加・リポジトリ修正してPush

How to add an image to a gist: https://remarkablemark.org/blog/2016/06/16/how-to-add-image-to-gist/ · GitHub

Latexを使ってふるさと納税で必要な身分証明証のコピー画像をまとめて印刷する

ふるさと納税のワンストップ申請は翌年1/10まで!!

概要

  • ふるさと納税のワンストップ申請ではたくさんの身分証明証(例:マイナンバーカード)を印刷して貼る必要がある
  • 毎回印刷していると紙と印刷代がもったいないので実寸代に敷き詰めて印刷できるようにPDFを生成する
  • 昔名刺を印刷する時に書いたLatexを流用してパッケージ化

モチベーション

ふるさと納税をしようとしたところ,ワンストップ申請ごとに身分証明証のコピーを貼る必要があったためこれらを大量に印刷する必要性に駆られました。

問題として,

  • プリンタもスキャナもないのでコンビニにいかねばならない。複数印刷するのは手間だし高い
  • Wordみたいな文書にスマホで撮った画像を複数貼って実寸のサイズに合わせて,一枚一枚貼って…というのが面倒

というのがあったため,下記のようにまとめて印刷できるような版組をLatexで組んでみました。

f:id:ossyaritoori:20201229014529p:plain
ここではたまたま名刺をサンプルに使ってますが,身分証明証の表と裏を使いました。

関連記事

github.com

  • 名刺を作ったときの過去の記事

ossyaritoori.hatenablog.com

パッケージの使い方

必要な環境

  • LatexpLatex)をでコンパイルできる環境。geometry.styが入っていることが必須。
  • 名刺か身分証明証の表面と裏面の画像(スケールは問わないがアスペクト比は正しくすること)
    • スマホで真上から撮ってペイントで切り抜くとかでもOK
  • コンパイル用のLatexファイル。IdentificationCard.tex

github.com

操作手順

  • 表面の画像をfront.jpg,裏面をback.jpg(pngでも可)としてIdentificationCard.texのあるファイル以下のimgsフォルダに保管
    • 上のリポジトリをCloneしてそこに置くのが多分手っ取り早い
  • コンパイル

2000円そこらで買えるガジェットでswitchなどのゲーム動画の録画環境を揃えられた話

概要

  • 動画録画配信に必要な「HDMIキャプチャボード」と「HDMIスプリッター」が合わせて2000円前後で買える時代になった
  • OBS Studioを使って実際に動画を撮ってみたが画質にこだわらなければ超安価なセットアップでも動画が撮れる

はじめに

SwitchやPSの出力をPCに取り込んで実況や動画撮影を行うには「キャプチャボード」という部品が必要です。

これが従来は1万を超えるなかなか高価なもので手が出なかったのですが下記のように最近1000円台でも普通に動作するものが手に入るようになったそうです。

ということで適当に買って試してみました。

japanese.engadget.com

note.com

使った機材について

新たに買ったのは以下の2つだけです。

併せて2000円少し。安い!
キャプチャボードは下記のもっと安いのでも良さそうですが,PCに直挿しはちょっと接触が不安だったので今回は分離型を選んでます。

また,動画の撮影編集にはPC環境が必要で,自分は下記の環境で動画を撮影・編集しました。

  • Windows 10 ノートPC (Zenbook Pro,そこそこスペック)
  • Adobe Premiere Rush(編集ソフト)
  • OBS Studio(録画ソフト)

OBS Studioはキズナアイごっこの時に入れた動画録画ソフトです。 動画つかってどうこうしたい時には今後もお世話になりそうです。

ossyaritoori.hatenablog.com

動画を撮る手順

  1. HDMI分配器でゲームの出力を分岐させて,ディスプレイとキャプチャボードにそれぞれつなぐ
  2. OBS Studioを起動,シーン追加,ソース追加から「映像キャプチャデバイス」を選択 f:id:ossyaritoori:20201125020145p:plain
  3. 「デバイス」から「USB Video」を選択 f:id:ossyaritoori:20201125020243p:plain
  4. 画面が写っていればOK! 右下の「コントロール」から録画開始

f:id:ossyaritoori:20201128164440p:plain
うつった!

なお,一度USBを取り外すとデバイスの再認識が必要っぽいので注意。 今の所5時間くらいは繋ぎっぱなしでもOKです。

副次的な使い方:ラズパイやJetsonなどのガジェットの出力確認

このHDMI出力をノートPCに写すという機能をもつHDMIキャプチャボードの副次的な使い方として,Raspberry PiやJetsonなどの画面出力のないデバイスのディスプレイとしてノートPCの画面が使えるというのがあります。

別に配信しないなんて人でもサブディスプレイもどきやガジェット開発にそれなりに使い手はありそうです。

おまけ:動画編集からYoutube投稿まで

せっかく動画を撮ったのでYoutubeにあげてみました。

使ったのはPremiere Rush。普段はaviutlを使うんですがPremiere Rushはよりシンプルでいいですね。 Fimoraというのが手軽と聞きましたが自分はそれよりPythonとかでMarkdownみたいなテキスト集から自動で挿入,編集できたらいいなーと思ってます。

note.com

自分はスプラジャンキーなのでスプラの動画を貼って終わりにします。

www.youtube.com

そういえばこんなデータ解析ごっこもしています。そろそろ以下の頃の倍データが溜まったのでまた解析にかけてみたいところ。

ossyaritoori.hatenablog.com

それでは皆さん,いいスプラトゥーンライフを!(違う)

MarkdownをAsciidocに変換するKramdocまたはPandocをDocker環境で動かす

概要

  • Asciidocは便利できれいだがちょっと書きにくい
  • 書き慣れているMarkdownから変換する手法を試した
  • Dockerイメージを用いて以下のように変換可能。

Kramdoc版:

docker run --rm -v $(pwd):/documents/ asciidoctor/docker-asciidoctor kramdoc  --wrap=ventilate --format=GFM sample.md

または,Pandoc版:

docker run --rm -v $(pwd):/data pandoc/core:2.10 sample.md --to asciidoctor -o sample_pandoc.adoc

なお,筆者の環境はDocker on ubuntu20 on wsl2 on windows 10です。(ギャグっぽい)

はじめに

Asciidocは書きやすさとリッチな描写力を兼ね備えた便利なマークアップ言語です。

qiita.com

ossyaritoori.hatenablog.com


しかし,Latexはいざしらず超楽なMarkdownに慣れてしまうとなかなか文法を覚えて書くというのをしたくなくなります。


そこで,Markdownでさっと書いてそこからAsciidocの雛形を書くという方式を取るための手順をまとめてみます。

サンプルやソースについて

本記事で用いたサンプルやソースはこちら。

github.com

Markdown to Asciidoc

ざっと調べた感じ,Pandocを使うという人とKramdoc(Kramdown)を使うという人の2パターンあるようです。

サンプルに使うマークダウンファイルはこちら

Pandoc(新しいバージョンを使うことを推奨)

Jupyterで使われているはずなので多分Pandocが入っている人も多いと思います。

有名かつ有用なツールですが古いバージョンに関してはAsciidocの生成に関しては使い物にならないので注意です。Dockerなどで特定のバージョンを使える環境を用意したほうが良いと思います。

qiita.com

WSL,Docker環境がある前提で行けば下記のコマンドにてsample.mdファイルをsample_pandoc.adocファイルに変換できます。

pandoc/core

おそらくこちらが本来のバージョンです。こちらを使ったほうが引用がきれいになりそうです。

既存の問題としてこのままだとタイトルのレベルがずれるので別途タイトルを= タイトルのようにAsciidoc記法で書く必要があります。

wsl docker run --rm -v $(pwd):/data pandoc/core:2.10 sample.md --to asciidoctor -o sample_pandoc.adoc 

pandoc/latex:2.10 (非推奨)

Latexコンパイルに特化したイメージです。

wsl docker run --rm -v $(pwd):/data pandoc/latex:2.10 sample.md --to asciidoctor -o sample_pandoc.adoc

Kramdoc(On Docker)

一方で,Asciidocの開発寄りで作られているのがKramdocです。

github.com

Rubyで動くらしいので手元にRuby環境がある場合はgemでインストール出来ます。


自分はRuby使いでない&環境構築に興味がないのでDockerを用いていきます。

asciidoctor/docker-asciidoctor 環境でのKramdoc

DockerでAsciidoc環境構築をしたことがあるならばasciidoctor/docker-asciidoctorのイメージを落としている方も多いと思いますが,Kramdocは現状asciidoctor/docker-asciidoctor環境にインストールされているので新規インストールの問題がないのでこちらを使っていきます。

変換コマンドは以下のとおりです。

docker run --rm -v $(pwd):/documents/ asciidoctor/docker-asciidoctor kramdoc  --wrap=ventilate --format=GFM  sample.md

$(pwd)の所はコマンドプロンプトの場合"%CD%"でも動くとは思います。wsl2で動かしている方は先頭にwslをつけるのをわすれずに。

オプションについては下記を参照しました。つけなくてもそこまで支障があるわけではなかったですが念の為。

matthewsetter.com

html変換

adocファイルが出来たらhtml変換も同様に以下のコマンドで変換できます。

docker run --rm -v $(pwd):/documents/ asciidoctor/docker-asciidoctor asciidoctor <sample.adoc> -r asciidoctor-diagram -a allow-uri-read -a data-uri -a toc=left

このオプションとして以下を追記しています。

  • data-uri:画像など埋め込み
  • toc=left:目次を左に
  • asciidoctor-diagram:PlantUMLの図などを埋め込む

見た目はこんな感じになります。

f:id:ossyaritoori:20201016210600p:plain

まとめ

Asciidocは環境構築やら書き方やらちょっとハードル高いですが,Docker環境があれば結構気軽に使えると思います。

PandocとKramdocのどちらがいいか?に関してはまだ自分では結論が出ていませんが,どちらでも実用に耐えうるとは思っています。

  • Pandoc
    • 言わずとしれた万能コンバータ
    • リストまわりの挙動に不安。バージョンによって大きく挙動が変わるので要注意
    • 半角スペースで改行を入れられてしまうことがあるのはちょっといただけない
  • Kramdoc
    • きれいに変換できる。
    • リンクや特殊文字が絡むと微妙
    • 開発速度にちょっと期待しづらいか?

変換結果詳細比較

下記リポジトリにて変換結果とコマンドなどを載せているのでご参考までに。

github.com

バグ報告など

とりあえず,下記リポジトリにも書いていますが,いくつかバグがあったのでメモしておきます。

GitHub - YoshiRi/MarkdownToAsciidoc: Test project for markdown to asciidoc conversion

なお,Kramdocのバージョンは1.01でした。

>> wsl docker run --rm asciidoctor/docker-asciidoctor kramdoc --version
kramdoc 1.0.1

PHPシンタックスハイライトをつけようとするとエラーが出る

xmlのコメントを変換する機能でエラーがでる。以下がそのエラー文。

/usr/lib/ruby/gems/2.7.0/gems/kramdown-asciidoc-1.0.1/lib/kramdown-asciidoc/converter.rb:99:in `convert': undefined method `convert_xml_pi' for #<Kramdown::AsciiDoc::Converter:0x0000561a13adec28> (NoMethodError)
Did you mean?  convert_li

デバッグの結果以下が原因となった部分。

<?php if (is_tag()){ $posts = query_posts($query_string . '&showposts=20'); } ?>

バージョンによっては改善しているかもしれない。

リンク以降の改行がおかしい

  • 定義参照リンク以降の変換がバグる。
    • 定義参照リンクは別口で書くなどして対応するしか?