| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- // ... existing code ...
- // 2. 比较特征相似度并分组
- group.notify(queue: processingQueue) {
- progressHandler("正在比较相似度...", 0.6)
-
- // 近似度
- let similarityThreshold: Float = 0.7
- var similarGroups: [[PHAsset]] = []
-
- // 使用并行处理来加速比较
- let processingGroup = DispatchGroup()
- let processingQueue = DispatchQueue(label: "com.yourapp.similarity.processing", attributes: .concurrent)
- let resultsQueue = DispatchQueue(label: "com.yourapp.similarity.results")
- let semaphore = DispatchSemaphore(value: 8) // 控制并发数量
-
- // 创建一个线程安全的数据结构来存储结果
- var processedIndices = Atomic<Set<Int>>(Set<Int>())
- var groupResults = Atomic<[Int: [PHAsset]]>([:])
-
- // 分批处理,每批处理一部分数据
- let batchSize = min(100, imageFeatures.count)
- let batches = Int(ceil(Float(imageFeatures.count) / Float(batchSize)))
-
- for batchIndex in 0..<batches {
- let startIndex = batchIndex * batchSize
- let endIndex = min(startIndex + batchSize, imageFeatures.count)
-
- for i in startIndex..<endIndex {
- // 检查是否已处理
- if processedIndices.value.contains(i) { continue }
-
- semaphore.wait()
- processingGroup.enter()
-
- processingQueue.async {
- // 再次检查,因为可能在等待期间被其他线程处理
- if processedIndices.value.contains(i) {
- semaphore.signal()
- processingGroup.leave()
- return
- }
-
- var similarAssets: [PHAsset] = [imageFeatures[i].asset]
- processedIndices.mutate { $0.insert(i) }
-
- for j in (i + 1)..<imageFeatures.count {
- // 检查是否已处理
- if processedIndices.value.contains(j) { continue }
-
- do {
- var distance: Float = 0
- try imageFeatures[i].feature.computeDistance(&distance, to: imageFeatures[j].feature)
-
- let similarity = 1 - distance
- if similarity >= similarityThreshold {
- similarAssets.append(imageFeatures[j].asset)
- processedIndices.mutate { $0.insert(j) }
- }
- } catch {
- print("相似度计算失败: \(error)")
- }
- }
-
- // 只保存有多个相似图像的组
- if similarAssets.count > 1 {
- resultsQueue.async {
- groupResults.mutate { $0[i] = similarAssets }
- }
- }
-
- // 更新进度
- let progress = Float(processedIndices.value.count) / Float(imageFeatures.count)
- DispatchQueue.main.async {
- progressHandler("正在比较相似度...", 0.6 + progress * 0.4)
- }
-
- semaphore.signal()
- processingGroup.leave()
- }
- }
- }
-
- processingGroup.wait()
-
- // 整理结果
- similarGroups = Array(groupResults.value.values)
-
- // 按照照片数量降序排序
- similarGroups.sort { $0.count > $1.count }
-
- DispatchQueue.main.async {
- completion(similarGroups)
- }
- }
- // ... existing code ...
|