Sponsor Link
環境&対象
- macOS Ventura 13.2 Beta
- Xcode 14.2
- iOS 16.0
OpenCV
一言でいうと、画像処理のライブラリです。
OpenCV の詳細は、こちらで確認してください。
プロジェクト設定
Google してみると、ローカルにコンパイルする方法が多く解説されています。
が、簡単に使用開始できる Swift Package を使っていきます。
GitHub のページは、こちら
プロジェクト作成
普通に(?)、プロジェクトを作成します。iOS だけでなく macOS にも対応しているので、MultiPlatform プロジェクトで作成しても問題ありません。
macOS では、Accelerate.framework と OpenCL.framework も追加することが必要です。
SwiftPackage を追加
先ほどの URL を使って、Siwft Package を登録します。
2023.1.15 時点では、最新版の 4.7.0 は、取得できません。
1つ前のバージョン 4.6.0 を Exact Version として設定するとうまく取得できます。
詳細は、こちらを見てください。
プロジェクトへの設定追加
Swift Package を追加した後に、以下の設定が必要となります。
ライブラリ追加
[Project]-[Target]-[General] で “Frameworks, Libraries, and EMbedded Content” に libc++.tbd を追加します。リンカー設定
[Project]-[Target]-[Build Settings] で Linking / Other Linker Flags に “-all_load” を追加します。これで、設定は完了です。
macOS/iOS の相違点
AppKit/UIKit では、画像データとして、NSImage/UIImage とそれぞれ別々のクラスが用意されています。
つまり、Multiplatform App として作ろうとしても、NSImage と UIImage が別々のクラスであることが理由で、異なるコードを作る必要が発生してしまいます。
例えば、以下のように宣言しておくと、NSUIImage というクラスで処理するようにコードを書くことで、実際の macOS/iOS で それぞれ NSImage/UIImage が使われるコードにすることができます。
#if os(iOS)
typealias NSUIImage = UIImage
#else
typealias NSUIImage = NSImage
#endif
実際には、上記の typealias 以外にも、メソッドの細かい引数の違い等を吸収する必要があります。
以降では、自作した NSUIBridge ライブラリを使って、実装していきます。
Github の URL は、こちら
OpenCVの初めの一歩
画像処理のコードを少し書いてみます。
Swift 版の OpenCV では、Imgproc というクラスのクラスメソッドに、OpenCV の多くのメソッドが定義されています。
また、OpenCV では、Mat と呼ばれる構造でデータを扱うようで、多くのメソッドの引数に、Mat を受け取ります。
例えば、カラー画像をグレースケール化するときに使用するときには、以下のようなコードになります。
// (1)
let image: NSUIImage = NSUIImage(named: "cat")!
// (2)
let srcMat = Mat(nsuiImage: image)
// (3)
let dstMat = Mat()
// (4)
Imgproc.cvtColor(src: srcMat, dst: dstMat, code: ColorConversionCodes.COLOR_BGR2GRAY)
// (5)
let result = dstMat.toNSUIImage()
- (Assets に登録している) cat というデータ を読み込んで、UIImage/NSImage として用意します
- UIImage/NSImage から、Mat データを作成します
- 変換先の Mat データを用意します
- Imgproc のクラスメソッドとして定義されている色変換メソッドをコールします
- 処理後の Mat から、UIImage/NSImage を取得します
chaining method っぽくしてみる
上記のように、書いても問題ないのですが、SwiftUI 等で慣れてきているので、chaining method っぽく書けるようにしてみます。
以下のような extension を Mat に定義します。
extension Mat {
func cvtColor(code: ColorConversionCodes) -> Mat {
let dstMat = Mat()
Imgproc.cvtColor(src: self, dst: dstMat, code: code)
return dstMat
}
}
上記のようにすると、先ほどのコードは、以下のようにかけることになります。
image = srcMat.cvtColor(code: .COLOR_BGR2GRAY).toNSUIImage()
最初のデータを cvtColor して、イメージを取得しているということが読みやすくなっている気がします。
SwiftUI
SwiftUI との組み合わせでの例を説明します。
View の中で、openCV のロジックを記述していくのは気が引けるので、ViewModel 内に書くことにします。
class ViewModel: ObservableObject {
@Published var image: NSUIImage = NSUIImage(named: "cat")!
func applyOpenCV() {
let srcMat = Mat(nsuiImage: image)
image = srcMat.cvtColor(code: .COLOR_BGR2GRAY)
.toNSUIImage()
return
}
func reload() {
image = NSUIImage(named: "cat")!
}
}
@Publish 指定した image を 持ち、applyOpenCV メソッドが呼ばれると 先ほどの cvtColor 処理したイメージを image に設定するメソッドを追加しています。
テスト用に、image に初期イメージを再設定するメソッドも追加してます。
openCV を使っているので、”import opencv2″ を書き忘れないでください。
struct ContentView: View {
@StateObject var viewModel = ViewModel()
var body: some View {
VStack {
Image(nsuiImage: viewModel.image)
.resizable().scaledToFit()
Button(action: {
viewModel.applyOpenCV()
}, label: {
Text("ApplyOpenCV")
})
Button(action: {
viewModel.reload()
}, label: {
Text("Reload")
})
}
.padding()
}
}
View の方は、Image を使って、処理前/処理後のデータを表示しています。
さらに、openCV の処理開始用のボタン、初期イメージを再設定するボタンを配置しています。
以下のようなアプリになり、openCV の処理が適用されていることを確認できます。
まとめ
OpenCV を使用するアプリの作り方
- Swift Package 化されている OpenCV を使うと簡単
- Libraries 設定で libc++.tbd の追加が必要
- BuildSettings/Linking 設定で、-all_load の追加が必要
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
SwiftUI おすすめ本
SwiftUI を理解するには、以下の本がおすすめです。
SwiftUI ViewMatery
SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。
英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。
View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。
超便利です
販売元のページは、こちらです。
SwiftUI 徹底入門
# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。
Swift学習におすすめの本
詳解Swift
Swift の学習には、詳解 Swift という書籍が、おすすめです。
著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。
Sponsor Link