なすびのブログ

iOS・swiftの情報を気ままに書いていきます。

【swift4.2】swiftでOpenCVを使ってみる

はじめに

どーも、なすびです。
今回はswiftからOpenCVを使って画像をいじれるようにしようかと思います。
調べてみたところswiftから直接は呼び出せないみたいですが、あまり気にしなくても良さげですね。
流れとしてはc++Objective-C++swiftのような形で利用します。
では簡単に説明していきます。
参考サイト:iOS(swift)でOpenCVを使うシンプルなサンプル - Qiita

OpenCVをインストールする

・CocoaPodsを使用してインストール。
CocoaPodsの使い方は別で記事を書いているのでそちらを参照してください。
【Xcode】CocoaPodsのインストール - なすびのブログ
PodfileにOpenCVを追加

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target '[プロジェクト名]' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for [プロジェクト名]
  # ここを追加
  pod 'OpenCV'

  target '[プロジェクト名]Tests' do
    inherit! :search_paths
    # Pods for testing
  end

  target '[プロジェクト名]UITests' do
    inherit! :search_paths
    # Pods for testing
  end

end


ちなみにもちろんCocoaPodsを使わなくても利用できます。 その場合は公式サイトから OpenCV iOS Packをダウンロードして追加してください。 http://opencv.org/releases.html

OpenCVのラッパークラスを作成する

Cocoa Touch Classを選択
f:id:nasubiblog:20181222002530p:plain

Objective-Cを選択
f:id:nasubiblog:20181222002601p:plain

Bridging-Header.hを追加
swiftからObjective-Cコードを使うために必要になります。
f:id:nasubiblog:20181222003059p:plain

・ファイル拡張子を.mから.mmにリネームする
.mObjective-Cのファイル拡張子なのでObjective-C++とするために.mmに変更します。
f:id:nasubiblog:20181222003436p:plain

Bridging-Header.hObjective-Cクラスのヘッダを追加

#import "OpenCV.h"

OpenCV.hにラッパーメソッドを定義

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface OpenCV : NSObject
+(UIImage *)grayScale:(UIImage *)image;
@end

NS_ASSUME_NONNULL_END

OpenCV.mmに処理を実装
下記の例ではグレースケール変換を行なっています。

#import <opencv2/opencv.hpp>
#import <opencv2/imgcodecs/ios.h>
#import "OpenCV.h"

@implementation OpenCV

+(UIImage *)grayScale:(UIImage *)image {
    // UIImageからMatを作成
    cv::Mat mat;
    UIImageToMat(image, mat);
    
    // グレースケール変換
    cv::Mat gray;
    cv::cvtColor(mat, gray, CV_BGR2GRAY);
    
    // MatからUIImageを作成
    UIImage *grayImg = MatToUIImage(gray);
    
    return grayImg;
}

@end

swiftコードから呼び出す

あとはいつものようにswiftでメソッドを呼び出します。

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let image = UIImage(named: "nasubi")!
        imageView.image = OpenCVWrapper.grayScale(image)
    }
}


実行。
f:id:nasubiblog:20181222015439p:plain
おー、簡単にできる。

二値化

グレースケール後に下記処理をすると二値化変換もできます。

cv::Mat binary;
cv::threshold(gray, binary, 128, 255, cv::THRESH_BINARY);

最後に

今回はswiftからOpenCVを使うサンプルについて説明しました。
今回は基本的な実装だけですが、これで色々と画像処理が捗りますね。
次は矩形検出とかしてみよかなー。画像処理の勉強をしたいです。
さて今回はこの辺りで。


今後も画像以外にもswiftに関するブログを書くのでよかったら読者登録お願いします!