안녕하세요
이번에는 2개의 사진을 두고 이 사진들이 서로 얼마나 비슷한지 보여주는 기능을 구현해볼거에요
Vision을 검색하면
VisionKit도 보일텐데요
처음에 보면 헷갈릴만한 프레임워크들이네요
Vision
컴퓨터 비전 알고리즘을 적용하여 입력 이미지와 동영상에 다양한 작업을 수행합니다.
VisionKit
디바이스의 카메라를 사용하여 환경 또는 앱이 표시하는 이미지에서 정보를 식별하고 추출합니다.
라고 정의되있네요
이미지를 분석해주는게 Vision, 카메라를 써서 스캐너같이 사용하는것이 VisionKit 정도로 간단히 이해하고 넘어가봅시다!
저희가 사용할건 Vision 프레임워크입니다!
Core ML을 사용하여 이미지를 분석해주고 그 특성들을 비교해서 얼마나 비슷한지 측정 할 수 있어요
다양한 요청들이 있는데 이미지 비교를 위해 저희는 맨아래에 있는 타입을 사용해요
VNGenerateImageFeaturePrintRequest
이미지에서 feature print를 생성하기 위한 이미지 기반 요청
이 요청은 생성한 feature print 데이터를 VNFeaturePrintObservation 오브젝트 배열로 반환
feature print란 특징 추출입니다
이미지에서 특징을 추출해서 벡터로 나타냅니다
이 특정한 벡터값을 이용해서 두 이미지의 벡터사이의 거리를 계산하여 이미지간 유사성을 판단합니다
애플의 Vision 알고리즘은 크게 2가지가 있는데
사람의 주의력(attension base)과 객체성(objectness base)을 기반으로 주목도를 통해 계산된다고합니다
코드를 한번 볼까요
아 그전에 Vision을 이용한 앱은 시뮬레이터에서 돌아가지않습니다! 시뮬내에 실행 할 수 있는 ML이 없어서라고 하네요
실기기로 테스트 하셔야합니다!
private func featurePrint(image: UIImage?, isLegacy: Bool) -> VNFeaturePrintObservation? {
let request = VNGenerateImageFeaturePrintRequest()
request.revision = isLegacy ? VNGenerateImageFeaturePrintRequestRevision1 : VNGenerateImageFeaturePrintRequestRevision2
guard let cgImage = image?.cgImage else {
print("error cgImage")
return nil
}
let handler = VNImageRequestHandler(cgImage: cgImage)
do {
try handler.perform([request])
let result = request.results?.first
return result
} catch {
print(error)
}
return nil
}
request를 상황에맞는 타입으로 생성하고
revision을 지정할 수 있어요
revision
알고리즘 버전을 표시하는 상수값이에요
글작성 시점엔 iOS13+, iOS17+을 기준으로 버전이 1,2로 나뉘어져있어요
개선된게 최신버전이니까 당연히 최신꺼를 쓰는게 좋아요
버전마다 거리값이 다르니 많이 테스트해서 임계치를 정해서 거리 기준값을 정하면 좋습니다
Revision1 (iOS13+)
iOS16에서 특징 인쇄는 2048개의 값을 갖는 정규화되지 않은 플로트 벡터입니다.
일반적인 거리 값의 범위는 0.0에서 40.0 사이입니다.
Revision2 (iOS17+)
iOS17에서 특징 인쇄는 길이 768의 정규화된 실수 벡터입니다.
거리 값의 범위는 0.0에서 2.0 사이입니다
cgImage혹은 ciImage를 이용해야해요
앨범으로부터 UIImage를 받아서 후처리를 해주고 Handler 인스턴스를 생성해줬습니다
VNImageRequestHandler
단일 이미지와 관련된 하나 이상의 이미지 분석 요청을 처리하는 개체
이 핸들러를 인스턴스화 해서 단일 이미지에 대한 Vision Request를 수행합니다
perform() 을 호출하여 요청을 실행 할 수 있습니다
VNFeaturePrintObservation
위에서 handler.perform()을 통해 request를 실행하고
인식된 feature print을 제공하는 타입입니다.
이 타입을 이용해서 두 이미지의 feature print간 computeDistance를 이용해서 거리를 비교 할 수 있습니다.
func compare(isLegacy: Bool) {
guard let firstImage = featurePrint(image: image1, isLegacy: isLegacy),
let secondImage = featurePrint(image: image2, isLegacy: isLegacy) else {
return
}
var distance = Float(0)
do {
try firstImage.computeDistance(&distance, to: secondImage)
} catch let error {
print("Image comparison error.")
print(error.localizedDescription)
}
}
테스트를 해볼까요!
앨범에서 2개의 이미지를 불러와서 비교를 돌렸어요
결과는 아래와 같아요
같은사진은 0이 뜨는걸 볼 수 있고 전혀 달라질 수록 수치차이가 커지는걸 볼 수 있습니다
보통 기준을
버전2인 경우 0.5 아래
버전1인 경우 11 아래로 잡는다고하네요
하지만 이 경우에도 확실하진않으니 많은 테스트를 통해서 수치를 잡으면 좋습니다!
'iyOmSd > Title: Swift' 카테고리의 다른 글
[Swift] Xcode16 빌드시 CUICatalog initWithName:fromBundle:error: 런타임 에러 (0) | 2024.11.07 |
---|---|
[Swift] Python을 이용한 Excel -> Json 맵핑 스크립트 만들기 (1) | 2024.09.29 |
[Swift] EventKit Reminder 미리알림 데이터 이용하기 (0) | 2024.07.26 |
[Swift] iMessage 필터링 ILMessageFilterExtension (스팸 차단) (1) | 2024.02.27 |
[Swift] TimeZone과 Locale (1) | 2024.01.30 |