참고 블로그 : https://ios-daniel-yang.tistory.com/29
참고 사항 : https://developer.apple.com/kr/machine-learning/models/#text
- 위 블로그에서 사용한 Flower MLModel 을 사용하지 않고, 위 참고 사항 링크(=애플 공식 제공 MLModel) 을 사용하였습니다.
var imagePicker: UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .camera // 기본값은 카메라 라이브러리, 이미지를 찍을 수 있게 설정
picker.allowsEditing = true // 선택한 이미지나 동영상 편집 여부를 설정(Bool)
return picker
}
CoreML 의 이미지를 읽기 위해서는 꼭 CIImage(Core Image) 타입으로 변환해야 합니다.
훈련된 모델을 요청(Request) 한 후 handler 로 처리해서 분석을 합니다.
사용 예시
// CoreML의 CIImage를 처리하고 해석하기 위한 메서드 생성, 이것은 모델의 이미지를 분류하기 위해 사용 됩니다.
func detect(image: CIImage) {
// CoreML의 모델인 FlowerClassifier를 객체를 생성 후,
// Vision 프레임워크인 VNCoreMLModel 컨터이너를 사용하여 CoreML의 model에 접근합니다.
guard let coreMLModel = try? MobileNetV2(configuration: MLModelConfiguration()),
let visionModel = try? VNCoreMLModel(for: coreMLModel.model) else {
fatalError("Loading CoreML Model Failed")
}
// Vision을 이용해 이미치 처리를 요청
let request = VNCoreMLRequest(model: visionModel) { request, error in
guard error == nil else {
fatalError("Failed Request")
}
// 식별자의 이름(꽃 이름)을 확인하기 위해 VNClassificationObservation로 변환해줍니다.
guard let classification = request.results as? [VNClassificationObservation] else {
fatalError("Faild convert VNClassificationObservation")
}
// 머신러닝을 통한 결과값 프린트
print(classification)
}
// 이미지를 받아와서 perform을 요청하여 분석합니다. (Vision 프레임워크)
let handler = VNImageRequestHandler(ciImage: image)
do {
try handler.perform([request])
} catch {
print(error)
}
}
위에서 만들어준 메서드로 CIImage 를 분석을 합니다.
사용 예시
// 사진을 찍은 후 이미지를 갖고 할 일들을 정의
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true)
// info의 키 값으로 수정한 사진 이미지 받아옵니다.
guard let userPickedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage else {
fatalError("Failed Original Image pick")
}
// 위에서 받은 이미지를 이미지 뷰에 저장
imageView.image = userPickedImage
// Core모델 이미지로 사용하기 위해 CIImage로 변환
guard let coreImage = CIImage(image: userPickedImage) else {
fatalError("Faild convert CIImage")
}
// 변환 된 CIImage를 갖고 이미지를 처리하는 메서드 호출
detect(image: coreImage)
}
Print 값 대신 VNClassificationObservation 배열의 첫 번째 타이틀을 identifier 로 설정해 줍니다.
사용 예시
// 👉 타이틀을 가장 정확도 높은 이름으로 설정
if let fitstItem = classification.first {
self.navigationItem.title = fitstItem.identifier.capitalized
}
import CoreML
import UIKit
import Vision // CoreML 과 작업을 할 때 이미지를 보다 쉽게 처리할 수 있게 도와주는 프레임워크
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
var imagePicker: UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = self
picker.sourceType = .camera // 기본값은 카메라 라이브러리, 이미지를 찍을 수 있게 설정
picker.allowsEditing = true // 선택한 이미지나 동영상 편집 여부를 설정(Bool
return picker
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func cameraTapped(_ sender: UIBarButtonItem) {
// UIImagePickerController 도 ViewController 이므로 present로 불러와야 한다.
present(imagePicker, animated: true)
}
}
// MARK: - CoreML 이미지 분류
extension ViewController {
// CoreML 의 CIImage를 처리하고 해석하기 위한 메서드 생성, 이것은 모델의 이미지를 분류하기 위해 사용 됩니다.
func detectImage(image: CIImage) {
// CoreML의 모델인 FlowerClassifier를 객체를 생성 후,
// Vision 프레임워크인 VNCoreMLModel 컨테이너를 사용하여 CoreML의 model에 접근한다.
guard let coreMLModel = try? MobileNetV2(configuration: MLModelConfiguration()),
let visionModel = try? VNCoreMLModel(for: coreMLModel.model)
else {
fatalError("Loading CoreML Model Failed")
}
// Vision 을 이용해 이미지 처리를 요청
let request = VNCoreMLRequest(model: visionModel) { request, error in
guard error == nil else {
fatalError("Failed Request")
}
// 식별자의 이름(꽃 이름)을 확인하기 위해 VNClassificationObservation 로 변환해준다.
guard let classification = request.results as? [VNClassificationObservation] else {
fatalError("Failed convert VNClassificationObservation")
}
// 타이틀을 가장 정확도 높은 이름으로 설정
if let firstItem = classification.first {
self.navigationItem.title = firstItem.identifier.capitalized
}
// 머신러닝을 통한 결과값 프린트
print("#### \(classification)")
}
// 이미지를 받아와서 perform을 요청하여 분석한다. (Vision 프레임워크)
let handler = VNImageRequestHandler(ciImage: image)
do {
try handler.perform([request])
} catch {
print(error)
}
}
}
// MARK: - UIImagePickerControllerDelegate & UINavigationControllerDelegate
extension ViewController: UIImagePickerControllerDelegate & UINavigationControllerDelegate {
// 사진을 찍은 후 이미지를 갖고 할 일들을 정의
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
picker.dismiss(animated: true)
// info의 키 값으로 수정한 사진 이미지 받아온다.
guard let userPickedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage else {
fatalError("Failed Original Image pick")
}
// 위에서 받은 이미지를 이미지 뷰에 저장
imageView.image = userPickedImage
// Core모델 이미지로 사용하기 위해 CIImage로 변환
guard let coreImage = CIImage(image: userPickedImage) else {
fatalError("Faild convert CIImage")
}
// 변환 된 CIImage를 갖고 이미지를 처리하는 메서드 호출
detectImage(image: coreImage)
}
}