頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


iOS 13のショートカットで13時間後のアラームを設定する

ヨーグルトメーカーでR-1複製200回成功
↑時々記事にもしているようにウチでは頻繁にヨーグルトメーカーでヨーグルトを作っている。

いつもヨーグルトメーカー(タイマーは付いてない)に牛乳パックをセットしたら13時間後にアラームがなるようにSiriに言ってセットしている。
このアラーム設定にショートカットを使ってみようということだ。

一定時間後なら通常タイマーを使うべきなんだろうけど、iOSのタイマーは同時に2つ以上はできない。13時間の間に短いタイマー、例えばお風呂のお湯入れだったり、読書や料理などいろいろと使う。
なのでヨーグルトの13時間のだけはアラームを使う。

ところがiOSのアラームは決まった時刻で設定する。例えば6:30とか22:00とか。「現在時刻から13時間後」というような相対的な設定ではないのだ。
なのでこれをショートカットで実現するのに随分苦労したのでメモ。

(1)現在の日時を得る

最初のアクション。まずは現在の日時を得る必要がある。
「アクションを追加」タップで、

ショートカット検索画面

↑こういう画面が出てくる。どこか探ればあるのかもしれないがよくわからないので上部の検索窓で「日付」とでも入力してみよう。日時とかDateとかでもいけるかもしれない。

日付の検索結果1

↑検索結果に「日時」というのがあればそれを選択。

現在日時取得

↑これで最初のアクションはOK。


(2)13時間後を得る

日付の検索結果2

↑次のアクションも「日付」で検索すると出てくる「日付を調整」を選ぶ。

日付を調整を追加

↑その時点でこんな感じになってるはず。ここの「0 秒」を「13 時間」にしてやればOK。


(3)アラーム作成

アラーム検索結果

↑最後のアクションも検索で「アラーム」なんかで探せば見つかるであろう「アラームを作成」を選択する。

アラーム作成

↑すると自動的に「調整済みの日付」に対してのアラームになってる!別に変数をどうのこうのとする必要もない。
アラームの名称を適当なのに設定するとわかりやすい。

(4)ショートカット名

「次へ」をタップするとショートカット名が出てくるのでわかりやすいのを設定する。この文字列は自分のショートカット一覧の中でタイトルとして表示される。

以上でOK!

NFCタグを貼ったヨーグルトメーカー

↑ちなみにウチではこの処理をオートメーションで使っており、ヨーグルトメーカー上部にNFCタグを貼り付け、牛乳パックをセットしたらiPhoneを近づけるだけでアラーム設定が完了するようにした。上部の白い丸がNFCタグだ。

アラーム時のスクリーンショット

↑時間が来るとこのように表示される。何のアラームかわかりやすい😄
この文字列は(3)で指定したアラームの名称に相当する。




↑こちらがAmazonで購入したNFCタグ。中国からなので少し日数がかかったが。



iPhone XS Max
iOS 13.1.2
スポンサーサイト






TensorFlowで画像の水増し時のパラーメタの検討方法

TensorFlowで学習時に画像を水増しする、というおなじみの手法。

画像の水増し方法をTensorFlowのコードから学ぶ - Qiita
TensorFlowを使った画像の水増しレシピまとめ
↑このあたりを見るとどのパラメータをいじるとどういう風に画像が変わるか、というのがざっとわかる。

自分がデータセットに使おうとするpng画像があるとして、それを水増し用処理した画像を表示するコードを紹介。
import tensorflow as tf
import numpy as np
from PIL import Image


def img_show(img) :
pil_img = Image.fromarray(np.uint8(img))
pil_img.show()


srcImg = Image.open(“lena.png")
img_show(srcImg)

if srcImg.mode == 'RGBA' :
# srcが4chの場合3chにする — (1)
rgbImg = Image.new('RGB', srcImg.size, (255, 255, 255))
rgbImg.paste(srcImg, mask=srcImg.split()[3])

elif srcImg.mode == 'RGB' :
rgbImg = srcImg

npArray = np.asarray(rgbImg)/255.0


with tf.Session() as sess :

tfImage = tf.convert_to_tensor(npArray, np.float32)


# いろいろな水増し処理
#tfImage = tf.image.adjust_brightness(tfImage, 0.4)
#tfImage = tf.image.adjust_contrast(tfImage, 1.4)
tfImage = tf.image.adjust_hue(tfImage, 0.25)
#tfImage = tf.image.adjust_saturation(tfImage, 2.0)


newNpArray = 255.0*tfImage.eval()
newNpArray = np.clip(newNpArray, 0, 255.0)
img_show(newNpArray)



(1)読み込んだ画像がアルファチャンネルを持っている場合に3chになるような処理をしている。というのもTensorFlowの水増し処理は3chでないとダメなのがあるため。

画像出力結果

↑実行すると別ウインドウで画像が表示される。


おまけ
保存して確認する場合は↓こんな感じで。
	saveImg = Image.fromarray(np.uint8(newNpArray))
saveImg.save(filePath)




TensorFlow 1.7.0-rc1
Python 3.5.2
macOS 10.14.6


grayscaleのMTLTextureをCoreML/Visionの予測に渡す

機械学習の結果であるmlmodelファイルがあり、それをiOSアプリで使う場合。

Core ML+Visionを用いた物体認識の最小実装 - Qiita
↑通常このような流れでできると思うのだが、画像が白黒のMTLTextureだったので躓いた。

モデルへの入力が画像の場合、
let handler = VNImageRequestHandler(ciImage: ciImage, options: [:])
//let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
try! handler.perform([mlRequest])
↑このような感じで予測を実行するのでCIImageかCGImageが欲しい。

今回はMTLTextureがあるのでまずはそれを変換する必要がある。
let ciImageA = CIImage(mtlTexture: mtlTexture, options: nil)
↑MTLTextureをCIImageに変換するメソッドがあるので一撃。
これでモデルへ渡せる。
カラーだとこれでいいんだと思う。

今回のケースはこのMTLTextureがgrayscaleの白黒画像だった。pixelFormatは .r8Unorm だと確認できる。
これを使いモデルで予測させると全然期待してない結果を出す。警告などもない。
これがモデル自体の性能なのか?モデル作り直すかなと思っていたのだが、よくよく調べると白黒画像に起因するものだった。

結果から言うと上記のCIImageで色空間(color space)を設定していなかったことが原因だった。
let option = [ CIImageOption.colorSpace: CGColorSpaceCreateDeviceGray() ]
let ciImageB = CIImage(mtlTexture: mtlTexture, options: option)
↑このようにcolor spaceを設定しておけば意図通りの予測結果が出てきた。

画像で表示した結果

↑一番上が元の白黒画像。
imageAは上記ciImageAを
let uiImageA = UIImage(ciImage: ciImageA!)
このようにUIImageオブジェクトにして表示したもの。そもそもがRGBの色空間に赤の1チャンネルだけのデータがあるから赤っぽくなるんだろう。
imageBは上記のオプションで色空間を指定した場合。ちゃんと色空間を設定した白黒画像は赤っぽく表示されることはないんだな、、、覚えておかねば!

なお、imageA,BともciImage作成時に上下反転させているが略。


tfcoremlを使ってTensorFlowの学習結果をiOS/macOSアプリで使う

機械学習の結果をiOS/macOSアプリで使おうとするといくつか方法はある。

CreateMLで学習させると結果をmlmodelファイルで得ることができ、これをiOS/macOSアプリではCoreML+Visionで簡単に使うことができる。
この方法が一番簡単だと思うが自分の場合ではCreateMLだと学習が進まなかったこともあり断念。

TensorFlow、もしくはKeras(バックエンドはTensorFlow)での学習結果を使う場合にはiOS/macOSアプリでweightやbiasのデータを読み込んでMetalPerformanceShadersを使ったことはあった。今回もそうしようと思ったのだが、、、MPSCNNConvolutionのイニシャライザ
init(device:convolutionDescriptor:kernelWeights:biasTerms:flags:)
が deprecated in iOS 11.0 と出てしまう。そらあかん。
ということで今回は、、、

TensorFlowで作ったモデルをCore MLで利用する - Qiita
↑こちらの記事を参考にTensorFlowで学習、pbファイルを出力し、それをtfcoremlを使ってmlmodelに変換してiOS/macOSアプリで使ってみることにした。その時に躓いたところをメモしておく。


1)tfcoremlのインストール
tfcoreml · PyPI
↑本家tfcoremlのサイト。現時点で0.3.0が最新か。betaもあるみたいだけどおっかないので
pip install -U tfcoreml
で0.3.0をインストール。ちなみにPythonは3.5.2、TensorFlowは1.7.0-rc1。


2)TensorFlowでのモデル作成
#    x = tf.placeholder(tf.float32, [None, HEIGHT*WIDTH], name = 'x')
x = tf.placeholder(tf.float32, [None, HEIGHT, WIDTH, 1], name = 'x')
↑入力がHEIGHT*WIDTHになっていた(MNISTの例題などではこうなってるのでその流れでこうなってた)ので区切って画像形式にしたここではカラーではなくグレースケールなので1にしてる。
pbファイルとして出力するところは略。


3)tfcoremlで変換
classLabels = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

tf_converter.convert(tf_model_path = PbFilePath,
mlmodel_path = MlmodelFilePath,
output_feature_names = ['y_conv:0'],
input_name_shape_dict = {'x:0':[1, Height, Width, 1]},
image_input_names = ['x:0'], # — (1)
class_labels = classLabels, # —(2)
image_scale = 1.0/255.0 # —(3)
)
↑肝心の変換部分はこんな感じ。
(1)image_input_namesは上記参考記事の通り。画像形式にしておくとiOS/macOSアプリで使う時にもラク。
(2)softmaxを使う画像分類なのだがclass_labelsを設定しないと結果を見てもよくわかんない、となるのでラベルの設定が必要だった。
(3)自分のモデルには必要だった。0から1の値で学習させていたんだわ。

変換処理をすると
[espresso] [Espresso::handle_ex_] exception=Unsupported engine type
[espresso] [Espresso::handle_ex_] exception=Espresso exception: "Device not found": Can't find metal device

といった警告が表示される。

macOSアプリでもmlmodelロード時(?)にも同じものが表示されたが、意図通りに予測できていた。
Core ML+Visionを用いた物体認識の最小実装 - Qiita
↑iOS/macOSアプリでmlmodelを使うのはこのあたりを参考に。

予測の実行結果
↑macOSアプリでの予測結果。あってるよ〜!
助かった!ありがとう、tfcoreml!


iPhone故障で確認コード受信できずApple IDでサインインできない!

妻のiPhone 7 Plusの調子が悪くなった。ディスプレイ右側に太い縦線が2本入りタッチによる操作もうまくできないことが多い。
ソフト的な原因かもということで再起動、および強制的な再起動をするも効果なし。
次に工場出荷状態に戻して(つまりリセット)iCloudにあるバックアップから復元させようとした。
リセットはできたのだが、最新のiOSをダウンロードしてから、とのことで夜間にダウンロード。
翌朝、無事ダウンロード終了して復元作業をしようとしたが、

故障したiPhone 7 Plus

↑縦線以外にも何やらおかしくなっており、もはやディスプレイが入力をほとんど受け付けず、さわってもないのにキー入力しているような状態になってしまってた。もうAppleに修理に出すしかないと決断した。

修理に出している間、携帯がないのも不便ということで使っていなかったiPhone 5sを代わりに使おうとしたのだが、、、
5sを妻のiCloudにあるバックアップから復元させる手順の途中で、Apple IDが2ファクター認証になってるので確認コード入力を求められる。
本来なら確認コードは妻のiPhone 7 Plusに送信されている。
しかしすでに壊れてリセットまでしているので当然受信することはできない。

Apple ID を使って 2 ステップ確認でサインインできない場合 - Apple サポート

↑サポートページの説明には
Apple ID で 2 ステップ確認をお使いの場合、サインインの際に下記のうち 2 つ以上が必要となります。
・Apple ID のパスワード
・信頼できるデバイス
・復旧キー

↑このような記述が。
パスワードはあるんだが、妻にとって「信頼できるデバイス」は壊れた7 Plus以外にはない。復旧キーなんて聞いたこともないとのこと。
つまり、3つのうちパスワード1つしか持っていない、、、詰んだ、、、?
知らんかったわ、、、これ、7 Plusを修理したとしても、前のアカウントにはアクセスできないってことじゃ?
うかつにリセットせずに修理してればなんとかなったのかもしれなかった。あああ、やってもうた、、、旅行の写真があぁ、、、


と思ってたんだが、確認コードをメッセージではなく電話番号でも受信できそうだったので、試しに、7 Plusのsimを息子のiPhone 6に差してみたところ、6で確認コードを受信することができた!
ということで無事5sは復元に成功し妻の代替機となり、7 PlusはAppleに修理に出した。見積額は税込42,984円、、、痛いっ!


なお、壊れたiPhone 7 Plusも6も5sも全てsimフリー機、simのサイズは同じ。




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.