読者です 読者をやめる 読者になる 読者になる

OpenCV3.1をOSXでJava(Eclipse)で実行する

OpenCV3をMacで使おうと思ったらかなり苦労したのでメモしておきます。

最初OpenCV3をGitでチェックアウトして使おうと思ったら迷走しました。

Windowsであればexeを実行してすぐ使える状態なんですが、Macだと苦労・・・

結局Homebrewで入れたんですが、それでも一曲あったので実行できるまでの流れをメモしておきます。

環境

1.OpenCV3.1を入れる

※Homebrewが使えることを前提に進めます。

brew tap homebrew/science
brew install opencv3 --with-java

--with-javaでjarが用意されます。
最初この指定を忘れていて、用意されなかったので一旦アンインストールしました。

brew uninstall opencv3

その後再度installしようとすると以下のエラーがでました。

Error: You must `brew link eigen libpng libtiff ilmbase openexr numpy` before homebrew/science/opencv3 can be installed

brew linkしろって言ってるので言われてる通りしてみます。

brew link libtiff ilmbase openexr numpy

するとまたエラー。。。

Error: Could not symlink lib/pkgconfig/libtiff-4.pc
/usr/local/lib/pkgconfig is not writable.

権限の問題なので付与します。

sudo chmod g+w include/

無事インストールできたら以下のような構成になると思います。

/usr/local/Cellar/opencv3/3.1.0_1/share/OpenCV/java/

  • libopencv_java310.so
  • opencv-310.jar

これでOpenCVの用意は完了です。
次はEclipseで使えるようにしましょう。

Eclipseにライブラリを取り込む

Eclipseで新しいJavaプロジェクトを作成して、ライブラリを単純に追加というわけではなく、jarを追加したあと、ネイティブライブラリとして追加する必要があります。

そこら辺の記述はググればいっぱいでてきますが、日本語で説明している記事見つけたのでリンク貼って割愛します。

JavaでOpenCVのインストール・eclipseの設定など(Mac OSX) | takuroYONEZAWA

※記事では2.4.4ですが、3.1.0に読み替えてください。

追加するjarのパスは上記でも説明したとおり以下です。 * /usr/local/Cellar/opencv3/3.1.0_1/share/OpenCV/java/opencv-310.jar

で、問題のネイティブライブラリですが、作成されたファイルはlibopencv_java310.soです。
Macでの実行なので、拡張子を変更してlibopencv_java310.dylibにします。

よってネイティブライブラリのパスは以下です。 * /usr/local/Cellar/opencv3/3.1.0_1/share/OpenCV/java/libopencv_java310.dylib

OpenCVでいうHelloWorld

OpenCV java」とググるとよく見るサンプルのコードを実行することで、動作が正しく動くかの確認ができるようです。

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
 
public class Hello {
    public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat m  = Mat.eye(3, 3, CvType.CV_8UC1);
        System.out.println("m = " + m.dump());
    }
}
実行結果

m = [ 1, 0, 0;
0, 1, 0;
0, 0, 1]

うまくいくと上記のような結果が表示されます。

ネイティブライブラリのパスが正しく書かれているかは以下で確認できます。

System.out.println(System.getProperty("java.library.path"));

とりあえず今日は動くところまで!

以上ですー。

DeepLearningで画像から判断してみよう #1

最近仕事で今表示されている画面から判断して自動で入力して、作業を行うことができないかという話が上がったので色々調べてみた。

今回はその第一弾として、まずは調べた結果をまとめておきます。

画面のスクショから何の画面か判断する

まずはこれです。今開いている画面のスクショを撮影し、何の画面が開いているかという判断をまず行う必要があります。
画像といえばOpenCVです。
最近はOpenCV3が出て、12月末にはOpenCV3.1がリリースされています。

OpenCV 3.1 | OpenCV

OpenCV3になってからDeepLearningの機能が強化されたようです。
contlibとかって、ライブラリ機能が別で用意され自前で必要なものを用意するとか。。。
(まだこの辺はあまりよくわかってないです)

テンプレートを予め用意して、マッチングする箇所の座標を調べる方法としてTemplateMatchingという方法を取るようです。

Template Matching — OpenCV 2.4.12.0 documentation

画面のスクショとって、そのスクショの画像から場所を特定したいボタンだけを別画像でテンプレートとして用意してTemplateMatchingをやってみました。

for文で単純にX軸とY軸を少しずつ移動し、テンプレート画像と一致する場所を特定するという方法を取るわけですが、まぁ見事に場所は特定されるわけです。
けどボタンのサイズが変わったり画素数が変わるとうまくいくのかというと怪しい。。

ということは、テンプレート画像を縮小してみたり、ターゲット画像とテンプレート画像をグレースケール変換して比較してみたりといろいろ必要になります。

DeepLearningでやる前に読んでみたい記事

要はやりたいことってこれだなーと思った記事が以下。
※職場では少し開きづらい記事だなw

d.hatena.ne.jp

qiita.com

[Chainer] Deep Learning でアニメ (ゆるゆり) キャラクターを識別する(2015/11/4少し追記) | まさかり募集中

kivantium.hateblo.jp

christina.hatenablog.com

bohemia.hatenablog.com

ChainerやGoogleが突然公開したTensorFlowを利用して学習させましょうということのようですね。

がしかし、学習用の画像を数千枚・・・

この方々は数千枚もの画像を用意したというのか・・・・

ワンパンマンが見たくて。。

今期アニメも最終回を無事次々と迎えてますね。

今期のアニメであったワンパンマン、調べてみると「となりのヤングジャンプ」というWEBサイトでマンガを無料公開しているではないですか。
(うまるのスピンオフもあるんだ・・・今知ったわ。。ザワザワ) f:id:kakushika:20151231065506p:plain

ただiPhoneで通勤中見ようと思ったら、レイアウト崩れが酷くて読めるレベルじゃない! f:id:kakushika:20151231072943p:plain

だったらSwiftで専用のビューアを作ってしまえ!ということで作りました↓ f:id:kakushika:20151231070104g:plain

色々と本当はまだ手を加えるべきですが、AppStoreに公開するわけでもなく個人で楽しむ用なので一旦終了の意味も込めて今回やったことのメモ書きをしておきます。

環境

  • iOS SDK 9.1
  • Swift2.1
  • Xcode7.1

CocoaPods

Kanna

github.com

  • 今回わざわざ作ろうと思ったきっかけのライブラリ。
  • RubyのNokogiriのiOS版みたいなもの。
  • CSSセレクタが利用できたので、簡単に必要な情報だけ抜き出して操作できた。

SVProgressHUD

github.com

SDWebImage

github.com

  • これも言わずと知れた画像のライブラリ。
  • 画像の読み込み時のスレッド処理を意識することなく書ける本当にいいライブラリ。

RealmSwift

realm.io

  • 最近使って見てるRealmさん。
  • 前まではORマッパーのMagicalRecordを使ってましたが、最近はこっちの方が書き方が楽でいい。
  • 今回は今までの冗長な書き方とは別の書き方でできたので、また勉強になった。

JOLImageSlider

github.com

  • 画像のスライダーです。
  • マンガ新刊情報でも使ったライブラリで、少しマンガ新刊情報用に拡張してるものを流用しました。

まとめ

これでおれのワンパンマンライフも快適だぜ!と思った矢先、公式の「となりのヤングジャンプ」さんは改修を行ったようで、正しくiPhoneで見れるようになってました。。。年末にお疲れ様です(いろんな意味で涙目)

Swift2.0で正規表現

Swift正規表現扱うときどうやるんだろうと思って調べてるうち行き着いた先が「EasyRamble」さんの以下の記事です。 http://easyramble.com/swift-regular-expression-utility.html

ただSwift2.0になって少し変わっているようなので、手を加えました。

init

変更前

init(_ pattern: String) {
    self.pattern = pattern
    var error: NSError?
    self.internalRegexp = NSRegularExpression( pattern: pattern, options: NSRegularExpressionOptions.CaseInsensitive, error: &error)!
}

変更後

NSRegularExpressionの引数にエラーが含まれなくなったようです。 なので以下のようにtry catchへ変更しました。

init(_ pattern: String) {
    self.pattern = pattern
    do {
        self.internalRegexp = try NSRegularExpression(pattern: pattern, options: [])
    } catch let error as NSError {
        print(error.localizedDescription)
        self.internalRegexp = NSRegularExpression()
    }
}

isMatch

変更前

func isMatch(input: String) -> Bool {
    let matches = self.internalRegexp.matchesInString( input, options: nil, range:NSMakeRange(0, count(input)) )
    return matches.count > 0
}

変更後

optionsの指定方法ぐらいですね。

func isMatch(input: String) -> Bool {
    let nsString = input as NSString
    let matches = self.internalRegexp.matchesInString(input, options:[], range:NSMakeRange(0, nsString.length))
    return matches.count > 0
}

matches

変更前

func matches(input: String) -> [String]? {
    if self.isMatch(input) {
        let matches = self.internalRegexp.matchesInString( input, options: nil, range:NSMakeRange(0, count(input)) )
        var results: [String] = []
        for i in 0 ..< matches.count {
            results.append( (input as NSString).substringWithRange(matches[i].range) )
        }
        return results
    }
    return nil
}

変更後

countの箇所でエラーが起きるので以下のように変更しています。

func matches(input: String) -> [String]? {
    if self.isMatch(input) {
        let nsString = input as NSString
        let matches = self.internalRegexp.matchesInString( input, options: [], range:NSMakeRange(0, nsString.length) )
        var results: [String] = []
        for i in 0 ..< matches.count {
            results.append( (input as NSString).substringWithRange(matches[i].range) )
        }
        return results
    }
    return nil
}

個人的に追加

正規表現で一致した内容を削るものです。

func delMatches(input:String) -> String {
    var strRet:String = ""
    if self.isMatch(input) {
        let matchList = self.matches(input)
        strRet = input
        for var i = 0; i < matchList!.count; i++ {
            strRet = strRet.stringByReplacingOccurrencesOfString(matchList![i], withString: "", options: [], range: nil)
        }
    }
    return strRet
}

使い方

左側に正規表現を記載し、右側に対象の文字列を書きます。

Regexp("(\\d+)").delMatches(self._strTitle)

以上です。

LINEで送るをiOS9でやるには

起動時に出る謎のエラー

iOS9ではSchemeを使った実装方法が変わったらしいです。
XCode7にして、実機はiOS9に変更していろいろと触っていると、起動時によくわからないエラーが出ました。スクリーンショット 2015-09-21 22.43.24.png

先人の方々が言うにはplistでLSApplicationQueriesSchemesを追加するように!とのこと。 これで謎のKindleエラーが消えました。

スクリーンショット 2015-09-21 22.44.12.png

本題のLINEで送る

何も気にせずLINEで送るようのコードをSwiftで書いてたんですが、実際に動かしてみると・・・う、動かない。。。

@IBAction func pushLine(sender: AnyObject) {
    let text: String! = "Message!!"
    let encodeMessage: String! = text.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
    let messageURL: NSURL! = NSURL( string: "line://msg/text/" + encodeMessage )        
    if (UIApplication.sharedApplication().canOpenURL(messageURL)) {
        UIApplication.sharedApplication().openURL( messageURL )
    }
}

Kindleと同じようにlineLSApplicationQueriesSchemesに追加してあげればいいんだな!

スクリーンショット 2015-09-21 22.38.58.png

これでいけましたー!以上ですー。