WhatFlower (2)
기본 코드 구성.
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
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
let imagePicker = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.allowsEditing = true
}
@IBAction func cameraTapped(_ sender: UIBarButtonItem) {
present(imagePicker, animated: true)
imagePicker.dismiss(animated: true)
}
}
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let userPickedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage
imageView.image = userPickedImage
}
}
SeeFood와 동일한 구조로 기본 코드를 구성한다.
차이점이라면 allowsEditing이 true로 되었고, 그에따라 userPickedImage 역시 editedImage가 되었다는 것.
info.plist file 수정
카메라 접근 권한 허용을 유져에게 물어봐야 하기에 해당부분을 구현한다.
CoreML, Vision 사용하여 기능 구현.
어제 SeeFood와 했던 것 그대로 작성한다.
고고
우선 내 기억과 이해를 바탕으로 먼저 작성해본다.
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
// 나
func detect (image: CIImage) {
var coremlModel = try! VNCoreMLModel(for: FlowerClassifier().model)
var request = VNCoreMLRequest(model: coremlModel) { (request, error) in
print(request)
}
var handler = VNImageRequestHandler(ciImage: image)
do {
try handler.perform([request])
} catch {
print(error)
}
}
// 강의
func detect (image: CIImage) {
guard let coremlModel = try? VNCoreMLModel(for: FlowerClassifier().model) else {
fatalError("Import model failed")
}
let request = VNCoreMLRequest(model: coremlModel) { (request, error) in
print(request)
}
var handler = VNImageRequestHandler(ciImage: image)
do {
try handler.perform([request])
} catch {
print(error)
}
}
// request 수정.
let request = VNCoreMLRequest(model: coremlModel) { (request, error) in
let result = request.results?.first as? VNClassificationObservation
self.navigationItem.title = result?.identifier
}
실행하여 테스트.
102 종류의 꽃을 분류한다고하니 확인해보자.
애플 개발자 계정은 무료일땐 3개가 최대이다. (실제 폰에서 테스트할때)
결과의 첫번째 문자를 대문자로 바꾸기.
현재 결과를 보면 전부 소문자로 나온다.
앞에 대문자를 만들어 주자.
self.navigationItem.title = result?.identifier.capitalized
뒤에 capitalized 만 넣어주면 해결.
특정 Library 설치
Alamofire 와 swiftyJson을 설치한다.
위키피디아 api를 사용.
Docs 참고.
API에 대한 간략한 정보는 여기에.
1
2
3
4
5
6
7
8
9
10
11
12
let wikipediaURl = "https://en.wikipedia.org/w/api.php"
let parameters : [String:String] = [
"format" : "json",
"action" : "query",
"prop" : "extracts",
"exintro" : "",
"explaintext" : "",
"titles" : flowerName,
“indexpageids” : "",
"redirects" : "1",
]
위의 정보를 바탕으로 api 호출 url을 만들어본다.
그럼 다음과 같다
https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=&explaintext=&titles=flowerName&indexpageids=&redirects=1
저기서 flowerName 부분에 label에 있는 꽃의 이름을 입력하면
이렇게 json 정보를 얻을 수 있다
Alamofire(Old version) 사용하여 JSON 가져오기.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func requestInfo(flowerName: String) {
let parameters : [String:String] = [
"format" : "json",
"action" : "query",
"prop" : "extracts",
"exintro" : "",
"explaintext" : "",
"titles" : flowerName,
"indexpageids" : "",
"redirects" : "1",
]
Alamofire.request(wikipediaURl, method: .get, parameters: parameters).responseJSON { (response) in
if response.result.isSuccess {
print("Got")
print(response)
}
}
}
parameters라는 배열을 통해 위에처럼 주소로 다 안적고 심플하게 할 수 있다.
강의상 Alamofire를 구버전으로 설치했기에 그걸로 했다.
특히 어려워할부분은 없다.
특이한건 responseJSON을 사용했다는것.
그러다보니 데이터 타입이 다르다.
기존에 우리가 아는 개념으로 적용했을땐 decoding 하고 어떤 Model이 DataType이었는데, 그런식으로 적용한 코드가 아니다.
기능테스트
화면과 콘솔에 출력되는 결과이다.
swiftyJSON 사용
1
2
3
4
5
let flowerJSON: JSON = JSON(response.result.value!)
let pageid = flowerJSON["query"]["pageids"][0].stringValue
let flowerDescription = flowerJSON["query"]["pages"][pageid]["extract"].stringValue
self.label.text = flowerDescription
SDWebImage 사용하기.
위키에서 제공하는 이미지를 사용하기위해 파라미터를 수정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let parameters : [String:String] = [
"format" : "json",
"action" : "query",
"prop" : "extracts|pageimages", // modified
"exintro" : "",
"explaintext" : "",
"titles" : flowerName,
"indexpageids" : "",
"redirects" : "1",
"pithumbsize" : "500"
]
let flowerImageURL = flowerJSON["query"]["pages"][pageid]["thumbnail"]["source"].stringValue
self.imageView.sd_setImage(with: URL(string: flowerImageURL))
이미지에 주소에 대한 파라미터를 바꾸니 경로가 나온다.
작동 완료.