頭と尻尾はくれてやる!

iOSアプリなどの開発日記です


アイリスオーヤマのLEDシーリングライトを買ってみた

初めてLEDのシーリングライトを買ったってお話だよ。

8月も下旬というなんともタイミング的にあれなんだけど、LEDのシーリングライトを買ったんだよ。
関電の節電トライアルは8月末で結果が出るから残り2週間もないタイミングなんだけどね。もっと早くに買っておけばよかったんだけど今使ってるのが壊れて買ったんだからまあ仕方ないよね。
買ったのはアイリスオーヤマのCL6N-E1ってシーリングライト。



↑ここアマゾンで買ったよ。LEDシーリングライトで一番安くて評価が高そうなのを選んだんだ。まあ入門機みたいなもんかな。値段もお手頃だしね。

消費電力が測定できないのは残念だけどかなり節電に貢献するはずなんだ。
取扱説明書によると100%点灯時で34W、25%点灯時で9Wと書いてる。今のところ50%で使っているからおよそ17〜18W程度なんだろうな。今まで使ってた通常のシーリングライトなんて32形(30W)+40形(38W)でおよそ68Wくらいだろうから、、、すごいじゃない?!

アイリスオーヤマのLEDシーリングライト
↑今日到着して早速取り付け。
問題はホントに設計寿命の40000時間に届くんだろうかってことだけどね。1日10時間としても4000日=約11年だと!俺、何歳だよ?!


岸和田浪切ホールで腹話術のいっこく堂をみてきた

いっこく堂

腹話術のいっこく堂のライブへ行ってきたってお話だよ。

いっこく堂 オフィシャルホームページ

場所は岸和田の浪切ホール。別にファンでもないんだけど、プレゼントで当選したので無料で行くことができたんだよ。

ライブはすごく楽しめたんだけど、芸が芸だけに遠くからだとよくわからないってのが難点だね。
会場の客席をぐるーっと歩くこともあって目の前で見ることもできたけど、結局ステージ後方に用意されている大きいスクリーンを見てることが多かったという、それじゃライブへ行かなくてもいいやんってことになりそうな残念感も味わってきたよ。

ちなみに5歳の息子には前座の手品ショー(Mr.チョップリン)の方が楽しかったみたい。赤ちゃんの人形が怖かったらしいんだけどあそこは笑うところだよ!


数値などをソートする方法

NSDictionaryを使って数値をソートするってお話だよ。

日本語OCRでカメラで撮影、切り出した画像がデータベース内の多数の画像と比較して類似度を数値かするでしょ。一番数値の高いのがその文字だって流れなんだけど、今のところどうもうまくいかなくてさ。まだひらがなしかデータ化していないんだけど(83個)、1割くらいしか正解しないというレベルなんだよ、まずいね。
このあたりの調査でふと数値をソートしたくなったんだよ。一番類似度が高いのはこのひらがな、二番はこのひらがな、、、って具合に。
ざっくりコードの流れはこんな感じとするよ。
for (ii=0;ii<83;ii++) {
    imageData = [self getImageDataFor:ii];
    score = [self getScoreForData:imageData];
}
なんでひらがなだけで83個なんだよって思うかもしれないけど、「が」とか「ぁ」とか古い「え」なんてもあったりするんだ。でこれらの文字データをカメラで撮影した画像データを全数比較するんだ。実際には全数比較なんてことはしないだろうけどここはまだテストってことで全数やっちゃうよ。
するとそれぞれの類似度みたいなものを示す値が出てくるよね。コード内ではscoreってしてるけど。これをソートしたいわけなんだ。

ソートするためにはスコアと文字(上のコードだとii)の情報をメモする必要があるよね。スコアだけソートしてもそのスコアがどの文字なのかわからなければ意味ないしね。

このソートを実現するのに必要なのがNSSortDescriptorってクラスでこのあたりを調べれば参考コードがすぐに見つかるよ、きっと。
ただ、俺の場合はそれ以前にどうやってスコアと文字(くどいけど上のコードのiiね)をまとめてデータ化すればいいのかというところからわからなかったんだ。
ようやくできたのが下のコード。まずはデータ化する部分。
NSMutableArray *scoreArray = [[NSMutableArray alloc] initWithCapacity:0];
for (ii=0;ii<83;ii++) {
    imageData = [self getImageDataFor:ii];
    score = [self getScoreForData:imageData];
    [scoreArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:ii], @"ii",
[NSNumber numberWithFloat:score],@"score",nil]
    ];
}
scoreArrayって配列に文字ごとにNSDictionaryオブジェクトを突っ込んでるよ。これで一つのNSDictionaryオブジェクトはスコアと文字情報(三回目だけどiiのことね)の両方を持たせることができるんだ。
次は肝心のscoreArrayのソート部分。
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"score" ascending:NO];
NSArray *sortDescriptorArray = [NSArray arrayWithObjects:sortDescriptor, nil];
NSArray *sortArray = [scoreArray sortedArrayUsingDescriptors:sortDescriptorArray];
for (ii=0;ii<5;ii++) {
    NSDictionary *dic = [sortArray objectAtIndex:ii];
    NSLog(@"%f , %d",[[dic objectForKey:@"score"] floatValue], [[dic objectForKey:@"ii"] intValue]);
}
"score"に着目してソートしてよってのが一行目。
そういう条件をいくつも設定して配列に入れられるんだけど、ここでは一つだけなので一つのNSSortDescriptorオブジェクトで配列sortDescriptorArrayを作ってる、ってのが二行目。
三行目でscoreArrayに対してソートの実行ができるよ、と。
そうそう、メモリ管理については記述していない部分もあるので注意してね。


8月の節電結果

8月分の消費電力量が出たってお話だよ。

関西電力の"節電トライアル"に参加中なんだけど、8月分(ややこしいけど7月1日から末日まで)の結果が出てたんだ。

8月の節電結果

おおお。測ったように-15%をわずかにクリアしてるではないか!全然実感ないんだけどね。
今月もこのままならいいんだけど、さすがに夜もエアコン使っていたりするからどうだろうな。


面積平均法で画像を縮小してみる

面積平均法って方法で画像の縮小をしてみたってお話だよ。

最近やっている日本語OCR関連なんだけど、画像を縮小したくなったんだ。
処理の手順としてはカメラから画像を取得するでしょ。その画像内から文字らしき部分、それも一文字分の画像エリアを得るでしょ。処理の都合この一文字分の画像は正方形なんだけど、これを縮小したいんだ。

画像の縮小といってもUIImageやUIImageViewなんかは登場しなくて、輝度データが配列に入ってる状態。
一文字分カットした画像のサイズは任意(正方形)、縮小後のサイズは16x16pxとするね。

アルゴリズムを調べるとこういうのがあったんだよ。
陶見の窓 画像リサイズ「面積平均法」
へえ。面積平均法だってさ、初めて聞いたよ。リンク先の解説が図解入りで理解しやすいのでここでは詳細は書かなくてもいいね。
ところがいざObjective-Cで実装しようとしたら案外面倒でさ。イライラしてチョコを無駄に消費しちゃったよ。こういうのをサクっとコード化できるようになりたいよね。

つたないコードで恥ずかしいけどコードを以下に書いとくよ。恥ずかしいと言えばこの前近所の歯医者さんに子供を連れて行ったら知り合いの美人ママさんが助手?歯科技工士?かなにか知らないけどそこで働いていたんだよ。連れて行く前は、今回は息子だけど今度は自分が診てもらおうかな、と思っていたんだけど、知り合いに口の中を見せるのって恥ずかしいよね。そりゃキレイな口内ならいいけどさ、虫歯の治療痕がいっぱいだし正直裸よりも見られるのが恥ずかしい気分だよ。あれ、なんの話だっけ?そうそうコードね。

//float squArray[length*length];//ここに輝度のデータが入ってる
{
    //まず横方向から縮小する(length→16px)
    float red1Array[length*16];//横方向を縮小した結果を入れる
    float numeratorArray[16];//numerator=分子
    float denominatorArray[16];//denominator=分母
    unsigned int ite1, ite2;
    float aa1,aa2 , cc;//高速化のための定数
    float rate = 16.f/length;
    float theBr;
    for (j=0;j < length;j++) {
        //リセット
        for (i=0;i < 16;i++) {
            numeratorArray[i] = 0.f;
            denominatorArray[i]=0.f;
        }
        
        for (i=0;i < length;i++) {
            theBr = squArray[j*length+i];
            aa1 = rate*i;
            aa2 = rate*(i+1);
            ite1 = floor(aa1);
            ite2 = floor(aa2);
            if (ite1 == ite2) {
                numeratorArray[ite1]+= theBr*rate;
                denominatorArray[ite1]+= rate;
            } else {
                cc = ite2-aa1;
                numeratorArray[ite1]+= theBr * cc;
                denominatorArray[ite1]+= cc;
                if (ite2 != 16) {
                    cc = aa2-ite2;
                    numeratorArray[ite2]+= theBr * cc;
                    denominatorArray[ite2]+= cc;
                }
            }
        }
        //平均値を出す
        for (i=0;i < 16;i++) {
            red1Array[j*16+i] = numeratorArray[i]/denominatorArray[i];
        }
    }
    
    
    //次は縦方向の縮小
    for (j=0;j < 16;j++) {
        
        //リセット
        for (i=0;i < 16;i++) {
            numeratorArray[i] = 0.f;
            denominatorArray[i]=0.f;
        }
        
        for (i=0;i < length;i++) {
            theBr = red1Array[i*16+j];
            aa1 = rate*i;
            aa2 = rate*(i+1);
            ite1 = floor(aa1);
            ite2 = floor(aa2);
            if (ite1 == ite2) {
                numeratorArray[ite1]+= theBr*rate;
                denominatorArray[ite1]+= rate;
            } else {
                cc = ite2-aa1;
                numeratorArray[ite1]+= theBr * cc;
                denominatorArray[ite1]+= cc;
                if (ite2 != 16) {
                    cc = aa2-ite2;
                    numeratorArray[ite2]+= theBr * cc;
                    denominatorArray[ite2]+= cc;
                }
            }
        }
        //平均値を出す
        for (i=0;i < 16;i++) {
            characterArray[i*16+j] = numeratorArray[i]/denominatorArray[i];
        }
    }
}
あまりObjective-Cに見えないねえ。実のところ今回の日本語OCRアプリだと画像データを直接扱ったりするからどうしてもこんな感じになっちゃうんだ。
画像の数値データをNSArrayに入れようとしてもNSNumberかまさないとだめだし、そういうのすると処理に時間がかかるからねえ。

面積平均法で縮小

↑上から、カメラで撮影した画像、一文字を切り出した画像、横方向を縮小した画像、縦方向を縮小した画像だよ。
上のリンク先にあるように縦方向、横方向と別々にやっても可なので、まずは大きい正方形の画像の横方向を縮小して縦長の画像にして、次に縦方向を縮小して正方形にって具合で二段階でやってみたんだ。

その結果なんだけど、46x46→16x16ピクセルに縮小するのにiPhone 4S実機で0.7msec程度かかってたよ。
うーん、もうちょっと速くならないかな、と思っていっぺんに処理するのもやってみたんだよ。一度にやるんだからもっと速くなるんじゃないかな、と思って修正したんだけどさ、、、
約0.7msecだったのが0.65msecくらいかな。少しは速くなったみたいだけど、なにかと計算が複雑になるからか劇的には変わらなかったよ、、、vDSP使ってみてもこの程度の個数じゃ影響なかったね。

とりあえず一度にやる方のコードは下のような感じ、、、と思ったけどやっぱりめんどくさいからやめとこう。それよりも歯医者どうしたもんかねえ。




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