2012年6月に買ったMacBookProが壊れた。いや、正確には壊れていないのかもしれないが、とにかく動作が重い。クリックのたびに虹色グルグルに待たされ、入力した文字は途中で消え、IMEが落ちる。こんな状況では作業なんて出来るわけがない。
壊れたのはこれが初めてではない。今年の7月には、HDDを認識しなくなり3万円で修理に出した。その時はHDDケーブルの破損だったが、今度はHDDが逝ってしまわれたのか。
現在はデータのバックアップを取りつつ、SSDが届くのを待っている。プロコンが目前だというのに、OSから入れなおすのはとてもつらい。
HDD外してubuntuでデータを単純にコピーしてるけど、これができるってことはHDD壊れてないかもしれない?
さて、この2週間はインターンシップでとある企業に通っていた。企業名は出してもいいのかもしれないが許可をもらっていないのでここでは言わないことにした。
さて、僕がインターンシップで何をしてきたか。それは「iOSアプリの開発」である。僕はiOSプログラミングも、Objective-Cも、そもそもオブジェクト指向プログラミングさえもやったことがなく、それはインターンシップの相方も同じであった。そんな2人がチームを組んで作ったアプリだ。出来がいいわけがない。それでも、iOSプログラミングの初歩を学ぶことが出来た。
さて、とりあえずアプリは完成した。AppStoreに出すのは金がなくてできないが、公開する方法はGitHubなりなんでもある。だから僕は公開しようと思うが、これはチームでの成果だ。画像も画像なので、そのまま公開するのは、無理だ。
そこで。今はやることがありすぎて手一杯なのですぐという訳にはいかないが、1から作り直し(画像関係の削除と相方の担当分を書き直すのみ)て公開し、作り方を(自分でも忘れないように)ここに書いていこうと思う。文章量が多くなるのは簡単に想像がつく。が、やりたい。
iOSでのアプリ開発ができるようになってから何年経っただろうか。インターネットには解説が溢れ、書店に行けば「iPhoneアプリの作り方」なんて本がいくらでも並んでいる。そんな状況で自分で最初から説明するのは確かに無駄かもしれないが、自分の理解が深まるし、様々な書籍やwebサイトを見ても分からなかった部分というものがあるので、その部分の説明などは決して無駄ではないと思う。というかいいこと書いてるようだがただPVが欲しいだけである。
申し訳ない申し訳ない……コメントとかで急かすと作業が早くなるかもしれません……
どうも、vim-airlineの導入に手こずって放置する程度のvim力の持ち主ことうなすけです。
さて、Qiitaをチェックしているとまた良さげなlightline.vimなるものを見つけてまあ早速導入しました。そんな時間ないけど。
例えばvim-airlineを導入直後だとこんな表示です。
fontがおかしいっていうか。なんかスッキリしない。
まずNeoBundleを導入する必要があったりしますがまあ今はそれについては置いといて。
こうして
:NeoBundleClean
して
:NeoBundleInstall
して
こうじゃ
おお……なんかそれっぽい。
あとはカラースキームをsolarizedにしたいんだけどreadmeが英語の上にvim力低いのでよくわかりません。どなたか教えてください。見返りはないです。
貼る画像間違えてた。あと、.vimrcにこう書けばsolarizedになる。焦ったらだめね。
NeoBundle 'itchyny/lightline.vim'
let g:lightline = {
\ 'colorscheme' : 'solarized' ,
\}
作者のitchynyさんありがとうございます。
そんな意見を聞いたことがある。実際はどうかわからないし、調べる気も起きない。 たとえばenchant.jsはゲームプログラミングの敷居を下げようとしているし、文部科学省ではプログラミンなんていう子供にもプログラミングが体験できるようなwebページを公開している。ドットインストールには僕も助けられている。
プログラミングの入門書はいくつも出版され、勉強会や講習会も多く開催されている。プログラミング人口を増やそうという試みが、全国的に、というか世界的に広がっている。
それでも、例えばプログラミングを義務教育に導入したとして、プログラマが増えるとは僕には思えない。それはなにも「数学を学んだから大学で数学を専攻するようになる」とか、「国語を学んだから小説家になる」とか(飛躍し過ぎだとは思うが)いう、エキスパートになることができないということではなく、「数学を勉強したが二次方程式は解けない」とか「国語を学んだが助詞が未だに正しく使えない」とかいうレベルでできないものはできないのだ。当たり前といえば当たり前であるが。
なぜプログラミングができないのか。それはやはり世界が違うからだ。数学は数の世界に、言葉は言葉の世界に分かれている。言葉の世界は生まれた時から強制的に放り込まれているからこの世界には慣れたものだし、この世界でうまくやれないと何をするにも難しい。数の世界なんかもある程度うまくやっていけないと文明社会で生きるには辛いものがある。
ところがプログラミングの世界ときたら、そんな世界に順応する必要があるわけでもなく、そのうえにその世界の住人から、自分たちの慣れ親しんだ世界用の成果物が放っておいてもどんどん出てくる。頼んでもないのにだ。こんな状況でプログラミングの世界に無理して慣れる必要なんて無い。
それに、プログラミングの世界には理解し難い、初見ではクリア不可能とも言える壁が存在する。 例えば数の世界の「ある数字の各桁の数の合計が3の倍数ならその数字は3の倍数である」というお作法(?)をプログラミングの世界の言葉で書くことを考える。
もう無理である。 数の世界でどうするか考え、それをプログラミングの世界の言葉にすることがまず難しい。各桁の数は一目瞭然だし、それぞれの数を足すのだって造作も無い。 しかしプログラミングの世界では、int型で数を覚えるのはわかっていても、
int num = 12345;
こっから「1」をどう取り出したらよいものか全くわからない。現実世界とのつながりが見えないのだ。だってプログラミングの世界だし。
#include<stdio.h>
int main(void){
int num = 12345;
int sum = 0;
for( ; num != 0; num /= 10 )
sum += num % 10;
if( sum % 3 == 0 )
printf("3で割り切れる");
return 0;
}
と、書かれたら「ああそんなやり方があったのか」と納得し、これからはこの方法を使って3の倍数かどうか求められるだろう。
コンピュータは「あいまい」を許さない。理解できない。それはつまり、プログラミングの世界で生きるためには完璧を求められるということ。それもプログラミングの世界での生き辛さの原因である。「アレ」とか「そこの奥」とかで通じたものが、いきなり「~/Documents/myExcelDocuments/明細.xlsxのA3」だなんて、無理だ。
今まで曖昧が許される世界にいただけあって、急にガチガチの間違えられない異世界に放り込まれると戸惑う。ただ、その世界が心地よい人もいる。人それぞれなのだ。プログラミングの世界に馴染むことのできない人は、数学の世界などのそれよりも多いだろう。プログラミングができないのは未経験だからではなく、その世界に住むことができないからだ。
僕もプログラミングの世界に住んではいる。いるが、その世界の中にもさらに世界がある。Cの世界だったり、Javaの世界だったり、その中でもandroidの世界がまたあったり……いま僕はiOSの世界に放り込まれて悪戦苦闘している。そんななかでふと思い浮かんだから書いてみただけである。プログラミングは難しい。今までのお作法が通じなかったりする。
とりあえず今作っているのが完成したら自分でまとめ直す。ので時間くれ。
共通鍵暗号と公開鍵暗号の解説とSSHでの認証手順 SSHの公開鍵と秘密鍵の関係 こういうところを読めば何となく分かるように、つまりは通信を暗号化するための鍵である、と。
必要な物は
まあ言わずもがな。
端末で
$ ssh-keygen
と入力すると、保存場所とパスフレーズを聞かれるので、それぞれこのように(パスフレーズは好きに)
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/username/.ssh/id_rsa): github_id_rsa
Created directory '/Users/username/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/username/.ssh/github_id_rsa.
Your public key has been saved in /Users/username/.ssh/github_id_rsa.pub.
The key fingerprint is:
00:11:22:33:44:55:66:77:88:99:aa<img alt="🇧🇧" class="emoji" src="/images/emoji/unicode/1f1e7-1f1e7.png">cc:dd<img alt="🇪🇪" class="emoji" src="/images/emoji/unicode/1f1ea-1f1ea.png">ff username@username-mac.local
The key's randomart image is:
+--[ RSA 2048]----+
| |
| |
| |
| |
| |
| |
| |
| |
| |
+-----------------+
これでSSH鍵ができましたーやったー!
SSH鍵の名前をデフォルトから変更したので、".ssh/config"に以下のように記述する。
Host github.com
User git
Hostname github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/github_id_rsa</pre>
あと、権限を変更しておく。
$ chmod 600 .ssh/github*
.ssh/github_id_rsa.pub
の中身をまるごとコピーする。
GitHub Setting SSH KeysからAdd SSH Keyをクリックして
ペーストする
端末で、
$ ssh git@github.com
を実行した結果が以下のようになれば成功!
$ ssh git@github.com
The authenticity of host 'github.com (204.232.175.90)' can't be established.
RSA key fingerprint is 00:11:22:33:44:55:66:77:88:99:aa<img alt="🇧🇧" class="emoji" src="/images/emoji/unicode/1f1e7-1f1e7.png">cc:dd<img alt="🇪🇪" class="emoji" src="/images/emoji/unicode/1f1ea-1f1ea.png">ff.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,204.232.175.90' (RSA) to the list of known hosts.
Identity added: /Users/username/.ssh/github_id_rsa (/Users/username/.ssh/github_id_rsa)
PTY allocation request failed on channel 0
Hi username! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.
GithubにSSH公開鍵を設定 初心者Git日記その五~GitHubにSSH公開鍵登録~ Github に SSH 公開鍵を登録する GitHub Help Categories/SSH
2013-12-26 リンク切れの削除と追加
#include <iostream>
#ifdef __cplusplus
#include <opencv2/opencv.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#endif
/*****************************************************
参考URL
http://opencv.jp/opencv2-x-samples/surf_extraction
*****************************************************/
int main(int argc, const char * argv[])
{
/*****カメラからのビデオキャプチャを初期化する*****/
//デフォルトカメラをオープン
cv::VideoCapture cap(0);
//カメラがオープンできない場合終了
if( !cap.isOpened() )
return -1;
//キャプチャ画像を1280*720で取得
cap.set( CV_CAP_PROP_FRAME_HEIGHT, 720 );
cap.set( CV_CAP_PROP_FRAME_WIDTH, 1280 );
/*****ウィンドウを作成する*****/
char windowName[] = "SURF-TEST";
cv::namedWindow( windowName, CV_WINDOW_AUTOSIZE );
//何かキーが押下されるまで、ループをくり返す
while( cvWaitKey( 1 ) == -1 )
{
cv::Mat gray , frame;
cap >> frame; //カメラからキャプチャ
cv::cvtColor( frame , gray , CV_RGB2GRAY ); //キャプチャ画像を処理用にグレースケール変換
/*****SURFクラスの初期化*****/
cv::SURF calc_surf = cv::SURF(500,4,2,true); //拡張ディスクリプタを用い128次元で取得
/*****SURF特徴をグレースケール画像から抽出*****/
std::vector<cv::KeyPoint> kp_vec; //C++の可変長配列(cv::Keypoint型)のベクトル配列を宣言
std::vector<float> desc_vec; //C++の可変長配列(float型)のベクトル配列を宣言
calc_surf( gray , cv::Mat(), kp_vec, desc_vec); //SURFディスクリプタ計算
/*****抽出したSURF特徴の位置とスケールを描画*****/
std::cout << "Image Keypoints: " << kp_vec.size() << std::endl; //標準出力に出力
#if 1
//この辺りちょっとよくわからない
//イテレータを使って???
std::vector<cv::KeyPoint>::iterator it = kp_vec.begin(), it_end = kp_vec.end();
for( ; it!=it_end; it++)
{
//円を描画
cv::circle( frame , /*描画先画像*/
cv::Point(it->pt.x, it->pt.y) , /*中心座標*/
cv::saturate_cast<int>(it->size*0.25) , /*半径*/
cvScalar(255,255,0) /*色*/
);
}
#else
for( int i = 0; i < kp_vec.size(); i++ )
{
KeyPoint* point = &(kp_vec[i]);
Point center; // Key Point's Center
int radius; // Radius of Key Point
center.x = cvRound(point->pt.x);
center.y = cvRound(point->pt.y);
radius = cvRound(point->size*0.25);
circle(colorImage, center, radius, Scalar(255,255,0), 1, 8, 0);
}
#endif
/*****適応的閾値処理による二値化*****/
/*
Mat adaptive_img;
//adaptiveThreshold(gray_img, adaptive_img, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 7, 8);
adaptiveThreshold(gray, adaptive_img, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 7, 6);
*/
//変換画像をウィンドウに表示
imshow( windowName, frame );
}
// ウィンドウを破棄する
cvDestroyWindow( windowName );
return 0;
}
アプリケーションのアップデートは、セキュリティ上の観念などから、バージョンが上がった時点で行うべきであるというのが僕の信条である。
さて、今朝docomoプリインストールアプリのアップデート通知がきたので、早速アップデートした。そして、ホーム画面に戻ると、何やら謎の何かが。
さて、この「しゃべってコンシェル」は邪魔なので消そう……としたところでアプリを起動すると使用許諾契約に同意を求められる。
お か し く ね ?
使用許諾契約にはこのように書いてある。 しゃべってキャラ対応しゃべってコンシェルアプリ ソフトウェア使用許諾規約
第4条(契約の成立、効力及び終了) 1. お客様が、本ソフトウェアの画面上に表示される「同意」ボタンを押下した時点をもって、お客様は本規約に同意したものとみなされ、お客様と弊社との間に本規約に基づく契約(以下「本契約」といいます。)が成立し、効力を生じるものとします。
はて、「同意」ボタンを押した覚えなどないのに起動しているということは、インストールした時点で使用許諾契約に同意したことになるのだろうか?でも使用許諾契約読んでないぞ? そもそも利用をしたくないのに使用許諾契約に同意しなければ利用の停止ができないとはどういうことなのだ? 腹が立つ。docomoは何を考えているのだろう。理解ができない。
お客様視点によるCS推進活動 さて、「お客様の満足度」を考えると、同意を得ていないサービスの提供というのははたして満足されるのだろうか?というか企業としてどうなのだ?
顧客にとっては、「繋がる」ことが当たり前であって(softbank除く)それによって満足度を得るのは難しい。しかし、繋がらないことや上記のことによって、満足度は簡単に低下する。満足度は上がりにくく下がりやすいから、努力が欠かせない。
なぜiPhoneが好まれるのか。キャリアによる不要なプリインストールアプリが無いからではないのか?その点で、本当に「お客様目線」で考えているとは考えがたい。
まあいちゃもんつけてるだけなんだけど、それでもこれには苛ついた。エンジニアは悪くない。体質が悪いのだ。
もしやMacPortsからOpenCVを導入したのは間違いだったのではと感じた。
OpenCVのインストールフォルダにdataフォルダがあって、その中のhaarcascadesフォルダに顔認識に必要なファイルがあるが、MacPortsからOpenCVをインストールするとそんなのはない。 Githubで落としてくるとかして手に入れなければならない。Itseez/opencv・GitHub
顔認識するときカメラ起動するとキモい顔が映って死ぬ。
#include <iostream>
#ifdef __cplusplus
#include <opencv2/opencv.hpp>
#endif
int main(int argc, char *argv[])
{
cv::Mat img , gray;
// カメラからのビデオキャプチャを初期化する
cv::VideoCapture cap(0);
//キャプチャ画像をRGBで取得
cap.set( CV_CAP_PROP_FRAME_HEIGHT, 720 );
cap.set( CV_CAP_PROP_FRAME_WIDTH, 1280 );
//カメラがオープンできない場合終了
if( !cap.isOpened() )
{
return -1;
}
// ウィンドウを作成する
char windowName[] = "camera";
cv::namedWindow( windowName, CV_WINDOW_AUTOSIZE );
// 分類器の読み込み(2種類あるから好きな方を)
std::string cascadeName = "/Users/yusuke/Desktop/data/haarcascades/haarcascade_frontalface_alt.xml";
//std::string cascadeName = "/Users/yusuke/Desktop/data/lbpcascades/lbpcascade_frontalface.xml";
cv::CascadeClassifier cascade;
if(!cascade.load(cascadeName))
return -1;
//画像を使う場合はこれ
/*const char *imagename = "example.jpg";
img = cv::imread(imagename, 1);
if(img.empty()) return -1;
*/
//scaleの値を用いて元画像を縮小、符号なし8ビット整数型,1チャンネル(モノクロ)の画像を格納する配列を作成
double scale = 4.0;
// 何かキーが押下されるまで、ループをくり返す
while( cvWaitKey( 1 ) == -1 )
{
cap >> img;
// グレースケール画像に変換
cv::cvtColor(img, gray, CV_BGR2GRAY);
cv::Mat smallImg(cv::saturate_cast<int>(img.rows/scale), cv::saturate_cast<int>(img.cols/scale), CV_8UC1);
// 処理時間短縮のために画像を縮小
cv::resize(gray, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR);
cv::equalizeHist( smallImg, smallImg);
std::vector<cv::Rect> faces;
/// マルチスケール(顔)探索xo
// 画像,出力矩形,縮小スケール,最低矩形数,(フラグ),最小矩形
cascade.detectMultiScale(smallImg, faces, 1.1, 2, CV_HAAR_SCALE_IMAGE, cv::Size(30, 30));
//cascade.detectMultiScale(smallImg, faces);
// 結果の描画
std::vector<cv::Rect>::const_iterator r = faces.begin();
for(; r != faces.end(); ++r)
{
cv::Point center;
int radius;
center.x = cv::saturate_cast<int>((r->x + r->width*0.5)*scale);
center.y = cv::saturate_cast<int>((r->y + r->height*0.5)*scale);
radius = cv::saturate_cast<int>((r->width + r->height)*0.25*scale);
cv::circle( img, center, radius, cv::Scalar(80,80,255), 3, 8, 0 );
}
//cv::namedWindow("result", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
cv::imshow( windowName, img );
//cv::waitKey(0);
}
}
リンクさせるライブラリは
libopencv_core.2.4.5.dylib
libopencv_highgui.2.4.5.dylib
libopencv_imgproc.2.4.5.dylib
libopencv_objdetect.2.4.5.dylib
libstdc++.dylib
Build Setting→Apple LLVM compiler 4.2 - Language
から、C++ Standard Library を ibstdc++(GNU C++ standard library)
に設定する。
htc j butterflyという端末は防滴で充電端子があるのにスタンドが売り切れだから作るしかなかった
ケーブルを切ってピンヘッダを切って抜いてハンダ付けして終わり。
でもこれだけだと手で押さえるかテープで貼ったりしないと充電できないので……
こんなのをLEGOで作った
こんな感じに端子が接触して充電される
//
// main.cpp
// OpenCV-Cameratest
//
// Created by unasuke on 2013/05/27.
// Copyright (c) 2013年 unasuke. All rights reserved.
//
#include <iostream>
#ifdef __cplusplus
#include <opencv2/opencv.hpp>
//#include <opencv2/highgui/highgui.hpp>
#endif
int main(int argc, const char * argv[])
{
// insert code here...
// カメラからのビデオキャプチャを初期化する
//macではカメラの順序が最初なのでcvCreateCameraCaptureに渡す引数は0
CvCapture *videoCapture = cvCreateCameraCapture( 0 );
if( videoCapture == NULL )
{
return -1;
}
// ウィンドウを作成する
char windowName[] = "camera";
cvNamedWindow( windowName, CV_WINDOW_AUTOSIZE );
// 何かキーが押下されるまで、ループをくり返す
while( cvWaitKey( 1 ) == -1 )
{
// カメラから1フレーム取得する
IplImage *image = cvQueryFrame( videoCapture );
// ウィンドウに画像を表示する
cvShowImage( windowName, image );
}
// ビデオキャプチャを解放する
cvReleaseCapture( &videoCapture );
// ウィンドウを破棄する
cvDestroyWindow( windowName );
return 0;
}
リンクさせる.dylibは
libc++.dylib
libopencv_core.2.4.5.dylib
libopencv_highgui.dylib
の3つ(画像加工をしないので)
MacのiSight?内蔵カメラは最初に接続されてるのでcvCreateCameraCaptureに渡す引数は0。
C++の設定だけどC++要素全くない。