-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathImageClassificationView.swift
107 lines (93 loc) · 3.52 KB
/
ImageClassificationView.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import SwiftUI
import CoreML
import Vision
struct ImageClassificationView: View {
@State private var image: UIImage?
@State private var classLabel: String = ""
@State private var classLabelProbs: [String: Double] = [:]
@State private var isCameraVisible = false
@State private var isTakingPicture = false
var body: some View {
ZStack {
if isCameraVisible {
CameraPreview(isTakingPicture: $isTakingPicture, image: $image)
}
else {
VStack {
if let image = image {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
.clipShape(RoundedRectangle(cornerRadius: 20))
.padding()
} else {
Button("Take a picture") {
self.isCameraVisible = true
}
.padding()
}
if !classLabel.isEmpty {
Button("Show result") {
self.isCameraVisible = false
}
.padding()
}
}
.onAppear {
self.image = UIImage(named: "example")
if let image = self.image {
self.classifyImage(image)
}
}
}
}
}
func classifyImage(_ image: UIImage) {
guard let model = try? VNCoreMLModel(for: vegetables().model) else {
print("Failed to load Core ML model.")
return
}
let request = VNCoreMLRequest(model: model) { [self] request, error in
guard let results = request.results as? [VNClassificationObservation],
let topResult = results.first else {
print("Failed to classify image: \(error?.localizedDescription ?? "Unknown error")")
return
}
let classLabelProbs = Dictionary(uniqueKeysWithValues: zip(results.map({ $0.identifier }), results.map({ Double($0.confidence) })))
DispatchQueue.main.async {
self.classLabel = topResult.identifier
self.classLabelProbs = classLabelProbs
}
}
guard let ciImage = CIImage(image: image) else {
print("Failed to convert UIImage to CIImage.")
return
}
let handler = VNImageRequestHandler(ciImage: ciImage, options: [:])
do {
try handler.perform([request])
} catch {
print("Failed to perform classification request: \(error.localizedDescription)")
}
}
}
struct ResultView: View {
@Binding var predictions: [String: Double]
var body: some View {
NavigationView {
List {
ForEach(predictions.sorted(by: { $0.value > $1.value }), id: \.key) { prediction in
HStack {
Text(prediction.key)
.font(.headline)
Spacer()
Text("\(prediction.value, specifier: "%.2f")")
.font(.subheadline)
.foregroundColor(prediction.value == predictions.values.max() ? .green : .secondary)
}
}
}
.navigationBarTitle("Predictions")
}
}
}