福野泰介の一日一創 - create every day

デジタル色メガネで見よう colorsight - テクノロジーと高専生とアフリカと

2018/06/02
#megane #kosen #IchigoJam #codefor #JS #africa 

Code for Sabae発、WebMeganeがCode for Nerimaに飛び火。
WebMegane(色覚体験)

WebMegane、色を文字化してみました。

colorsightsrc on GitHub in JS
時計表示のおまけ付き! 簡単なJavaScriptで改造可能です!


マダガスカル、モロッコからの留学生へIchigoSodaレクチャーする高専生!


夜は高専インターンOG/OBと!

高専生による高専生のための、最高のインターンを目指す、jig.jpインターン、申込み期限間近!
学生インターンプログラム2018~全国高専生向けjig.jpインターンシップ募集開始のお知らせ~

QRコードが読め、ズームでき、写真が撮れるメガネ開発!オープンソースなスマホMR in Swift4

2018/05/26
#swift #megane 

外カメラ x スマホVR = デジタルメガネ

JSで手軽なWebMeganeもオススメながら、iPhoneネイティブアプリとして作ると、顔認識や、QRコード認識などが高速で楽しい!

リアルタイムにQRコード内容をデコードして、視界をオーバーレイ(上書き)するメガネができた。
megane - qrdetector on GitHub」 Swift4で実装

ウィンクシャッターが便利だったGoogle Glassのように、手軽に写真撮影もついでに実装。
ボリュームダウンキーで、シャッター(初回のみダイアログがでるので、VRにする前に押しておこう)
ボリュームアップキーで、視界をズームすることもできる(現在は、1920x1080の画像をデジタルズーム)

こちら「オタマートで売ってるVRゴーグル」の一番安いもの。ボリュームアップダウンが上からアクセスできる!
ボリュームアップダウンキーのついたイヤホンを接続すると、手元でも操作できるようになって便利。
デジタルメガネなUXづくり、いろいろ試していきましょう。

鯖江の道の駅、西山公園前のバス停。日本語表記しかない標識にQRコードをつけておけば、リアルタイムに見ている人の母国語に変換できそう。

Let's hack your sight!

AppDelegate.swift

import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { return true } func applicationWillResignActive(_ application: UIApplication) { } func applicationDidEnterBackground(_ application: UIApplication) { NotificationCenter.default.post(name: NSNotification.Name(rawValue: "applicationDidEnterBackground"), object: nil) } func applicationWillEnterForeground(_ application: UIApplication) { NotificationCenter.default.post(name: NSNotification.Name(rawValue: "applicationWillEnterForeground"), object: nil) } func applicationDidBecomeActive(_ application: UIApplication) { } func applicationWillTerminate(_ application: UIApplication) { } }

ViewController.swift

// // ViewController.swift // megane, QR code detector glass with VR goggle // // CC BY taisukef on 2018/05/24. // http://fukuno.jig.jp/2133 // import UIKit import AVFoundation import MediaPlayer class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate { override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor.black self.imageView1 = UIImageView() self.imageView2 = UIImageView() let w = self.view.frame.width let h = self.view.frame.height let w2 = w / 2 let h2 = w2 * 1080 / 1920 let y = (h - h2) / 2 self.imageView1.frame = CGRect(x:0, y:y, width:w2, height:h2) self.imageView2.frame = CGRect(x:self.view.frame.width / 2, y:y, width:w2, height:h2) self.view.addSubview(self.imageView1) self.view.addSubview(self.imageView2) self.initNotificationsFromAppDelegate() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } var input:AVCaptureDeviceInput! var output:AVCaptureVideoDataOutput! var session:AVCaptureSession! var camera:AVCaptureDevice! var imageView1:UIImageView! var imageView2:UIImageView! override func viewWillAppear(_ animated: Bool) { self.configureCamera() self.listenVolumeButton() } // notifications foreground and background func initNotificationsFromAppDelegate() { NotificationCenter.default.addObserver(self, selector: #selector(type(of: self).viewWillEnterForeground(notification:)), name: NSNotification.Name(rawValue: "applicationWillEnterForeground"), object: nil) NotificationCenter.default.addObserver(self, selector: #selector(type(of: self).viewDidEnterBackground(notification:)), name: NSNotification.Name(rawValue: "applicationDidEnterBackground"), object: nil) } @objc func viewWillEnterForeground(notification: NSNotification?) { print("foreground") self.listenVolumeButton() } @objc func viewDidEnterBackground(notification: NSNotification?) { print("background") self.removeVolumeButton() } // override func viewDidDisappear(_ animated: Bool) { session.stopRunning() for output in session.outputs { session.removeOutput(output) } for input in session.inputs { session.removeInput(input) } session = nil camera = nil } let DETECT_QRCODE = false func configureCamera() { session = AVCaptureSession() // iPhone Xで実験 //session.sessionPreset = AVCaptureSession.Preset.cif352x288 // 34% 荒い //session.sessionPreset = AVCaptureSession.Preset.vga640x480 // 47% 4:3 なかなかきれい //session.sessionPreset = AVCaptureSession.Preset.iFrame1280x720 // CPU50% 16:9 かわらない? //session.sessionPreset = AVCaptureSession.Preset.hd1280x720 // CPU50% 16:9 きれい session.sessionPreset = AVCaptureSession.Preset.hd1920x1080 // CPU88% 16:9 かわらない? iPhone6でもQRcode offならOK! //session.sessionPreset = AVCaptureSession.Preset.hd4K3840x2160 // CPU93% 16:9 かわらない? QRcode offなら実用的 camera = AVCaptureDevice.default( AVCaptureDevice.DeviceType.builtInWideAngleCamera, for: AVMediaType.video, position: .back) // position: .front do { input = try AVCaptureDeviceInput(device: camera) } catch let error as NSError { print(error) } if (session.canAddInput(input)) { session.addInput(input) } output = AVCaptureVideoDataOutput() // AVCapturePhotoOutput() 写真用 output?.videoSettings = [kCVPixelBufferPixelFormatTypeKey as AnyHashable : Int(kCVPixelFormatType_32BGRA)] as! [String : Any] let queue:DispatchQueue = DispatchQueue(label: "myqueue", attributes: .concurrent) output.setSampleBufferDelegate(self, queue: queue) output.alwaysDiscardsLateVideoFrames = true // 間に合わないものは処理しない if (session.canAddOutput(output)) { session.addOutput(output) } session.startRunning() } var zoom:CGFloat = 1.0 func captureOutput(_: AVCaptureOutput, didOutput: CMSampleBuffer, from: AVCaptureConnection) { // from.videoOrientation = .portrait //デバイスの向きを設定、縦の時 from.videoOrientation = .landscapeLeft //デバイスの向きを設定、landscape left の時 DispatchQueue.main.sync(execute: { var image = self.imageFromSampleBuffer(sampleBuffer: didOutput) image = resizeImage(image: image, ratio: zoom) if DETECT_QRCODE { image = drawQR(image: image) } self.imageView1.image = image self.imageView2.image = image }) } func resizeImage(image: UIImage, ratio: CGFloat) -> UIImage { if ratio == 1.0 { return image } let iw = image.size.width / ratio let ih = image.size.height / ratio let size = CGSize(width: iw, height: ih) UIGraphicsBeginImageContext(size) image.draw(in: CGRect(origin: CGPoint(x:-(image.size.width - iw) / 2, y:-(image.size.height - ih) / 2), size: image.size)) let resimage = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() return resimage } func drawQR(image: UIImage) -> UIImage { UIGraphicsBeginImageContext(image.size) let rect = CGRect(x:0, y:0, width:image.size.width, height:image.size.height) image.draw(in: rect) let g = UIGraphicsGetCurrentContext()! g.setStrokeColor(UIColor.white.cgColor) g.setLineWidth(1) let font = UIFont.boldSystemFont(ofSize: 14) let textStyle = NSMutableParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle let textFontAttributes = [ NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: UIColor.black, NSAttributedStringKey.paragraphStyle: textStyle ] // 顔認識もおもしろい // let detector : CIDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options:[CIDetectorAccuracy: CIDetectorAccuracyLow] )! // 読める四角は今のところひとつだけ // let detector : CIDetector = CIDetector(ofType: CIDetectorTypeRectangle, context: nil, options:[CIDetectorAccuracy: CIDetectorAccuracyHigh, CIDetectorAspectRatio: 1.0] )! let detector : CIDetector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options:[CIDetectorAccuracy: CIDetectorAccuracyHigh] )! let features : NSArray = detector.features(in: CIImage(image: image)!) as NSArray if features.count > 0 { for feature in features as! [CIQRCodeFeature] { var rect: CGRect = (feature as AnyObject).bounds rect.origin.y = image.size.height - rect.origin.y - rect.size.height // QRコードを上書き! g.beginPath() g.setFillColor(UIColor.white.cgColor) g.addRect(rect) g.fillPath() feature.messageString?.draw(in: rect, withAttributes: textFontAttributes) } } let resimage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return resimage! } func imageFromSampleBuffer(sampleBuffer: CMSampleBuffer) -> UIImage { let imageBuffer: CVImageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)! CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) let baseAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0) let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer) let width = CVPixelBufferGetWidth(imageBuffer) let height = CVPixelBufferGetHeight(imageBuffer) let colorSpace = CGColorSpaceCreateDeviceRGB() let bitmapInfo = (CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue) let context = CGContext(data: baseAddress, width: width, height: height, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo) let imageRef = context!.makeImage() CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) return UIImage(cgImage: imageRef!) } // volume switch var initialVolume = 0.0 var volumeView: MPVolumeView? func listenVolumeButton() { volumeView = MPVolumeView(frame: CGRect(x:-3000, y:0, width:0, height:0)) view.addSubview(volumeView!) let audioSession = AVAudioSession.sharedInstance() do { try audioSession.setActive(true) let vol = audioSession.outputVolume initialVolume = Double(vol.description)! if initialVolume > 0.9 { initialVolume = 0.9 } else if initialVolume < 0.1 { initialVolume = 0.1 } } catch { print("error: \(error)") } audioSession.addObserver(self, forKeyPath: "outputVolume", options: NSKeyValueObservingOptions.new, context: nil) } func removeVolumeButton() { AVAudioSession.sharedInstance().removeObserver(self, forKeyPath: "outputVolume") volumeView?.removeFromSuperview() } override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { if keyPath == "outputVolume" { let volume = (change?[NSKeyValueChangeKey.newKey] as! NSNumber).floatValue let newVolume = Double(volume) if newVolume > initialVolume + 0.05 { if let view = volumeView?.subviews.first as? UISlider { // volume up pressed view.value = Float(initialVolume) if zoom < 12.0 { zoom *= 1.2 } else { zoom = 1.0 } print("zoom: \(zoom)") } } else if newVolume < initialVolume - 0.05 { if let view = volumeView?.subviews.first as? UISlider { // volume down pressed view.value = Float(initialVolume) /* if zoom > 1.0 { zoom /= 1.2 } */ if let image = self.imageView1.image { saveImage(image: image) print("save image") } } } } } // save private func saveImage(image: UIImage) { UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) } }

megane - qrdetector on GitHub」 in Swift4

links
- WebMegane - your new digital sight / デジタルな視界 on iPhone Safari x VR goggles (JS、webアプリ版)

今までの延長線上に未来なし、攻める鯖江商工会議所と常識反転メガネ

2018/05/25
#sabae #megane #js 

鯖江市内を中心に1846の会員を持つ、鯖江商工会議所の記念すべき第60回通常議員総会。

WebMegane」 JSで作ったブラウザで動くWebMeganeに、反転モードを追加
左右反転させるレンズもプログラム1行で実現できてしまう、デジタル化したメガネ。

強烈に気持ち悪い左右反転視界も、しばらく歩き回っているとなんとかなってしまう不思議。
電話も、ネットも、スマホ、「今までの常識と違う」気持ち悪さも「利便性」には叶わない。

一眼レフがデジタル化し、光学ファインダーから液晶モニター化によるミラーレスが実現したように。 メガネの世界でもレンズレス時代が訪れる。


今までの延長線上じゃだめだと開会宣言する、鯖江商工会議所、黒田会頭。


新任で阪大から来られた福井工業大学、学長で、理学博士の掛下知行さんと鯖江市長!
商工会議所、鯖江市、福井工大による産官学連携も丸10年。


鯖江商工会議所副会頭「」代表の加藤さんによる〆。


サイトリニューアルしていた「日本酒「梵」の酒蔵 | 加藤吉平商店 |


SDGsバッジとメガネバッジを付けた鯖江市長、いよいよ国連本部、ニューヨークへ!
鯖江の市長さん、ニューヨークへ行く!こどもプログラミングで地方が変わる、EDIX&自治体総合フェア!
鯖江の新しい一歩のきっかけに!

Swift4でつくるQRコードをリアルタイムに読むアプリ

2018/05/24
#swift #megane 

iPhoneの本当のおもしろさはプログラミングしないと分からない。
画像認識APIのひとつ、QRコード認識を使って、リアルタイムにQRコードが読めるアプリを作ってみました。

QRコードを認識すると、埋め込まれている文字として上書きします。
(QRコード生成アプリ qrmakeriPhone風スマホ画像素材使用)

Swift4で書く、QRコードの認識プログラムは簡単!カメラからの画像を CIDetector に渡すだけ。
画面内の複数のQRコードをまとめて認識してくれるのがおもしろい!

let detector : CIDetector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options:[CIDetectorAccuracy: CIDetectorAccuracyHigh] )! let features : NSArray = detector.features(in: ciimage) as NSArray

まちの標識の先頭につけておき、その人が分かる文字にリアルタイムに、視界を上書きするメガネが簡単にできちゃいそうです。

現実とネットをつなぐインターフェイス、メガネ。
いよいよ実現が近づいてきました!

links
- WebMeganeでMR、JSで手軽に実現、外カメラ映像とCGをミックス!

WebMeganeでMR、JSで手軽に実現、外カメラ映像とCGをミックス!

2018/05/23
#megane #js 

MR = Mixed Reallity。CGと現実を混ぜること。

スマホとVRゴーグルで手軽なデジタルメガネを実現、WebMegane
three.jsと組み合わせて、MR化!

ひとまずシンプルな赤い画面を半透明にして合成。
現実とCGが混ざる世界ができあがった。


カメラ入力とThree.jsのCGをミックス!「redsnow - WebMeganesrc on GitHub
ただ失敗は背景のカメラは立体視非対応で、CGは立体視なので違和感あり・・・。
CGの左右視差はなしにする必要がありそう。外カメラ2つが使えれば、立体視可能にできるかも。


こちらオタマートで販売しているVRゴーグルの一番安いもの。
高いものにはついているボタンがないので、何かインタラクションを付ける場合は、視点の移動を基本にする必要がありですが、デジタルメガネ実現だけなら問題なし!

格安VRゴーグルとJSで、Let's begin to make your WebMegane!

links
- 任天堂伝説のゲーム機、バーチャルボーイ風をスマホVRとWebVRで手軽に創る
- WebMegane - your new digital sight / デジタルな視界 on iPhone Safari x VR goggles

WebMegane - your new digital sight / デジタルな視界 on iPhone Safari x VR goggles

2018/05/12
#js #megane 

2007年の今日、5/12、アニメ「電脳コイル」が放送開始。
バーチャルとリアルが融合した、近未来の世界はまさにエンジニアの夢。
12th May is anniversary day of "COIL A CIRCLE OF CHILDREN", a dream of all engneers!
電脳コイル on Otamart

オタマートで買ったVRゴーグル
任天堂伝説のゲーム機、バーチャルボーイ風をスマホVRとWebVRで手軽に創る

スマホというイノベーションは、安価で軽量なVRディスプレイ、Oculusを産んだ。
iOS11で利用可能になったweb上でのカメラのストリーミングを使った「WebMegane」を作ってみた。
I created WebMegane, digital eye glasses using web technologies.

カメラからの画像をCanvasに2枚貼り付け、VRゴーグルでこのサイトを開いて見るだけ。
WebMegane」 web app for iOS11 with VR goggles

立体感はなく、ちょっと遅延が気になるが、メガネをしなくてもゴーグルでクリアな視界が見られる体験が楽しい。
2014年のSXSW発表時点では、ネイティブアプリでしかできなかったものが、JSで簡単に誰でも無料で自在に配布できるようになったのは大きい。
It's so fun and easy to share!


ゴーグルのボタンタップで、視界をモノクロ、セピア、色相回転、色反転、標準と切り替え可能。
You can modify your sight using the button on your goggles.


モノクロモードにしたWebMeganeをかけて開発していると、モノクロモードになったかどうかの確認ができないことに気がつく。 手軽に、色弱や弱視など、障がいを体験することができるメガネとしても使える。

もちろん真骨頂は見えないものを見せるメガネ。
You can improve your sight by WebMegane!

オープンソースかつオープンライセンスな WebMegane CC BY、どんどん進化させてみたいと思います。
Join us on GitHub "WebMegane - github.com"

links
- Circle for Glass concept by Zeppelin x jig.jp in SXSW Trade Show 2014
- iPhoneで開発可能な「攻殻機動隊」の世界、80年代の夢が現実に (2014)
- 課題と向き合い、みんなで創ろう、世界最先端IT国家、電脳メガネサミット2018 in 東京
- Smart Glasses x Open Government = Smart City, Smart Glasses Summit! (2012.8.3)

自分で創ったモノを売ってみよう!はじめてのしょうばい - 高性能温湿度計のつくりかた(SHT31編)

2018/04/08
#KidsIT #sabae #megane #IchigoJam #maker 

人はなぜ勉強するのか?
→ 価値提供力を高め、社会をより良く発展させるため。

最もシンプルな価値提供、自分で創って自分で売る。
「はじめてのおつかい」ならぬ「はじめてのしょうばい」体験を鯖江市の定例祭、誠市で実施。
小学生自ら、メーカー兼販売店兼販売員となって、行き交う人に売り込み!
商品は、先日「ハードオフ x Hana道場企画、ジャンクREメイクショップ」で創ったもの。


ラジオの発電機と扇風機の羽を再構築してメガネに接続魔改造された「せんぷうメガネ」2,000円


メカなメガネだから「メカネ」ナイスネーミング!


ガラケーを再構築した「電話けんし」500円


基板やコンピューターをたっぷりつかったメガネ「コンピューターづくし」1000円(税抜)


メーカーさんと一緒に写真が撮れるサービス、いいね!


試着できます


興味がある人ない人、買ってくれる人くれない人、値段は高い?安い?


商売というコミュニケーション、売り手の立場が分かると、買うときの意識も変わります。


どういう店構えにするといいかな?「自分の商品を売る」をゴールにあれこれその場でチャレンジ!
自分の作品が売れたあとも、「友達の作品を紹介して一部もらおう」など、早速商売の幅が広がってました。
雨で客足少ないなら、売り込んじゃおうと、会場中を商品を持って走り回ってました。


ここでしか買えないメガネ!


美味しくてお買い得な、たくあん
周りのお店で何がいくらで、どのくらい、どういう人に売れている?現場で学ぶマーケティング。


鯖の丸焼き!


あったかいシシ汁、おいしかった!


定番サバエドッグ、実はその誕生は2010年7月12日の誠市(命名は鯖江市長!)
サバエドッグ(福井県鯖江市) 持ち歩くソースカツ丼  :日本経済新聞
全国にファンを持つ鯖江グルメの代表格。いち早く掲載したのはこのブログ

あるくソースカツ丼!?サバエドック登場、雨でも賑わう7月誠市&ご縁市
新しい商品が生まれるお祭、誠市!


市長と!


楽しかった、またやりたいとの声!それぞれ何か手応えを掴んだ様子。


5度台まで下がった冬日、ストーブと福井弁でしゃべる温度計が活躍してました。


950円の高性能温湿度計、SHT31
ピンヘッダーでブレッドボード上で接続してもOKですが、基板でIchigoJam用にコンパクト化!


SHT31使用 高精度温湿度センサモジュールキット: 組立キット 秋月電子通商 電子部品 ネット通販
基板 for プラケース(2枚入) - aitendo」←この基板をニッパーで切って使ってます


下二桁表示で、リアルタイムにくるくる変わる温度と湿度がなかなか新鮮。

SHT31、I2Cで数値を取り出す方法

POKE#700,#2C,#06:R=I2CR(#45,#700,2,#700,6)

温度や湿度の計算にマシン語を使って (A*B)>>16 を実現

R1+=R0 R0=[R1+0]W R2=[R1+1]W R0*=R2 R0=R0>>16 RET

これをasm15マシン語表を見て手でアセンブルしたものを使います。
ポインタで連続する2つの変数を渡して計算するテストで確かめましょう
マシン語わからなくても使えればOK!)

POKE#700,1,68,8,136,74,136,80,67,0,12,112,71 [0]=17500:[1]=24834 ?USR(#700,#800)-4500 2131 ← 21.31度

温湿度計に仕立てます!

10 U=96:LET[U],#4401,#8808,#884A,#4350,#0C00,#4770:U=#800+U*2 15 GSB@LINIT 20 POKE#700,#2C,#06:R=I2CR(#45,#700,2,#700,6) 30 [0]=17500:[1]=PEEK(#700)<<8|PEEK(#701):T=USR(U,#800)-4500 40 [0]=10000:[1]=PEEK(#703)<<8|PEEK(#704):H=USR(U,#800) 45 CLS:?"@"; 50 ?" ";T/100;".";DEC$(T%100+100,2);CHR$(1);" "; 60 ?H/100;".";DEC$(H%100+100,2);"%"; 70 ?" ":S=#900:GSB@LPOS:GSB@LPUT 80 WAIT10:GOTO20 300 @LINIT:LET[0],#38,#39,#14,#70,#56,#6C,#3C,#C,#1:FORI=0TO8:POKE#700,0,[I]:R=I2CW(#3E,#700,2):NEXT 305 POKE#700,0,#48:R=I2CW(#3E,#700,2):POKE#700,#40,#18,#18,7,8,8,8,7,0:R=I2CW(#3E,#700,9):RTN 310 @LPUT:R=I2CW(#3E,S,LEN(S)):RTN 320 @LPOS:POKE#700,0,#80:R=I2CW(#3E,#700,2):RTN

液晶AQM1602とSHT31を接続して使用
10行:掛け算&シフトのマシン語を配列に格納

WS2812Bでキラキラ光るバー表示もステキかも。
温度センサーIC MCP9700-E/TO 低消費電力リニアアクティブ: センサ一般 秋月電子通商 電子部品 ネット通販

次は何創る!?

links
- はじめてのはんばい!ジャンクREメイクショップ in誠市: Hana道場
- バラバラにしてつくって販売!?ジャンクREメイクショップ: Hana道場
- HARD OFF × Hana道場 ジャンク品REメイクショップ開催 | 親切丁寧な買取、リサイクルショップならハードオフグループ

鯖江駅から歩けるランチマップ by おてがるマイマップ - クリックして簡単なコメントを書いて即共有

2018/03/23
#jig #js #opendata #sabae #megane 

間もなく16期を迎えるjig.jp、今回は鯖江に全員集合してキックオフ!
いざこういう時にさっとランチ場所を伝える方法がないことに気が付き、マップを作成。
漠然としたデータから、誰かのためを思ったデータをセレクトすることで価値がでます。


鯖江駅ランチマップ」徒歩でいけるオススメスポット
「編集モード」ボタンを押して、いろいろ編集すると簡単にURLで共有できるマップができます。

利用シーンに特化したアプリづくり、大事ですね。
網羅的なオープンデータとの接続など、いろいろ拡張していけそうです。


この日、霧に包まれ幻想的な鯖江市、まるで、電脳コイルの舞台、大黒市のよう。


未来のSUI(Spatial User Interface)を先取りする、Windows MRによるVR体験会、人気でした!
VR出社も夢じゃない!

オフラインでフリーで使える音声認識 Julius、声で操作するロボを自作しよう

2018/03/19
#megane #AI #python 

APIを使った音声認識の精度はなかなか高いのですが、ネット接続が必須なので電力的やコスト的にまだ合わない場面多々。

そこで、Interface 2018.4号で発見、オフラインかつフリーで使える音声認識エンジン「Julius
読みは、ジュリアス、でした、ユリウスではなく(Thanks < 青木さん

事前に音声調整をすることなく使え、認識精度もそこそこいい感じ。辞書を自分で作って、その中から認識させることができて使い勝手良し。 ラズパイ0や小型でオフラインのA+などにいれて、IchigoJam連携するモジュールにするのにもいい感じそう!


「テレビ付けて」を認識した様子 on Mac

Juliusのインストールから、独自語彙認識させるまでのメモ (for Mac)
インストール

git clone https://github.com/julius-speech/julius.git cd julius ./configure --enable-words-int make sudo make install cd ~ mkdir -p sandbox/julius-kits cd sandbox/julius-kits wget -O dictation-kit-v4.3.1.tar.gz https://github.com/julius-speech/dictation-kit/archive/dictation-kit-v4.3.1.tar.gz wget -O grammar-kit-4.3.1.tar.gz https://github.com/julius-speech/grammar-kit/archive/v4.3.1.tar.gz tar xvf dictation-kit-v4.3.1.tar.gz tar xvf grammar-kit-4.3.1.tar.gz mv dictation-kit-dictation-kit-v4.3.1 dictation-kit-v4.3.1 cd ~/sandbox/julius-kits/grammar-kit-4.3.1/bin/linux/ ln -s `which mkfa` ln -s `which dfa_minimize`

独自語彙設定

mkdir -p ~/sandbox/test cd ~sand/box/test cat > test.yomi % TARGET IchigoJam いちごじゃむ テレビ てれび アンプ あんぷ ウーハー うーはー LED えるいーでぃー % ACTION つけて つけて 消して けして ON おん OFF おふ % WO を お % NS_B [s] silB % NS_E [s] silE

独自文法設定

cat > test.grammar S : NS_B TARGET ACTION NS_E S : NS_B TARGET WO ACTION NS_E

独自語彙をJulius用に変換しておく

iconv -f utf-8 -t eucjp test.yomi | yomi2voca.pl | iconv -f eucjp -t utf-8 > test.voca perl ~/sandbox/julius-kits/grammar-kit-4.3.1/bin/linux/mkdfa.pl test

独自語彙を設定して、音声認識エンジンを動かすスクリプト

cat > julius-server.sh julius -C ~/sandbox/julius-kits/grammar-kit-4.3.1/hmm_mono.jconf -input mic -gram test -module &

音声認識エンジンに接続して、認識したコマンドを受け取るスクリプト(Python3)

cat > julius-client.py #!/usr/bin/env python3 import socket client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(("127.0.0.1", 10500)) sockfile = client.makefile() while 1: line = sockfile.readline() print(line)

試しに、音声認識エンジンを動かし、認識させてみる

sh julius-server.sh python3 julius-client.py

client.sendで、認識を一時中止したり、認識語彙を切り替えてYES/NOのみを待ったりといろいろできて、便利そう!
モジュールモードについて - Julius

links
- 声だけでプログラミング! 耳がついたスマートIchigoJamの作り方

1コ4円のLEDが光センサーに!? IchigoJamで光ファイバーで通信実験とTEPIA訪問

2018/02/23
#megane #sabae #IchigoJam 

インターネットを物理で支える、光の反射を利用して、信号を遠くまで伝える光ファイバー

iPhone Xのフラッシュの光が IchigoJam につないだ、1コ4円のLEDを通じて、アナログ入力の値として捉えた瞬間。


akibaピカリ館で、光ファイバー照明用を発見。
照明用光ファイバーは漏れる光がきれい!


実験方法は簡単、100コで400円1コ10円)の普通のLEDの長い方(アノード)をIchigoJamのIN1へ、短い方(カソード)をIN2へ差し込み、次のプログラムを動かします。

10 OUT8,0 20 ?ANA(2):CONT

スマホのフラッシュライトなど強力な光を照らしてみると、値が小さくなります!
LEDは光センサーにもなっちゃうわけです。(弱い光の検出には増幅などが必要です)


LEDに光ファイバーをセロテープでとめれば光通信実験のできあがり!
強力に光るLEDを用意して、IchigoJam 2台で光ファイバーでつないでみるのも楽しそうですね!


ここは、一般財団法人 高度技術社会推進協会「TEPIA」のエレベーター。
中身が見えるっていいですね!興味を持ったら、触ってみたくなり、作ってみたくなります。


TEPIAでは、プログラミング教材としてIchigoJamを使ってくれています!
ロボットプログラミング・3Dプリンタ教室 | TEPIA 先端技術館」次回は、3/21、24開催!


TEPIAの丹治先生と!
TK-80以前からコンピューターに触れ、手に入れたApple IIに感動したという本筋な方!
IchigoJamかわいがってもらっていて感動です。

ワクワクする技術、こどもたちにどんどん広めていきましょう!

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY 福野泰介 - Taisuke Fukuno / @taisukef / アイコン画像 / プロフィール画像