Danny의 iOS 컨닝페이퍼
article thumbnail

CoreML의 특징

이전 글 [iOS/Swift] CoreML (1) - Create ML으로 Model 만들기 에서도 이미 정리를 했지만 대략적으로 핵심만 알아봅시다.

  • 사전에 훈련된 모델로 로드됩니다. (Static Model)
  • 네트워크 연결 없이도 사용이 가능합니다.
  • 보안 측면에서 개인 데이터를 네트워크를 통해 전송할 필요가 없으므로 상대적으로 안전합니다.
  • 수요가 증가해도 서버부하와 직접적인 관련이 없어 확장성이 좋습니다.
  • Apple 기기와의 빠른 호환성이 좋습니다.

 

사용 방법

오늘 만들어 볼 것은 이전 글 의 훈련된 이미지 모델(꽃 이름)을 갖고 CoreML 및 Vision 사용법을 알아보겠습니다.

간단히 소개하면 카메라를 통하여 훈련된 모델(꽃 이름)을 유추하는 앱을 만들어 보겠습니다.

 

1. CoreML을 다루기 위해 프레임워크인 CoreML 및 Visionimport를 해줍시다.

import CoreML
import Vision  // CoreML과 작업을 할 때 이미지를 보다 쉽게 처리할 수 있게 도와주는 프레임워크

 

2. 카메라를 사용해야 하므로 UIImagePicker를 통하여 이미지를 사용할 수 있게 만듭시다.

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()
    }
    
    @IBAction func cameraTapped(_ sender: UIBarButtonItem) {
        // UIImagePickerController도 ViewController 이므로 present로 불러와야 한다.
        present(imagePicker, animated: true)
    }
}

 

3. CoreMLVision으로 이미지를 처리하기 위해서 detect(image: CIImage)란 함수를 만들어 봅시다.

  • CoreML의 이미지를 읽기 위해서는 꼭 CIImage(Core Image)로 타입으로 변환을 해서 사용해야 합니다.
  • 훈련된 모델을 요청(request) 한 후 handeler로 처리해서 분석을 합니다.
// MARK: - CoreML 이미지 분류
extension ViewController {
    // CoreML의 CIImage를 처리하고 해석하기 위한 메서드 생성, 이것은 모델의 이미지를 분류하기 위해 사용 됩니다.
    func detect(image: CIImage) {
        // CoreML의 모델인 FlowerClassifier를 객체를 생성 후,
        // Vision 프레임워크인 VNCoreMLModel 컨터이너를 사용하여 CoreML의 model에 접근한다.
        guard let coreMLModel = try? FlowerClassifier(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)
        }
    }
}

 

4. UIImagePickerControllerDelegate를 통해 훈련된 모델과 이미지랑 비교를 합니다.

  • 위에서 만들어둔 메서드로 CIImage를 분석을 한다.
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를 갖고 이미지를 처리하는 메서드 호출
        detect(image: coreImage)
    }
}

여기까지 과정을 마치고 사진을 찍어서 확인해 보면 데이터들이 정신없이 만들어져 있는 걸 볼 수 있습니다.

 

우리는 여기서 VNClassificationObservation정확도(confidence)이름(identifier)만 유심히 보면 됩니다.

여기를 보시면

  • confidence = 0.9945, identifier = "무궁화"
  • confidence = 0.0035, identifier = "나팔꽃"...

백분율로 나타낸다면 "무궁화" 99.45% , "나팔꽃" 0.3% 이런 순으로 학습된 데이터들이 이미지와 비교하여 값이 나오게 됩니다.

 

우리는 사진과 가장 정확한 꽃의 이름만 알고 싶으니,

VNClassificationObservation 배열에서 정확도가 가장 높은 값, 즉 첫 번째 값만 알면 됩니다.

 

타이틀 값을 변경해 주기 위해서, CoreML 이미지 처리를 해준 3번으로 메서드로 돌아가봅시다.

print 값 대신에 VNClassificationObservation 배열의 첫 번째로 접근해서 타이틀identifier로 설정해 줍시다.

// MARK: - CoreML 이미지 분류
extension ViewController {
    
    func detect(image: CIImage) {
        guard let coreMLModel = try? FlowerClassifier(configuration: MLModelConfiguration()),
              let visionModel = try? VNCoreMLModel(for: coreMLModel.model) else {
            fatalError("Loading CoreML Model Failed")
        }
        let request = VNCoreMLRequest(model: visionModel) { request, error in
            guard error == nil else {
                fatalError("Failed Request")
            }
            guard let classification = request.results as? [VNClassificationObservation] else {
                fatalError("Faild convert VNClassificationObservation")
            }
            
            // 👉 타이틀을 가장 정확도 높은 이름으로 설정
            if let fitstItem = classification.first {
                self.navigationItem.title = fitstItem.identifier.capitalized
            }
        }
        
        let handler = VNImageRequestHandler(ciImage: image)
        do {
            try handler.perform([request])
        } catch {
            print(error)
        }
    }
}

 

자! 테스트를 해봅시다.

무궁화, 히야신스, 연꽃

테스트 결과

모델을 만들 때 학습 이미지의 개수를 15개씩 밖에 넣지 않았는데도 생각보다 높은 정확도를 갖고 있었습니다.

다만 범위를 너무 넓게 찍거나 꽃이 여러 개 있을 땐 정확도가 떨어지네요.

 

이상 CoreML로 이미지 다루기였습니다. 전체 코드는 여기 서 확인하세요

 

 

참고

 

Classifying Images with Vision and Core ML | Apple Developer Documentation

Crop and scale photos using the Vision framework and classify them with a Core ML model.

developer.apple.com

 

Training a Create ML Model to Classify Flowers | Apple Developer Documentation

Train a flower classifier using Create ML in Swift Playgrounds, and apply the resulting model to real-time image classification using Vision.

developer.apple.com

 

iOS & Swift - The Complete iOS App Development Bootcamp

From Beginner to iOS App Developer with Just One Course! Fully Updated with a Comprehensive Module Dedicated to SwiftUI!

www.udemy.com

 

반응형
profile

Danny의 iOS 컨닝페이퍼

@Danny's iOS

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!