いいものたくさん鯖江市。まだまだ情報発信が足りてません。特に若者に伝えるためには、動画メディアの活用は外せません。
鯖江市長がYouTuberに!というプラン、VTuber(バーチャルYouTuber)化すれば、みんなが鯖江市長になって配信可能!?

ということで、メガネアプリを改造して、つくってみました、だれでも鯖江市長アプリ!(src on GitHub
鯖江市長画像は、学生団体with制作のウェルカム市長より!
画面収録を使ったり、ふわっちの画面配信機能を使えば、今すぐ鯖江市長になれますよ。
顔出しはちょっと・・・という、人、こどもでも、安心!


と、思った矢先、鯖江市市長YouTuberスタート!


こちらベースになった鯖江版SDGs、グローカルアプリも人気でした!(グローカル写真集


12回目の発表会の会場もこちら、鯖江の「ご本山」こと、誠照寺(じょうしょうじ)。
高校生、高専生、大学生による5人混成チームのスキット(寸劇)を交えたプレゼンテーション x 6。
審査員も12回目、今年は「地域の課題をITで解決」KDDI 松野さんとご一緒いただきました!

鯖江総変人化計画(鯖変) by チームイヌワシ(伊藤園賞、写真
廃校を使ったアミューズメント施設「わがまま学校」をスタートさせ、年代を問わず学ぶ学校へ!
本来学びは遊び。大人でも先が読めない現代、自分の好きで得意を大いに伸ばそう。

世界一有名なまち、鯖江 by チームツバメ(優秀賞、写真
ジェットコースターでもズレない鯖江のメガネ、市長自信がオープンデータなど、若者受けする企画をJK課で考案、Hana道場で編集、主演は鯖江市長!
市長も乗り気だけど、体がついていくかどうか・・・、そこで提案バーチャルユーチューバー。鯖江市長の容姿オープンデータで、誰でも鯖江市長になって配信できますね!

鯖式会社 - 鯖江を「JK社長」が日本一多い市に! by チームミミズク(最優秀賞、写真
鯖江式の株式会社、略して鯖式会社。就職するその会社も誰かが起業した会社。そもそも起業とは?社長とは?やってみるのが一番です!
敷居をぐっと下げた鯖式会社で、小さな夢を実際叶えてみるまでのレクチャー付き!鯖江のイベント、ものづくり博や、月一のお祭り誠市で実践しよう。

物々交換しながら鯖江を目指せ - めざされるまち鯖江 by チームシラサギ(優秀賞、写真
ヨーロッパを舞台に開催されたレッドブルの企画「CAN YOU MAKE IT?」の日本からの参加者ならではの企画、鯖江のSDGsピンバッジ11コ(サバエの3+8)だけを元手に、物々交換しながらあたたかいまち、鯖江を目指す。
大学生向けなので夏休み、メガネフェス的なお祭りと合わせて企画できると楽しそう。

スケボーのまち - 合言葉はナイストライ! by チームコウノトリ(写真
昭和56年からの鯖江市の姉妹都市、新潟県村上市は、スケボーのまち。すごいスケートパークがオープンしてました。(スケボーの「聖地」!! 村上市スケートパーク完成 - スポーツ : 日刊スポーツ
オリンピック競技にもなり、実は公道でも使えるスケボーというスポーツを鯖江市でもスクールから始めてみようという企画。スケボーにやさしい道づくりをして、車を持たない若者、免許返納後の高齢者の足としての活用を考えてみるとか新しいかも!?

さば絵プロジェクト - 自由に落書きができるまち by チームムクドリ(写真
絵を描くのが好きな人、街中じゆうに落書きできたら楽しい!
鯖江市が管理する400以上ある橋など、公共物や公共施設、自由に落書きしていいスポットをオープンデータ化すると楽しいかも?
ARメガネを使ったら見えるバーチャル落書きなら、めがね会館にも、空にだって落書き可能!


発表会、おつかれさまでした!


Hana道場通う、熱き高校生も参加!


運営の学生団体withからのプレゼント!


参加者、スタッフ、実行委員長水野さん、ステキなイベント、ありがとう!


プラコンOBも応援に来てくれました!


いつでも鯖江を目指してきてくださいねっ


360度写真が撮れる楽しいカメラ THETA V - THETA SCなら22,000円〜


早速、参加高校生からも参加表明、ますますパワーアップする学生団体with!
さぁ、今年プランの実現だ!

links
- 鯖江市地域活性化プランコンテスト | 市長をやりませんか?
- 鯖江市地域活性化プランコンテスト - Facebook
- 学生団体with (@sabaepc_with) / Twitter
- 学生団体with
- 第12回目の「鯖江市地域活性化プランコンテスト」でした | 『さばえ.jp』百さんのブログです
- 住みたい鯖江 学生提案 活性化プラン 全国6チーム発表 JK企業支援案 「チームみみずく」が最優秀賞 「福井新聞社」提供(牧野 百男 Facebook投稿)

鯖江のお土産にオススメ「眼鏡堅麺麭」せっかくなので、堅パンカメラも開発。

グローカルサバエイトに続く、鯖江なメガネアプリ第三形態。
iPhoneアプリのプログラム on GitHub

メガネ画像 megane.png を用意して、顔認識させて目の位置(left/right)を使って、こんなプログラムで顔にフィットさせます。(SwiftというiPhoneやiPad向けのアプリを作るためのプログラミング言語)

let dx = left.x - right.x let dy = left.y - right.y let len = sqrt(dx * dx + dy * dy) let th = atan2(dy, dx) let cx = (left.x + right.x) / 2 let cy = (left.y + right.y) / 2 let mw = len * 2.2 let mh = mw / imgmegane.size.width * imgmegane.size.height let px = cx - mw / 2 let py = cy - mh / 2 g.saveGState() g.translateBy(x: cx, y: cy) g.scaleBy(x: 1.0, y: -1.0) g.rotate(by: CGFloat(-th)) g.translateBy(x: -cx, y: -cy) imgmegane.draw(in: CGRect(x: px, y: py, width: mw, height: mh)) g.restoreGState()

meganeworld/meganeworld/ViewController.swift内、堅パン描画部分
let CAMERA_FRONT = true // を変更すれば、インカメラ、アウトカメラ選べます(切り替えスイッチをつけてもいいですね!)


めがね会館、1Fの売店にて視力が測れそうなメガネ紙袋と共にどうぞ!

持続可能なまちに必要なのはビジネスモデル。持続しない補助金頼みではジリ貧間違いなし。
2030年を見据え、企業連携を強める鯖江市と地方発現場発のオープンイノベーションを牽引するSAPのタッグ!


鯖江市のSDGs解説パンフレット。「ITのまちづくり」としてオープンデータと、鯖江産パソコンIchigoJamが載ってます!
SAP支援によってスタートした、オープンイノベーション道場、Hana道場では、今日も子供と大人が学びます。
元鯖江の小学校の先生、岩堀美雪さん、IchigoJamと共にカンボジアへ!
岩堀先生に、「めがねのまちさばえ国際親善大使」任命 | 『さばえ.jp』百さんのブログです


パンフレットとちょっと配色が違う、グローカル。
メガネのセンター、ブリッジの色が「5 ジェンダー平等」のものが正式版です!


好評、SDGsメガネアプリ


次の計画!


jigインターン、各チームから、SAPのみなさんにプロダクトを紹介!


大阪の企業、フルタ製菓との企業連携、サバエイトチョコレート


インターン生に差し入れ!メガネといえばもちろん、こういう写真!


せっかくなのでアプリ化!メガネ写真アプリにサバエイトモードも追加してみました!(src on GitHub)


チーム毎にランチ会、本日はCチームで、場所は、鯖江駅前、惣(SOU)


さばの味噌煮定食にチェックイン!?


惣(SOU)のランチメニュー!
食をテーマにした3チームの成果発表会は来週末!
jigインターン11日目!! - jigintern2019のブログ」ごはんが!w


鯖江のSDGsのシンボルマーク、グローカルのピンバッチ、めがね会館でも販売中。
持続可能なまち創造実験、オープンなまち鯖江、いつでもお声がけください!

失敗例から生まれる成功もあるので、とにかくいろんなことにチャレンジしてもらいたい。自身で考え、行動を起こすことで地域の問題を自分事だと思ってほしいんですよね。もちろん住民の方や移住を考えている方からのアイデアも大歓迎ですので、どんどん声を聞かせてください!(笑)
“ゆるい”取り組みでは地方創生はできない、なんてない。 - 牧野 百男 | LIFULL STORIES」より

SDGs未来都市に選ばれた鯖江市。市長、インターン訪問時に決定した、SDGsメガネ「グローカル」のアプリ化!

グローバルに考え、ローカルに動く!iOSアプリによるメガネアプリができました。(Swift src on GitHub)
プログラムでグローカルを再現!ブリッジ部分は鯖江市が中心に掲げる「5 ジェンダー平等」(モデル:たかげん)


グローカル配色な「めがねのまちさばえSDGsピンバッジ」めがね会館1Fでも販売中。

メガネ左フレーム Think gloabally!
1 貧困をなくそう E5243B
2 飢餓をゼロに DDA63A
3 すべての人に健康と福祉を 4C9F38
4 質の高い教育をみんなに C5192D
14 海の豊かさを守ろう 0A97D9
15 陸の豊かさも守ろう 56C02B
16 平和と公正をすべての人に 00689D
17 パートナーシップで目標を達成しよう 19486A

メガネ右フレーム Act locally!
6 安全な水とトイレを世界中に 26BDE2
7 エネルギーをみんなに そしてクリーンに FCC30B
8 働きがいも 経済成長も A21942
9 産業と技術革新の基盤をつくろう FD6925
10 人や国の不平等をなくそう DD1367
11 住み続けられるまちづくりを FD9D24
12 つくる責任 つかう責任 BF8B2E
13 気候変動に具体的な対策を 3F7E44

メガネブリッジ
5 ジェンダー平等を実現しよう FF3A21
(グローカル配置 by 鯖江市、データ:さばえ博・SDGs・ネクタイ - さばえものづくり博覧会2018

スマホVRを使って見ると、メガネをかけていない人はみんなグローカルをかけている世界に行くことができます!


みんなでグローカル!(jigインターン2019 BBQ


グローカルの製造担当した「ボストンクラブ」にて、2020年のさばえIT推進フォーラムに向けてMTG!
テーマは、SDGs x 電脳メガネ。


ボストンクラブ所在地、三六町といえば、軍隊堅麺麭 by ヨーロッパンキムラヤ
堅すぎて食べられない!? 福井県鯖江市の「軍隊堅パン」 | at home VOX(アットホームボックス)


堅パンと開発


4日間を1区切り(1スプリント)として開発中のインターン生をOBが視察


キーボードのご先祖様、タイプライターの打ち心地に感動


エモい!


お昼、ヨーロッパ軒 神明分店


初のビーフカツ丼

テーマは食、jigインターン2019
jigインターン2019 8日目! - jigintern2019のブログ

links
- めがねのまちさばえのSDGsとは – めがねのまちさばえ 鯖江市
- SDGs未来都市・自治体SDGsモデル事業に選ばれました! – めがねのまちさばえ 鯖江市

インターンハッカソンの後は、こちらも恒例BBQ!

やってきました、小次郎の里!


BBQ!


13時ごろ、お腹が膨れたところで、散歩!こちら佐々木小次郎氏と。


一乗滝!


滝があったら入りたい


入るよね


入った!


靴で来ると砂利が痛いと学んだインターン生、なべの足。去年は炎天下だとアスファルトが熱くてやばいことを学んで、サンダルで来た。改善、大事!


目隠しの替わりに、スマホVR。下を向いて5回回って、さぁスイカは割れるか!?
見えている景色は左右反転、しかもラグあり。意外と難しくて、楽しい。
2次元フィルタなどで楽しむ、Swift版「megane」アップデート!Webアプリ「WebMegane」もどうぞ!


悲劇の動画。


(バドミントン+テニス)/2、スピードミントン人気でした。百均のおもちゃや、電子ウクレレなど、いろいろ楽しいグッズ持ち込み歓迎!


みんなで記念撮影!


高専マガジン、共同創設者、OKB、来鯖、ありがとう!
高専生なら時間を無駄にするな!高専卒起業家の「思考術」 – 高専マガジン」(←福野取材記事)


夏休み感ある1日でした。.

jigインターン2019 7日目!BBQ開催! - jigintern2019のブログ

福井高専電子情報工学科、1年後期から、いよいよプログラミングの授業スタート!
初回は IchigoJam を使って、自分のパソコンづくりとプログラミング入門。
ひとりずつはんだづけした後、エルチカ、かわくだりゲーム、10秒あてIoTゲームをペアでつくってコンピューターを操る感覚を掴んでもらいました。


はんだづけスタート!
自分のパソコンをまだもっていなかった学生も、ひとまず1台ゲット。


個性がでるはんだづけ、部品をまっすぐつけることにこだわる!


女子は髪をこがさないよう、注意!


できあがった IchigoJam S。すっきりシンプルになったこともあってトラブルも減って1コマ、90分ちょっとでほぼ全員完成!


ペアプログラミングスタイルで、プログラミング入門&IoTはじめのいっぽスタート!

IchigoJam かわくだりゲームの改造版(点数追加、スペースキーでボム、時間でだんだん速くなる)

10 CLS:X=15:CLT 20 LC X,5:?"O" 30 LC RND(32),23:?"*" 35 WAIT 6-TICK()/180 36 X=X-BTN(28)+BTN(29) 37 X=X&31 38 IF BTN(32) CLS 40 IF SCR(X,5) GOTO20

IchigoJam BASIC リファレンスを見ながら、解読してみよう!
ネットでじっくり学ぶテキスト「IchigoJamプリント
ブラウザで動く、IchigoJam web もあるよ!
良い作品ができたら、Kidspod;や、電子工作マガジンに投稿しよう。
わからないことがあれば、IchigoJam-FAN (Facebook) か、#IchigoJam (Twitter) へどうぞ!


福井高専の電子情報工学科を選択した42名、楽しくプログラミング学んでいきましょう!
作ったIchigoJamは、実験でも使いますよ!
(現在福井高専は、1年生が混合学級をとっていますが、専門科目の時間は各クラスから集まって実施)


福井高専IT研究会に新1年生を勧誘!PCN鯖江にも新メンバー!


福井高専メディア研究会のラジオ番組新コーナー「OBさんいらっしゃい」に出演!
OB/OGというのは冗長なので、語源はともかくOBで統一する形でいきましょう。


ものづくりのまち鯖江ならではの、新基軸情報発信を目指す会!


体験しないとわからない、VR/MRの世界 at 鯖江商工会議所の新企画「あたらしもん好き勉強会#1」

アイデアディスカッション、その1「続きはリアルで!鯖江のVRと言えば?」

メガネを作っている職人視点VR(製造工程) コンサート映像VR(人形浄瑠璃、サンドーム) 歴史VR(近松門左衛門) 西山動物園(動物間近でみる) 鯖江の郷土料理のつくりかたVR動画(サバエドッグ) 加藤吉兵衛商店で酒造り見学、中松で飲む気分VR ドローン映像、上空から鯖江(鳥視点) 福鉄運転席 サバエドッグ視点 観光ガイドVR(自治体とお年寄りがネック?) 美術館・博物館の美術品を見せる

アイデアディスカッション、その2「ミライのメガネ」

カーナビ(人生ナビ) 年収見えるメガネ 共通の友達が見えるメガネ 自分との相性が見えるメガネ(好感度) 料理のカロリー見える(アレルギー) スイカの糖度判定(果物) 透けるメガネ 寿命が見えるメガネ(デスノート) 財布替わりになるメガネ 見るだけで最安値が見えるメガネ(レビュー) 店の評価が見えるメガネ リアルなマリオブラザーズ(クリボーがでてくる) 武家屋敷復元 メガネがスマホの替わりになる(事故率下がる、猫背が治る?) 組み立て手順をガイドする

もりあがった、MR、電脳メガネ。
オープンソースな電脳メガネアプリをSwift4.2に対応し、ちょっとバージョンアップ。
「Megane」src on GitHub

世界が印刷物風に見えるメガネと


世界がステンドグラス風に見えるメガネを追加!

メガネのまち鯖江だけに、IT研究会でもOculusなどメガネ系に関心ある学生多いかも!?
今度持っていくのでお楽しみに!

見る人すべてがめがねをかけて見える「meganeworld
MR(Mixed Reality)による近未来、たった800円のスマホVRで開発可能です。

見えている人が「かわいい」と、人はやさしくなれるかも?

安直な「かわいい」の実現「ネコミミ」を見ている人側で勝手に付加するMRアプリを作ってみましょう。

Hana道場、若宮さんと学ぶIoTとIchigoJamプログラミングと地域フィールドラボ第5期スタート!」より

GitHubにあるiPhone用、プログラミング言語Swiftで書かれた、「meganeworld - megane」 にネコミミ表示を足します。 右目位置、左目位置を、顔認識APIから受け取って、三角関数を使って角度を求め、ネコミミ位置を計算し、黒の三角形を描画!(プログラム全文はGitHubで

// nekomimi let dx = left.x - right.x let dy = left.y - right.y let len = sqrt(dx * dx + dy * dy) let th = atan2(dy, dx); let ox = [ right.x, left.x ] let oy = [ right.y, left.y ] for n in 0...1 { let dir = CGFloat(n == 0 ? 1 : -1) let deg0 = 90 + 20 * dir let th0 = th + CGFloat.pi / 180 * CGFloat(deg0) let len0 = len * 1.3 let x0 = ox[n] + cos(th0) * len0 let y0 = oy[n] + sin(th0) * len0 g.beginPath() g.setLineWidth(4) g.setFillColor(UIColor.white.cgColor) let th1 = th0 + CGFloat.pi / 180 * 20 * dir let len1 = len * 0.4 let x1 = x0 + cos(th1) * len1 let y1 = y0 + sin(th1) * len1 g.move(to:CGPoint(x:x1, y:y1)) let th2 = th1 + CGFloat.pi / 180 * 120 * dir let len2 = len * 0.6 let x2 = x0 + cos(th2) * len2 let y2 = y0 + sin(th2) * len2 g.addLine(to:CGPoint(x:x2, y:y2)) let th3 = th1 - CGFloat.pi / 180 * 120 * dir let len3 = len * 0.6 let x3 = x0 + cos(th3) * len3 let y3 = y0 + sin(th3) * len3 g.addLine(to:CGPoint(x:x3, y:y3)) g.addLine(to:CGPoint(x:x1, y:y1)) g.fillPath() }

MSX BASICの三角関数であれこれ遊んだ小中学生時代。
シューティングゲームや、優雅な動き、3Dプログラミングなど、よく出てくるので遊びながら覚えちゃいます。
一番好きな三角関数は、atan2こと、yとxをパラメータとして渡す逆タンジェント(Arctangent)
atan(y / x) として使うため、引数の順序も普通じゃない atan2(y, x) というのもお気に入り。

Swiftでプログラミングしていて驚いたコンパイルエラー
「Expression was too complex to be solved in reasonable time; ...」
IchigoJamのも計算用のスタックに多くのメモリを使えないため「Too complex」というエラーがありますが、現代言語でも目にかかるとは!

IchigoJamと同様、式を分割するか、型の明確化で対応が可能しましょう。

links
- Ichigojam Basicで円を描く – chobitte
- 2015-08-26 [IchigoJam]円を描く - SHIROのモバイル日記
- 三角関数が好き sin cos tan

Welcome to Megane World! めがねをかけないと損する時代は、もうまもなく!

一足先にスマホMRで体験、見えている人、全員が赤いメガネをかける世界。


6/9-10の2日間はステキなメガネに会える「めがねフェス2018
ステージ、グルメ、ショップ、ワークショップなど、イベント盛りだくさん!隣のめがね会館へもどうぞ!


オススメは800円から買えちゃう、各種スマホVR、ぜひ試着してお気に入りのVRを手に入れてください。
一段上のVR体験、Oculus Go も展示!
発売開始から3分で完売 Oculus Go中国国内モデル、入荷待ちは5万人以上 | Mogura VR - 国内外のVR/AR/MR最新情報


めがねxIT」ブースで体験できるメガネアプリ開発者は鯖江���住の現役高校生プログラマー!
ITの基本、プログラミングを子供も大人も学べる格安パソコン「IchigoJam」の体験コーナーもあります。限定品の販売も!?


めがねのまちさばえ!

links
- めがねフェス2018

外カメラ 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. // https://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アプリ版)

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をミックス!

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