func analyzeImage(image: UIImage) -> String {
guard let modelPath = model.modelPath else {
return "모델 파일을 찾을 수 없습니다."
}
// 1. interpreter 생성
do {
let interpreter = try Interpreter(modelPath: modelPath)
try interpreter.allocateTensors()
guard let rgbData = preprocessImage(image, width: inputWidth, height: inputHeight) else {
return "이미지 전처리 실패"
}
// 2. inputData 전달
try interpreter.copy(rgbData, toInputAt: 0) // 데이터를 interpreter에 전달(복사)
try interpreter.invoke() // interpreter 실행
// 3. outputData 가져오기
let output = try interpreter.output(at: 0) // 추론 결과 가져오기
let results = output.data.toArray(type: UInt8.self) // 추론 결과를 Int8 배열로 변환 - '해당 식물일 확률'의 배열
// 4. output 데이터 가공
if let max = results.max(),
let maxIndex = results.firstIndex(of: max) {
let confidence = Int((Float(max) / 255.0) * 100)
let grade = Confidence.from(value: max)
let plantName = "\(maxIndex)"
return "\(grade.rawValue): \(confidence)% 확률로 \(plantName)입니다."
}
} catch {
// 에러 처리
}
return ""
}
모델이 요구하는 사양에 맞추어 inputData를 가공해야함
-> 이미지 분석 모델이므로 이미지 데이터를 가공
1) input으로 요구하는 이미지 크기에 맞게 분석 대상 이미지 자르기
2) 리사이징한 이미지에서 비트맵 데이터 추출
: RGB값 (0~255)이 담긴 배열 데이터를 만들어냄
: CGContext를 활용하여 224x224 크기의 RGB 값을 담을 빈 메모리 공간 생성
-> context.draw 메서드를 통해 리사이징한 이미지의 RGB값을 context에 채워넣음
💡 CGContext를 사용하는 이유
UIImage는 많은 정보를 담고 있어서 RGB 데이터만 가져올 수 없음
-> CGContext를 활용하여 RGB값만을 추출
3) context.data를 1바이트씩 끊어서 R, G, B 값으로 담아낸 inputData 생성
4) inputData를 반환
AI 모델이 요구하는 input과 output 데이터 타입을 잘 봐야 제대로된 결과를 얻을 수 있음!