LoginSignup
5
3

More than 5 years have passed since last update.

pykakasiとMeCabを使ってモールス信号変換器を作る

Last updated at Posted at 2018-08-20

CSGAdventCalendar 9日目
最近ラズパイを使ってモールス符号変換器を作ったので、備忘録。
IMG_0956.JPG

概要

入力した文字列をモールス信号に変換、それをRaspberry PiのLEDを光らせて遊びました。
その際にpykakasiとMeCabを使ってアルゴリズムを組んだので備忘録です。
Githubのリンクも載せておきます。
環境はMac, python3.5.2です。

モールス信号とは

文字や記号を表象する方法のひとつ。電信による伝達を目的として発明され、短点とその3倍の長さを持つ長点の組み合わせにより文字や記号を表す。ラテン文字を基礎とした国際モールス信号の他、和文モールス信号のように各国の文字に対応したモールス信号が考案されている。

みなさんご存知SOSのあれです。
日本語やアルファベットを「トン」「ツー」の二つの記号で表すことができます。
そんなモールス信号にもいくつかのルールがあります。

  1. 長点1つは短点3つ分の長さ
  2. 文字と文字の間には短点3つ分をあける
  3. 単語と単語の間には短点7つ分あける

この他にもSOSは例外的に連続して打つなどルールはありますが、
今回は上記の3つをルールを中心にしていきます。

やるべきこと

目標は日常的にSNSで書いている文章をモールス信号に変換できるようにすることです。
そのためにはやるべきことがいくつかあります。

  1. 漢字をひらがなにする(漢字は変換できない)
    1. pykakasiを使って変換する
  2. 自動的に単語で区切る(普通文章を書くときに単語では区切らない)
    1. MeCabを使って形態素解析で単語ごとに区切る
  3. 変換のための条件分岐をひたすら書く

pykakasi

pykakasiは日本語の漢字仮名交じり文を平仮名やローマ字綴りの文に変換するプログラムKAKASIのPythonバージョンです。
pipでインストールしてください。

$ pip install six semidbm
$ pip install pykakasi

私は下記のように使いました。
setModeの引数で変換の形を決めることができます。

call.py
from pykakasi import kakasi
pic = "本日は晴天なり"
...
...
...
k = kakasi()
k.setMode("K", "H")  # カタカナをひらがなに
k.setMode("J", "H")  # 漢字をひらがなに
conv_k = k.getConverter()
pic = conv_k.do(pic)
print(pic) # ほんじつはせいてんなり

インストールや使い方は公式のリポジトリに載っています。

MeCab

MeCabはオープンソースの形態素解析エンジンです。
Mecabを選んだ理由は下記の二つです。

  1. 各種スクリプト言語でバインディングされていること
  2. 他の形態素解析エンジンより高速であること

MeCabを使い、入力された文章を自動で単語に区切ります。
(正確にはMeCabは文章を形態素で区切るので、単語では区切りません。)
インストールはMeCab本体とその辞書、そしてPythonでバインディングしたライブラリを入れます。

$ brew install mecab #本体のインストール
$ brew install mecab-ipadic #辞書のインストール
$ pip install mecab-python3 #ライブラリのインストール

実際には下記のように使いました。

call.py
import MeCab
pic = "本日は晴天なり"
try:
    m = MeCab.Tagger("-Owakati")
    pic = m.parse(pic)
    pic = pic.strip()  # 先頭と末尾の空白を削除
    pic = pic.replace(' ', '_')  # 単語間に開けた空白を変換
except RuntimeError:
    pic = ""
print(pic) #本日_は_晴天_なり

こちらは「MeCab (和布蕪)とは」と「Python3からMeCabを使う」が参考になりました。

実際に使ってみる

上記のpykakasiとMeCabを使った変換器が下記のコードになります。
import morseはWeb上にあったモールス信号のコンバータを改変したものです。
コードはこちらにあります。

call.py
# coding:utf-8
from pykakasi import kakasi, wakati
import MeCab
import morse


def convert(pic):
    pic = ''.join(pic.split())  # 空白の削除

    # MeCabによる形態素解析
    try:
        m = MeCab.Tagger("-Owakati")
        pic = m.parse(pic)
        pic = pic.strip()  # 先頭と末尾の空白を削除
        pic = pic.replace(' ', '_')  # 単語間に開けた空白を変換
    except RuntimeError:
        pic = ""

    # pykakasiによるカタカナ・漢字のひらがなへの変換

    k = kakasi()
    k.setMode("K", "H")  # カタカナをひらがなに
    k.setMode("J", "H")  # 漢字をひらがなに
    conv_k = k.getConverter()
    pic = conv_k.do(pic)

    context = ""
    for c in pic:
        context += c + "~"
    context.strip()

    ans = ""
    for c in context:
        ans += morse.s2m(c)

    return ans

これを下記のように実行させます。

Main.py
import call

txt = "本日は晴天なり"
txt = call.convert(txt)
print(txt)

すると下記のようにちゃんと変換できているのがわかります。
-・・ ・-・-・ --・-・ ・・ ・--・   -・・・   ・---・ ・- ・-・-- ・-・-・   ・-・ --・
後は、文字列で条件分岐をして光らせるなり音を鳴らす等すれば、完成です。

RaspberryPi LED発光のサンプル

light.py
import RPi.GPIO as GPIO
import time
import call

# それぞれの処理の秒数
dot = 0.33333333  # トン
stick = dot*3  # ツー
space = dot*3  # 空白
between_sleep = dot/3 #「トン」と「ツー」の間の時間

txt = "本日は晴天なり"

# 光らせる
def light_up(sec):
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(23, GPIO.OUT)
    GPIO.output(23, GPIO.HIGH)
    time.sleep(sec)
    GPIO.cleanup()

# 光らせない(何もしない)
def light_down(sec):
    time.sleep(sec)
    pass

for c in call.convert(txt)
    if c == '・':
        light_up(dot) #1拍点灯
    if c == 'ー':
        light_up(stick) #3拍点灯
    if str[num] == ' ':
        light_down(space) #3拍消灯
    time.sleep(between_sleep)

まとめ

kakasiやMeCabといった既存の変換器を使うことで簡単にモールス信号変換器を作ることができました。
pykakasiのwakatiを使えばMeCabは必要なかったのですが、勉強のために色々触ってみました。
テキスト処理はしっかりしてるはずなので次はこれをAmazon EchoのSkillと組んで遊びたいです。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3