iPX社員によるブログ

iPX社員が"社の動向"から"自身の知見や趣味"、"セミナーなどのおすすめ情報"に至るまで幅広い話題を投下していくブログ。社の雰囲気を感じ取っていただけたら幸いです。

SKKについて

近況

ひさしぶりの投稿になります。砂子です。年の瀬の、寒さの身にしみる季節となりました。12/09に本社の引越しがあり、真新しいオフィスでの勤務に励んでおります。 さて、皆様は日本語を入力する際にどのIMEを使用しているでしょうか?OSに標準で備わっているIMEを使ている方が多いはずですが、メジャーなところでは以下のような選択もあります。

本記事では私がEmacsで使用してる入力方式SKKの簡単な紹介とその機構の一部である辞書サーバの実装を試みたのでその紹介を行います。

SKKとは

SKKとは Simple Kana to Kanji conversion program の略となります。詳細はWikipediaなどに譲るとしてその大きな特徴はかなと漢字の区切りをユーザが指定することでしょう。

具体例でみてみましょう。「猫が部屋で寝ている。」という文章をWindowsIMEで入力することを考えます。打鍵するキーを英字(a-zA-Z)とスペース(␣)で表すと下記のようになります。(変換は一回で完了とする)

nekogaheyadeneteiru.␣

SKKでは下記のようになります。

Neko␣gaHeya␣deNeTeiru.

SKKの打鍵には所々に大文字の英字があります。これは2つの規則によるものです。一つ目の規則は漢字の始まりであることです。「猫が部屋で寝ている。」では漢字「猫」、「部屋」、「寝」の始まりのかな「ね(猫)」、「へ(部屋)」、「ね(寝)」に対応しています。2つ目の規則は漢字の送り仮名の始まりであることです。「猫が部屋で寝ている。」では「て」に対応します。

このようにして漢字とかなの境界を明示的に入力することで変換を行うときに曖昧さがなくなり変換する文節を間違えることはありません。SKK以外であると文を入力後に形態素解析などの技術を利用して文節を推測するため時には予期しない変換が行われていることがあります。

ちなみにSKKは入力方式の名称で具体的なIMEとしては下記のようなものがあります。 * AquaSKK(Mac) * SKK日本語入力FEP(Windows)

DDSKKとは

DDSKK(Daredevil SKK)はEmacsで専用のIMEです。つまり、Elispで実装されたEmacsでの日本語入力のみを実現するためのIMEです。

なぜOS標準のIMEを使わず、そんなIMEが使うのか?Emacsは非常に古いソフトウェアであるせいか、OSのIMEでの入力がダメな場合があるためです。いままでFedora、Arch、Manjaro、UbuntuのさまざまなLinuxディストリビューションでインストールされたEmacsIMEを使いました。しかし、Emacs内で日本語の入力を試みると変換候補があらぬ位置に表示されたり、そもそも反応しないことも多々ありました。さらに最近ではWindow10上でWSL+X410でEmacsを使っていますが、全角/半角キーを押すと`(バッククオート)が入力される始末です。

以上の理由からElispで実装されEmacsのみに依存しているDDSKKを使用しています。

辞書サーバ(SKKserv)

IMEは辞書が必要です。入力されたかなに対応する漢字を保持するためです。設定なので会社固有のキーワードを登録したり、外部の辞書をインポートして使用している方もいるかと思います。

SKKにも辞書がありファイル形式で配布されてます。しかし、もう一つの方式としてTCP通信を利用してサーバからかなに対応する漢字の候補を取得するこというものがあります。 なぜ、こんな機能があるかといえば恐らくですが昔のPCのスペックが悪い、Emacsがマルチスレッドに対応していないなどが理由と推測します。

SKKservのクライアントとの通信プロトコルは公開されており、下記ページにも記載があります。 * https://ja.osdn.net/projects/pysocialskkserv/wiki/SKKServ

これをRust言語で実装し、EmacsのDDSKKと通信を試みます。

SKKServ Rust実装

辞書を作るなどは難しいので「えんしゅうりつ」を変換すると実際の値「3.14159265359」を変換候補として返却するSKKservの実装です。

主に気をつけるのはクライアントとの文字列のやり取りがEUC_JPであることです。

use encoding_rs::*;
use std::convert::From;
use std::io;
use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};

fn handler(mut stream: TcpStream) -> Result<String, io::Error> {
    println!("Connection from {}", stream.peer_addr()?);
    let mut buffer = [0; 1024];

    let _nbytes = stream.read(&mut buffer)?;
    let (cow, _, _) = EUC_JP.decode(&buffer[..]);

    let msg = String::from(cow);

    let command = msg.chars().next().unwrap();

    let mut response = "".to_string();

    match command {
        '0' => {}
        '1' => {
            if msg[1..].starts_with("えんしゅうりつ") {
                response = format!("1/{}/\n", 3.141_592_653_59f64);
            } else {
                response = "4\n".to_string();
            }
        }
        '2' => response = "Software Name.Major.Minor".to_string(),
        '3' => response = "localhost:127.0.0.1:".to_string(),
        '4' => {
            if msg[1..].starts_with("えんしゅうりつ") {
                response = format!("1 {}\n", 3.141_592_653_59f64);
            } else {
                response = "4\n".to_string();
            }
        }
        _ => {}
    }

    let (cow, _, _) = EUC_JP.encode(&response);
    let _ = stream.write_all(&cow);
    stream.flush()?;

    Ok(command.to_string())
}

fn main() -> io::Result<()> {
    let listener = TcpListener::bind("127.0.0.1:8001")?;

    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                handler(stream).unwrap();
            }
            Err(e) => eprintln!("{}", e),
        }
    }

    Ok(())
}

通信

実際にEmacsのDDSKKと通信するためにEmacsに書き設定を追加し、上記実装を実行しました。

(setq skk-server-host "127.0.0.1")
(setq skk-server-portnum 8001)

結果「えんしゅうりつ」が「3.14159265359」に変換することを確認できました。

結び

令和になってもEmacsネタです。令和が終わるころまでにはVisualStudioCodeに移行しようと考えています。

普段使っているツールの仕組みを知るのも面白いものですね。ではまた。

高次元写像を見る

とある朝のこと。
いつものようにスマホのアラームが鳴っていた。
そしていつものように私はスマホの画面をスワイプしてアラームを止めようとした。
いつもと違うのは、スワイプしてもアラームが鳴り止まなかったこと。
私は「これはここからじゃないと止められない」と咄嗟に思った。

・・・・・ここ?

私はいつもと違う次元に写像されていた。
”ここ”は「高次元」領域だった。
いつもの「現実次元」に戻り、
いつものようにスマホの画面をスワイプしてアラームを止めた。



機械学習に取り組まれている方ならわかるだろう。
状態を高次元領域へ特徴量として写像し観測することが起きていたのだ。



実に興味深いと思った方へ。
是非見ていただきたいアニメ作品がある。
正解するカド」という作品だ。
この作品で、多次元に自身を写像するシーンが存在する。
きっと、私のこの経験を容易に想像できると思う。


それでは良い高次元ライフを。

iPX TCD
郡 伴興[Tomooki Koori]
IFRIT

【OpenCV】K-meansクラスタリングを用いた色の量子化【Python】

 こんにちは。
 最近読んだ論文の要約を書こうとしましたが挫折しました、安藤です。
 そういうことってよくありますよね、はは。


 今回はOpenCVライブラリのK-means法を使って色の量子化を行いたいと思います。
 量子化というとむずかしく聞こえてしまいますので、はじめにどのような画像をつくれるのか見てみましょう。

 目標はこんな感じの画像を作ることです。

f:id:ipx-writer:20191206174514j:plain
出典:http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html
 左上が元画像、それ以外の画像はK個の色のみになるように量子化を行っています。簡単に言うと、似ている色をひとつのまとまりに分けて色付けをし直すことです。それぞれのクラスタに分類された領域には、その領域内の平均の色を割り当てています。画像のノイズ除去なんかにも使えそうですね。

  • K-meansとは

 機械学習分野における教師なし学習で、クラスタリングを行うアルゴリズムです。くわしい説明は下記のリンクなんかがわかりやすかったので、こちらを参照してみてください。
k-meansとk-means++を視覚的に理解する~Pythonにてスクラッチから~ - 医療職からデータサイエンティストへ

 入力データとして1ピクセルあたりのRGB値を1データ(3次元ベクトル)として、K-meansクラスタリングを行いました。

  • 実装

 ここの最後の項のコードを基本にして、コメントを付け加えた形です。クラスタ数を2,4,6,8で設定した際の画像を出力します。

import numpy as np
import cv2 as cv


"""
画層の読み込みから前処理
"""
# 画像の読み込み
img = cv.imread('lena.jpg')
# 画像を2次元配列にreshape(row:ピクセル数、col:3(RGB))
img_1d = img.reshape((-1, 3))

# np.float32に型変換
img_1d = np.float32(img_1d)


"""
K-meansの実行
"""
# オプションフラグ
# ここではエポックごとのクラスタ中心移動量に対する閾値と最大エポック数を指定
criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 10, 1.0)

# k : 分割したいクラスタ数(2,4,6,8)
for k in range(2, 9, 2):

    # K-meansの実行
    # label  : 入力データに対するクラスタ番号配列
    # center : クラスタ中心 この場合ではK個の3次元配列が出力される
    _, label, center = cv.kmeans(img_1d, k, None, criteria, 10, cv.KMEANS_RANDOM_CENTERS)


    """
    出力の変換
    """
    # クラスタ中心になるRGB値をnp.uint8型に変換
    center = np.uint8(center)
    # 出力ラベルが2次元配列になっているので1次元にreshape
    label = label.flatten()
    # クラスタ番号にひもづくクラスタ中心RGB値を割り当て
    output_img = center[label]
    # 元画像と同じshapeになるようにreshape
    output_img = output_img.reshape((img.shape))


    """
    出力画像の表示と保存
    """
    # 表示するウィンドウの名前
    window_name = 'output_img_K{}'.format(k)
    # 表示するウィンドウの設定
    cv.namedWindow(winname = window_name, 
                   flags   = cv.WINDOW_NORMAL)
    # 画像の表示
    cv.imshow(winname = window_name, 
              mat     = output_img)
    cv.waitKey()
    cv.destroyAllWindows()

    # 出力画像の名前
    output_img_name = "result_K{}.png".format(k)
    # 画像の保存
    cv.imwrite(filename = output_img_name,
               img      = output_img)
  • 結果

無処理

f:id:ipx-writer:20191209114543j:plain
入力画像(無処理)
K = 2
f:id:ipx-writer:20191209114018p:plain
K = 2
K = 4
f:id:ipx-writer:20191209114021p:plain
K = 4
K = 6
f:id:ipx-writer:20191209114023p:plain
K = 6
K = 8
f:id:ipx-writer:20191209114027p:plain
K = 8

これをつかえば映える画像も作れるかもしれませんね!

  • 参考

labs.eecs.tottori-u.ac.jp

趣味の話 part2

ご挨拶

ななつぼし、ゆめぴりか、ふっくりんこ!
こんにちは、お米大好きiPX川口です。

趣味の話

今回も私の数少ない趣味、旅行の話をします。
北陸新幹線が開通して以来ずっと行きたいと思っていました金沢へ夏季休暇に初めて行ってきました。(2019年8月)

日程など

日程:2泊3日
移動手段:新幹線+バス
観光プラン:
 1日目
  金沢駅
  昼食 近江町市場
  兼六園
  ひがし茶屋町
  夕食 居酒屋
 2日目
  昼食 近江町市場
  長町武家屋敷跡
  金沢城公園
  金沢21世紀美術館
  夕食 旅館
 3日目
  昼食 金沢駅
  お土産物色

旅の目的

私の旅行の目的は食事6:観光4くらいの比率なので、近江町市場を軸に観光名所を回りました。
観光名所は巡回バスがあったのでそれに乗りました。
金沢駅の案内所で観光バス1日乗り放題券(500円)が購入できます。←ここ重要

写真

1日目

金沢駅
12:30頃 金沢駅に到着。
さっそく徒歩で近江町市場へ。
f:id:ipx-writer:20191103233039j:plain

近江町市場
13:00 到着したころには汗だくだくでした笑
駅からバスが出ているのでそちらをおすすめします。(特に真夏は)
お盆時期なのでたくさんの観光客がいました。(モザイク入れるの大変でした)
f:id:ipx-writer:20191103232904j:plain

近江町市場 店名失念
近江町市場内の建物の2階に飲食店が複数あり、そのうちの1つです。
待ち時間は1時間弱くらい。
f:id:ipx-writer:20191103232909j:plain
海鮮丼のお値段は4,100円でした。(特上にしたのでお高めです)
写真にゴミが写りこんでます汗
f:id:ipx-writer:20191103232913j:plain

兼六園
個人的には一番よかったです。(写真も一番多い)
とても暑かったので兼六園タオルを買いました。
苔が立派で興奮しました。
自宅で栽培できる兼六園の苔セット的なものがあれば買ったかもしれません。
f:id:ipx-writer:20191103232940j:plainf:id:ipx-writer:20191103232946j:plainf:id:ipx-writer:20191103232950j:plainf:id:ipx-writer:20191103233010j:plainf:id:ipx-writer:20191103233012j:plainf:id:ipx-writer:20191103233016j:plain

ひがし茶屋町
ここも定番ですね。
通りにお土産屋さんがたくさんありました。
f:id:ipx-writer:20191103233024j:plainf:id:ipx-writer:20191103233020j:plain

居酒屋 たかじ(金沢駅近く)
カウンターにお邪魔しました。
写真は加賀野菜のサラダです。
他にも美味しいものがいっぱいありましたが、食い気に負け写真撮り忘れました。
f:id:ipx-writer:20191103233033j:plain

2日目

近江町市場
11:00 観光客は多いが昨日よりは少ない印象。
12:00過ぎると混むのかもしれません。
市場では購入したものをその場で立ち食いできるようテーブルなどが用意されてました。
f:id:ipx-writer:20191103233043j:plain
f:id:ipx-writer:20191103233053j:plainf:id:ipx-writer:20191103233102j:plainf:id:ipx-writer:20191103233109j:plain

近江町市場 近江町市場寿し
前日は海鮮丼だったのでお寿司。
お味噌汁付きで3,000円でした。
f:id:ipx-writer:20191103233113j:plain

長町武家屋敷跡
f:id:ipx-writer:20191103233121j:plainf:id:ipx-writer:20191103233125j:plain

金沢城公園
f:id:ipx-writer:20191103233137j:plain

金沢21世紀美術館
チケット購入が大行列だったので、外のオブジェを観ただけです。(たしか1時間以上待ち)
写真は割愛。

旅館
外観と食事と能舞台
1年に1,2回能を見学する会があるそうです。
f:id:ipx-writer:20191103233148j:plain
f:id:ipx-writer:20191103233153j:plainf:id:ipx-writer:20191103233157j:plainf:id:ipx-writer:20191103233201j:plain
f:id:ipx-writer:20191103233205j:plain

3日目

金沢駅 金沢まいもん寿司
金沢おでんと悩みましたが結局お寿司を食べました。
お値段は3,280円でした。
f:id:ipx-writer:20191103233209j:plain

まとめ

お盆の金沢は普通に暑い(タオル必須)
金沢駅で観光バス券を購入すべし
魚が新鮮でおいしい
2泊3日あれば定番観光地はだいたい回れる(観光地が金沢駅付近に密集しているので観光メインのプランを立てれば10か所くらいは回れそう)

結び

2泊3日あれば十分に金沢満喫できると思います。
みなさまもいかがでしょうか。

以上、ご覧いただきありがとうございました。

Nvidia Isaacの概要

皆様、はじめまして。
入社7か月目の深澤と申します。

前職では鉄道の施工監督の仕事を行っていました。
鉄道の工事とは言ってもレールや信号、駅、など様々な工事があります。
そんな多種多様な工事の中で私は架線関係の施工監督を行ってました。
下記の写真で言うと赤く囲っている部分ですね。
鉄道業界からの転職で、まだまだ分からないことがありご迷惑をお掛けしますが
何卒宜しくお願い致します。

f:id:ipx-writer:20191025100207j:plain:w360


さて、挨拶はこれぐらいにして、本題に入りたいと思います。

概要

第2回オートモーティブワールド@名古屋で弊社はNvidia Isaacというものを使ってロボットのシミュレーションの展示を行いました。
今回はこのNvidia Isaacがどんなものなのかお話ししていきたいと思います。
Nvidia Isaacをざっくり説明しますと2019年1月にリリースされたロボティクス開発者向けのロボットエンジンやライブラリが組み込まれているツールキットです。
このツールキットを使うことで、今まで時間が掛かったロボットの制御部分の構築が手軽に作成することが可能です。
Nvidia IsaacではIsaacSDKとIsaacSimという2つのツールに分かれており、それぞれ制御部分とシミュレーション用のツールとなっています。

developer.nvidia.com
またようなツールで有名なものですとROS(Robot Operating System)というものがあります。
こちらも同様にロボティクス開発者のためのライブラリが公開されています。
wiki.ros.org



IsaacSDK

IsaacSDKではロボットの制御を行う部分を開発することができます。
IsaacSDKにはGEMと呼ばれる高品質な機能ライブラリがあり、ナビゲーションスタックやタグ認識、物体認識、音声認識といった機能があらかじめ用意されています。
これらの機能を組み合わせることで様々なロボットを作成することができます。
ROSと比較するとIsaacSDK自体に備わっているライブラリの数は少ないですが、ROSとブリッジをしてROSにあるライブラリを使用することも可能であるため、そこまで不便しません。
また、Nvidiaのホームページを見てみると以下のようなポーズや視線、ジェスチャーの検知などについての画像があるため、今後追加されていくと思います。
ライブラリの機能が増えれば、今まで以上にロボット開発に様々なアプローチができそうなのでとても楽しみです。
f:id:ipx-writer:20191025101106j:plain:w360
https://www.nvidia.com/ja-jp/deep-learning-ai/industries/robotics/

IsaacSim

IsaacSimはIsaacSDKで作成したロボットの動作確認をするためにシミュレーション環境を作成するツールです。
IsaacSimはゲームエンジンであるUE4(Unreal Engine4)をベースとして作成されています。
そのため、IsaacSimではMarketPlaceで購入したアセットやブループリントを使った環境の構築が可能です。
UE4に詳しい人が環境構築すれば、様々なテストケースでのロボットシミュレーションができそうです。
ロボット向け機械学習の学習環境の構築などにはよいかもしれません。
デフォルトで用意されている環境は倉庫、オフィス、病院の合計3つあり、かなりリアルに作られています。
・倉庫
f:id:ipx-writer:20191025142313p:plain:w360
・オフィス
f:id:ipx-writer:20191025142517p:plain:w360
・病院
f:id:ipx-writer:20191025142638p:plain:w360
人間をスポーンする機能をついているので、そのうちジェスチャー検知の機能があればそこに向かわせるといったことも可能だと思います。
ROSの動作検証で使われる3DシミュレーションツールとしてGazeboというツールがあるのですが、そちらに比べるとかなり動作が軽く、大量のアクターを出現させてもスムーズに動きます。
さすがゲームエンジンで使われているだけのことはあります。

まとめ

Isaacはロボティクス開発でシミュレーションを行いたい場合、とても有用なツールだと思います。
しかし、ライブラリの数はROSと比べるとまだ数が少ないためROSブリッジを使い、併用しながら実装していくか、ライブラリの機能の追加を待つ必要があります。
まだ、不十分なところがありますが将来性はあると思いますので今後も動向を見守りつつ情報の発信をしていきたいと思います。