Hatena::ブログ(Diary)

Over&Out その後 このページをアンテナに追加 RSSフィード Twitter

2012-11-29

たったの6ステップ!『漫画カメラ』風に写真を加工するiPhoneアプリの作り方

超大ヒットした『漫画カメラ』、ほんとに漫画っぽくなって、動作も軽快、シェアも簡単で楽しいですよね。


ただ、ちらほらと「同じこと考えてた」「そういうの作ってた」という声を聞くことがあります。実際に同様のコンセプトのアプリもたくさん出ています。


実は、カヤックでも、2年ほど前、Instagramが出てきた頃に"Comicgram"という企画が出たことがあって、ちょっとだけモックアプリをつくったことがありました。


そのときつくったモックアプリで自動で写真加工した結果がこちら

f:id:shu223:20121129210530p:image


『漫画カメラ』ほど漫画っぽくないかもしれませんが、それっぽいといえばそれっぽいです。


実は、このモックアプリはOpenCVにもともと備わっている機能を組み合わせただけなので、結構サックリ実現できます


以下でその6ステップの処理内容について紹介させていただきます。


ステップ1:領域分割

『画像ピラミッドを用いた画像の領域分割』というのをやります。領域分割とは、色情報をもとに画像内をセグメント化する処理です。次の画像がわかりやすいかと思います。


f:id:shu223:20121129082946p:image:w100

OpenCVのページからお借りしました)


実装にあたっては細かいアルゴリズムを知っている必要はなく、OpenCV の cvPyrSegmentation 関数を呼べばOKです。

cvPyrSegmentation (cvsrc, cvdst, storage, &comp, level, threshold1, threshold2);

引数が何やら多いですが、モックアプリでは、level に 4、threshold1 に 255.0、threshold2 に 50.0 を渡しています。

CvMemStorage *storage = 0;
CvSeq *comp = 0;
storage = cvCreateMemStorage (0);
IplImage *cvdst = cvCloneImage (cvsrc);
cvdst = cvCloneImage (cvsrc);
cvPyrSegmentation (cvsrc, cvdst, storage, &comp, 4, 255.0, 50.0);
cvReleaseMemStorage (&storage);

領域分割だけをかけた状態では、こんな感じ。


f:id:shu223:20121129083047j:image:w160


ちなみに Photoshop でいう『ポスタリゼーション』を使って階調を減らすのと効果が似ていますが、あちらは画素単体の色値だけを見て階調を間引くだけなのに対し、領域分割は「領域」とついている通り、周囲の画素の色値との関係も見ているので、まとまりを伴って階調を減らすことになり、より漫画っぽい効果が得られます(その分処理は重いです)


ステップ2:白黒にする

グレースケール(いわゆる白黒)にします。


OpenCV の cvCvtColor 関数を呼ぶだけ。

cvCvtColor(cvsrc, cvgray, CV_BGR2GRAY);

こんな感じになります。


f:id:shu223:20121129083143j:image:w160


グレースケール化の前に領域分割を行うのは、情報量が多い方が(色のチャネルが多い方が)領域分割の精度が高い(と当時の僕が考えた)からです。


ステップ3:ハイライトをとばす

ハイライトとは色値が明るい部分、つまり限りなく白に近いグレー部分です。漫画っぽくするために、いっそのこと白く飛ばしてしまいます。


forループで画素ごとに色値を見ていって、しきい値以上であれば白(255)にします。

for(int y=0; y<cvgray->height; y++) {
    for(int x=0; x<cvgray->width; x++) {
        uchar *p = (uchar *)cvgray->imageData + y * cvgray->widthStep + x;
        *p = *p >= threshold ? 255 : *p;
    }
}

モックでは threshold (しきい値)を 200 にしてます。


f:id:shu223:20121129083255j:image:w160


ステップ4:スクリーントーンをあてる

陰影を漫画っぽく表現するために、スクリーントーン風パターン画像を用意し、


f:id:shu223:20121129084941p:image


これを色値が特定の範囲におさまる領域に当てはめて行きます。たとえば色値が151〜200の範囲の領域には薄めのトーンを当てはめる、といった感じです。


モックではスクリーントーンのパターン画像と入力画像を同じサイズに揃えたあと、次のようなOpenCVを用いた自作関数に渡して、パターンへの置き換え処理を行っています。

/* min から maxまでをパターン画像で埋める */
- (UIImage *)createPatternedImage:(UIImage *)src
                          pattern:(UIImage *)pattern
                     minThreshold:(int)minThreshold
                     maxThreshold:(int)maxThreshold
{
    // UIImageをIPlImageに変換
    IplImage *cvsrc = [self CreateIplImageFromUIImage:src];
    IplImage *cvdst = [self CreateIplImageFromUIImage:pattern];
    
    // グレースケール
    IplImage *cvgray = cvCreateImage(cvGetSize(cvsrc), IPL_DEPTH_8U, 1);
    cvCvtColor(cvsrc, cvgray, CV_BGR2GRAY);
    
    // 2値化してマスクを作成する
    /*
     CV_THRESH_BINARY : 閾値を超えるピクセルは maxVal に,それ以外のピクセルは 0 になります.
     CV_THRESH_BINARY_INV : 閾値を超えるピクセルは 0 に,それ以外のピクセルは maxVal になります.
     */
    // maxThresholdを超える領域は処理対象外
    IplImage *cvmask = cvCloneImage (cvgray);
    cvThreshold (cvgray, cvmask, maxThreshold, 255, CV_THRESH_BINARY);
    
    // minThresholdより小さい領域は処理対象外
    IplImage *cvmask2 = cvCloneImage (cvgray);
    cvThreshold (cvgray, cvmask2, minThreshold, 255, CV_THRESH_BINARY);
    cvNot(cvmask2, cvmask2);	// 反転
    
    cvReleaseImage(&cvgray);
    
    // 2つのマスクの論理和
    cvAdd(cvmask, cvmask2, cvmask, NULL);
    
    cvCopy(cvsrc, cvdst, cvmask);
    cvReleaseImage(&cvsrc);
    cvReleaseImage(&cvmask);
    cvReleaseImage(&cvmask2);
    
    // 出力UIImageを生成
    UIImage *dst = [self UIImageFromIplImage:cvdst];
    cvReleaseImage(&cvdst);
    
    return dst;
}

上記関数では何をやっているかというと、指定した色値の範囲に収まるピクセルだけを残したマスク画像を生成し、そのマスクに従ってスクリーントーンのパターンを合成する、ということをやっています。


ここまでの処理結果はこんな感じです。


f:id:shu223:20121129083450j:image:w160


モックでは4段階のスクリーントーン画像を使っています。トーン画像を変えればまたかなり画風が変わってくるので、このあたりでフィルタのバリエーションを増やすと楽しそうです。


ステップ5:輪郭線をつける

最後に輪郭線をつけるとグッと漫画っぽくなります。


『適応的閾値処理』というのを用いて、輪郭線を生成します。

cvAdaptiveThreshold(cvgray, cv1bit, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, blockSize, 10);

単なる二値化や、エッジ抽出フィルタでは、いい感じに輪郭線を生成できません。「適応的に」二値化するのがポイントです。適応的に、というのは近傍の画素を見ながら閾値処理を行うという意味ですが、上記のように cvAdaptiveThreshold を用いればOKです。


生成した輪郭を、元画像に合成するとこんな感じになります。


f:id:shu223:20121129083522j:image:w160


ステップ6:集中線画像を合成

最後に集中線の画像を合成します。


f:id:shu223:20121129211604p:image:w100


合成には cvAdd 関数を使います。


cvAdd(src1, src2, dst, NULL);

これでグッと漫画っぽくなります。


f:id:shu223:20121129211828j:image:w160


『漫画カメラ』のようにこれにセリフや擬音を当てはめて、たくさんの種類を用意するとバリエーションが豊かになります。


まとめ

漫画カメラ風写真加工を実現するための6ステップの画像処理方法を紹介しました。


漫画風に加工するためのアルゴリズムはこれ意外にも何通りも考えられると思います。漫画風にするポイントは、階調を減らしてスクリーントーンをあてはめる、輪郭をつけるというところなので、このアルゴリズムのように領域分割といった重い処理を用いない方法も可能かと思います。


OpenCV以外にもハードウェアアクセラレーションの効いた vImage を用いる方法や、 CoreImageを用いる方法 もあるので、AppStoreにリリースするレベルのものをつくる際にはぜひ検討してみてください。



2012-11-27

たった1行でWebサービスと連携!UIActivity のまとめリポジトリをつくりました

UIActivityとは?

地味だからかあまり話題になってない気がするのですが、iOS 6 の便利な新機能の1つに UIActivity というのがあります。これは、


f:id:shu223:20120923052239p:image:w240


こんな感じでメールとか写真アプリとかFacebook/Twitterとかに写真やテキストを渡すためのUIです。(超ざっくり)


実装も超簡単!

投稿も写真アルバムへの保存もこれ一つでOKかつ実装も超簡単なので、もうTwitter.frameworkとか、Social.frameworkとか、MessageUI.frameworkとかは使わなくなってしまいました(※UIActivityViewControllerが内部的には使ってると思います)


UIActivity (UIActivityViewController) の実装コードはこんな感じです。

- (IBAction)pressBtn {

    NSString *text  = @"投稿するテキスト";
    NSURL    *url   = [NSURL URLWithString:@"http://投稿するURL.com"];    
    NSArray *activityItems = @[text, url];

    UIActivityViewController *activityView = [[UIActivityViewController alloc] initWithActivityItems:activityItems
                                                                               applicationActivities:@[]];    
    [self presentViewController:activityView animated:YES completion:nil];
}

「Twitter投稿の実装が簡単になった!」と iOS5 時代に大歓迎された TWTweetComposeViewController とそんなに実装量が変わらないですよね?


そんなわけで、僕はここ最近はほぼ確実に UIActivity を入れています。(OSのバージョン判定して、iOS6以上ならUIActivity、iOS5.XならTwitter.frameworkという実装をスニペットから貼り付けるだけなのでだいたい5分ぐらい)


カスタムUIActivityで、簡単に機能追加!

そんな便利な UIActivity ですが、さらに便利なことに、カスタムUIActivityをつくって UIActivityViewController に追加することができるのです。


どういうことかというと、たとえば、ARChromeActivity というライブラリを使うと、UIActivityViewController に Chromeアプリで URL を開くためのアイコンが追加されます。


f:id:shu223:20121127204445p:image:w200


で、このカスタムUIActivityの追加がまたラクなのです。

たとえば ARChromeActivity を追加したい場合に、上述したコードに追加するコードは1行だけ

ARChromeActivity *chromeActivity = [[ARChromeActivity alloc] init];

これを、UIActivityController を初期化する際の applicationActivities 引数に渡してやると、

UIActivityViewController *activityView = [[UIActivityViewController alloc] initWithActivityItems:activityItems
                                                                           applicationActivities:@[chromeActivity]];    

これだけの変更で Chrome アプリとの連携機能が実現するという優れものです。


カスタムUIActivityのまとめリポジトリ:UIActivityCollection

ずいぶん前置きが長くなってしまいましたが、そんなカスタムUIActivity を集めたリポジトリをつくりました。


https://github.com/shu223/UIActivityCollection


実装の参考用に、デモアプリも入っています。


f:id:shu223:20121212122550p:image:w200


ダウンロード方法

リポジトリはサブモジュールの形で入っているので、下記のように git で clone した後に submodule コマンドを実行してください。

$ git clone git://github.com/shu223/UIActivityCollection.git
$ cd UIActivityCollection/
$ git submodule update --init --recursive

本家リポジトリからファイル一式がダウンロードされます。


対応サービス/アプリ一覧

11/27現在でリポジトリに入っているサービス/アプリはこちら。

  • Buffer
  • Dropbox
  • Flattr
  • Instagram
  • Instapaper
  • Pinboard
  • Pinbook
  • Pocket
  • Readability
  • SoundCloud
  • Tumbletail

Githubで検索して集めただけなのですが、まだまだ意外と少ないなぁという印象です。

#この程度の数だと、カスタム UIActivity をオープンソースで配布することで、世界の誰かが見つけてくれてアプリに組み込んでくれたりしそうなので、カスタム UIActivity を配布すること自体がサービス/アプリのプロモーションに繋がるかも。


(2012/12/4追記)以下の2つの UIActivity を追加しました。


(2012/12/6追記)以下の2つの UIActivity を追加しました。

  • LINE
  • KakaoTalk

(2012/12/12追記)以下の2つの UIActivity を追加しました。

  • AppStore
  • In-App(アプリ内でUIWebViewに表示)

また、デモアプリの対応UIActivityを増やしました。


(2012/12/19追記)以下の2つの UIActivity を追加しました。

  • Google Maps
  • Nakamap

まとめ

思いのほか長くなってしまいましたが、カスタム UIActivity のまとめリポジトリ『UIActivityCollection』のご紹介でした!



2012-11-25

iOS のオーディオ/サウンド処理について学べる書籍10冊+α

Core Image や vImage や OpenCV、それらをラップする各種ライブラリの充実のおかげで、画像処理まわりは高度な処理をずいぶん簡単に高速に実装できるようになってきましたが、オーディオ処理(音声処理)まわりはいまだに再生や録音などの基本的なところから一歩踏み込もうとすると途端に敷居が高くなるイメージがあります。


たとえば2年ほど前にリリースした『i聖徳太子』は、「左右のイヤフォンから別々の音を再生する」という非常にシンプルなアイデアですが、たったこれだけのことでも AVAudioPlayer やMPMusicPlayerController とかだけでは実現することができず、OpenALやAVAsset等を使用して実現しています。


で、もうちょっとオーディオ処理まわりを勉強してみたいなと思い、まず手元にある書籍で参考になりそうなものを洗い出してみました。


以下、(だいたい)出版年月順に並べています。


iOS Core Frameworksテクニカルガイド

iOS Core Frameworksテクニカルガイド
Shawn Welch
インプレスジャパン
売り上げランキング: 242494


2012年9月と比較的最近出版されたものですが、原著の出版は2011年9月。したがって iOS5 時代のものです。


『Core Audio』という章があり、iPodのミュージックライブラリを使ったプレイヤーの実装方法や、AVAudioPlayer を用いたオーディオ再生方法について解説されています。


この本はグラフィックスやアニメーションについてはかなり詳しく書かれているのですが、サウンド周りに関して言えば、既出情報しかないなぁという印象です。


iOS5プログラミングブック

iOS5プログラミングブック
加藤 寛人 吉田 悠一 藤川 宏之 西方 夏子 関川 雄介 高丘 知央
インプレスジャパン
売り上げランキング: 88968


Chapter 9-2 『オーディオの新機能』という章に、Audio Unit に関する詳しい解説が載っています。Audio Unit は Core Audio の中でも最も低レイヤにあるため、自由度とパフォーマンスに優れる反面、実装の敷居が相当高い印象があったので、これはかなり貴重な情報といえます。(iOS 5 で増強された機能なので、後に紹介するCore Audio本にも載っていない内容もあります)


サンプルとして取り上げてられているのは「マイクから入力された音声にリバーブをかけるカラオケアプリ」で、AUGraph や AUNode について学べる好サンプルとなっています。


iOSプログラミング 第2版

iOSプログラミング 第2版
アーロン・ヒレガス ジョー・コンウェイ Aaron Hillegass Joe Conway
ピアソン桐原
売り上げランキング: 268758


第27章『メディア再生とバックグラウンドの実行』という章があり、iPodライブラリの再生、AVAudioPlayerを使ったmp3の再生、システムサウンドといった、基本的な事項について解説されています。


iOSプログラミング逆引きリファレンス110

iOSプログラミング逆引きリファレンス110 [iOS 5.1対応]
近藤 修平 畠山 貴 森田 秀幸 森本 一茂
マイナビ
売り上げランキング: 199047


第3章『カメラ・サウンド』で、SEやBGMの再生、iPodライブラリから曲を検索する方法などについて書かれています。逆引き形式で調べやすいのですが、サウンドまわりはあまりレア情報は見受けられず。


iOS4プログラミングブック

iOS4プログラミングブック
畑 圭輔 加藤 寛人 坂本 一樹 藤川 宏之 高橋 啓治郎 沖田 知彦 柳澤 昇
インプレスジャパン
売り上げランキング: 32117


第3章『マルチメディア』で、まるまる約70ページが AV Foundation の解説に割かれています。AV Foundation で何ができるか、音の再生といった基礎的なところから、カメラ関係の処理、AVCapture を用いたマイクからの音声取り込み方法、メタデータの処理、動画の編集とエクスポートなどなど、非常に盛りだくさんです。


特に後半は、マイクから入力される音声波形データの取得方法や、動画と音声を組み合わせた処理の方法など、知っておくと色々と応用が効きそうな方法の解説が充実しています。


iOS SDK Hacks ―プロが教えるiPhoneアプリ開発テクニック

iOS SDK Hacks ―プロが教えるiPhoneアプリ開発テクニック
吉田 悠一 高山 征大 UICoderz
オライリージャパン
売り上げランキング: 226658


目次をざっとみると音声処理に関するトピックはないのですが、第6章に@sonsonさんが書いたAccelerate.frameworkの項があるので、音声処理にvDSP等を使用して算術計算を行いたい場合(たとえばフーリエ変換を用いて周波数領域での処理を行いたい場合)などに参考になるかもしれません。


iPhoneSDK開発のレシピ

iPhoneSDK開発のレシピ
iPhoneSDK開発のレシピ
posted with amazlet at 12.11.26
高山 恭介 広部 一弥 松浦 晃洋
秀和システム
売り上げランキング: 72562


こちらもずいぶん前に出た本ですが、「AudioQueueで再生する」「AudioQueueで再生時のレベルを取得する」「AudioQueueでマイクから録音する」「音を関知するスイッチを作る」「OpenALで再生する」といった勉強になりそうな貴重なレシピが載っています。


iPhone Core Audioプログラミング

iPhone Core Audioプログラミング
永野 哲久
ソフトバンククリエイティブ
売り上げランキング: 28453

iOSの音声処理本といえばこれでしょ、で話が終わってしまいそうな殿堂入り本。500ページ超という極厚本でありながら、すべてが Core Audio についての解説にあてられているということからも、その情報の充実っぷりは伺えると思います。


何が載っています、ということを書いてもキリがないので、何が載ってないかということだけ書くと、iOS3.X時代に書かれたものなので、それ以降に追加された機能については(当然ですが)載っていません。


iPhone SDK アプリケーション開発ガイド

iPhone SDK アプリケーション開発ガイド
Jonathan Zdziarski
オライリージャパン
売り上げランキング: 28500


iOS開発本としてはかなり初期に出た本なのであまり期待してなかったのですが、第6章『iPhoneのサウンド - Audio Toolbox と AVFoundation』で、AudioQueue を用いたオーディオ処理について30ページにわたる解説が載っていました。AudioQueue で録音して生データにアクセスし、ファイル出力するところまで、かなり詳細に解説されています。


その他にもAVAudioPlayerで音量メーターを作るサンプルもあります。


iPhone デベロッパーズ クックブック

iPhone デベロッパーズ クックブック
Erica Sadun
ソフトバンククリエイティブ
売り上げランキング: 283151


発売日が2009年2月と、相当に古い本ですが、第7章『メディア』に、AudioQueueでの録音や、「バックアップファイルからのメディアの復元」といった珍しいレシピも載っています。Celestial という非公開フレームワークの使い方についても解説されています。


その他

Beyond Interaction ―メディアアートのためのopenFrameworksプログラミング入門

Beyond Interaction ―メディアアートのためのopenFrameworksプログラミング入門
田所 淳 比嘉 了 久保田 晃弘
ビー・エヌ・エヌ新社
売り上げランキング: 222538


「プレイヤーの演奏にリアルタイムに反応するグラフィックス」というサンプルが載っていて、FFTをかける、ノイズを除去する、とかやってて、openFrameworks を使うにしろ使わないにしろ、ひとつのサウンド処理の応用サンプルとして参考になりそうです。


Pd Recipe Book -Pure Dataではじめるサウンドプログラミング

Pd Recipe Book -Pure Dataではじめるサウンドプログラミング(単行本)
松村 誠一郎
ビー・エヌ・エヌ新社
売り上げランキング: 198038


iOS SDK ではなく Pure Data を用いたサウンドプログラミングの本ですが、サウンドをプログラムで扱うにあたって、「どういう処理をどう組み合わせるとどんなことができるのか」という参考になりそうと思いここに載せました。


掲載されているパッチを見ているだけでも参考になるし、実際にPure Dataをアプリ開発前のプロトタイピング的に使うのもありかと思います。



2012-11-24

CALayer を用いた「影」の描画処理を軽くする

CALayerを用いてUIViewを継承したクラスに影をつける方法は、下記のような感じで(CoreGraphicsで描画する方法などと比べて)わかりやすくお手軽で、質感もグッと増すので、ついつい多用したくなります。


self.layer.shadowOpacity = 0.5;
self.layer.shadowRadius = 2.0;
self.layer.shadowOffset = CGSizeMake(0.0, 0.0);

ただ、影とか透過とかの処理はなかなか重いらしく、例えば UITableViewCell に置いた背景用画像に影をつけると、iPhone4ぐらいでも完全に体感できるぐらいに遅くなってしまいます。


で、このコードに下記の3行を付け加えてやると、体感でわかるぐらいに改善されます。


self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds].CGPath;
self.layer.shouldRasterize = YES;
self.layer.rasterizationScale = [UIScreen mainScreen].scale;

shadowPath で、影をつける矩形のパスをあらかじめ与えてやり、shouldRasterize を YES にして rasterizationScale をセットしてやることで、ビットマップとしてプリレンダリングされるらしいです。

(※本家ドキュメント未確認です)


(参考ページ)

http://stackoverflow.com/questions/8333736/uitableview-lagging-due-to-shadows-and-borders



2012-11-18

DropBox 連携 UIActivity、"GSDropboxActivity" の使い方

DropBox用カスタムUIActivity、"GSDropboxActivity" の導入方法(のメモ)です。


GSDropboxActivity


UIActivityとは何ぞや?という方はこちらの記事 からどうぞ。


準備

  • GSDropboxActivity フォルダをプロジェクトに追加
  • DropboxSDK.framework をプロジェクトに追加

実装

ヘッダインポート

#import "GSDropboxActivity.h"

呼び出し
GSDropboxActivity *dropboxActivity = [[GSDropboxActivity alloc] init];
UIActivityViewController *activityView = [[UIActivityViewController alloc] initWithActivityItems:activityItems
                                                                           applicationActivities:@[dropboxActivity]];

補足

上記実装は UIActivityViewController に連携用アイコンが出てくるところまでしか試していません。

アップロードとかエラーの細かいハンドリングは、本家リポジトリに入っているデモのソースをご参照ください。



2012-11-03

英単語の単数形/複数形変換をメソッド1つで行えるようにする NSString のカテゴリ

iOS アプリを英語ローカライズする際,単数形/複数形の取り扱いはなかなかやっかいです。-s, -es の違いを始めとして,不可算名詞,person/peopleのようにイレギュラーなものもあります。


それら諸々のルールをプロパティリストファイルに記述し,

- (NSString *)pluralizeString;
- (NSString *)singularizeString;

このように非常にシンプルなメソッドで単数/複数変換を行えるようにしたカテゴリが ActiveSupportInflector です。


使い方

1. ダウンロード

https://github.com/tomafro/ActiveSupportInflector


2. プロジェクトに追加

NSString+ActiveSupportInflector クラス、ActiveSupportInflector クラスと、ActiveSupportInflector.plist をプロジェクトに追加します。


どんな変換ができるようになる?

本カテゴリによってどんな変換ができるようになるかは,リポジトリ内に付随しているテストケース用のプロパティリストファイルActiveSupportInflectorTest.plistを見ると一目瞭然ですので,使用を検討されている方はチラッとのぞいてみてください。以下に一部抜粋しておきます。

#イレギュラーケースがまとまっているので、英語の勉強にもなります。。

("search", "searches"),
("stack", "stacks"),
("fish", "fish"),
("category", "categories"),
("ability", "abilities"),
("agency", "agencies"),
("index", "indices"),
("wife", "wives"),
("safe", "saves"),
("half", "halves"),
("person", "people"),
("man", "men"),
("woman", "women"),
("basis", "bases"),


※本記事は、gihyo.jpの連載第3回 の一部を焼き直したものです。

(長めの記事の最後の方にチラッと出しただけなので、そこまで読んでない人が多いと思い、こちらに再掲しました)



2009 | 08 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2015 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2016 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 11 | 12 |
2017 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2018 | 02 |