You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift计算两个UIImage相似度百分比及unrecognized selector报错处理

iOS UIImage相似度计算问题解决方案

1. 解决convertoand:]: unrecognized selector sent to instance报错

这个报错核心原因是按钮点击事件绑定了不存在的方法,按以下步骤修复:

  • 打开项目对应页面的Storyboard/XIB文件,右键点击触发计算的按钮
  • 在弹出的绑定菜单中找到Touch Up Inside事件,删除名为convertoand的旧绑定
  • 确认当前按钮仅绑定了btnFindSimilarity方法,重新运行即可

2. 差异度转相似度实现

你当前的compareImages方法返回的是0-100区间的差异百分比,数值越低代表两张图越相似,转相似度只需用100减去差异值即可,修改后的代码如下:

func compareImages(image1: UIImage, image2: UIImage) -> Double? {
    // 先校验两张图尺寸完全一致
    guard let cgImg1 = image1.cgImage,
          let cgImg2 = image2.cgImage,
          cgImg1.width == cgImg2.width,
          cgImg1.height == cgImg2.height else {
        return nil
    }
    guard let data1 = pixelValues(fromCGImage: cgImg1),
          let data2 = pixelValues(fromCGImage: cgImg2),
          data1.count == data2.count else {
        return nil
    }
     
    let pixelCount = Double(cgImg1.width * cgImg1.height)
    // 计算差异度
    let diff = zip(data1, data2)
        .enumerated()
        .reduce(0.0) {
            // 跳过alpha通道不参与计算
            guard $1.offset % 4 != 3 else { return $0 }
            return $0 + abs(Double($1.element.0) - Double($1.element.1))
        }
    let diffPercent = diff * 100 / (pixelCount * 3 * 255)
    // 差异转相似度:完全一致返回100,完全不同返回0
    return 100 - diffPercent
}

同步修改按钮点击逻辑,处理异常情况:

@IBAction func btnFindSimilarity(_ sender: Any) {
    let imgRect = CGRect(x: 0, y: 0, width: 400, height: 100)
    let imageStroke = canvasView.drawing.image(from: imgRect, scale: 1.0)
    guard let baseImage = imageOnApp,
          baseImage.size.equalTo(imageStroke.size) else {
        lblPrintScore.text = "图片尺寸不匹配"
        return
    }
    guard let similarity = compareImages(image1: imageStroke, image2: baseImage) else {
        lblPrintScore.text = "对比失败"
        return
    }
    lblPrintScore.text = String(format: "相似度:%.2f%%", similarity)
}

3. 可选优化点

如果出现图片对比经常返回nil的情况,是因为不同来源的图片像素格式不一致导致CGContext创建失败,可以修改pixelValues方法的CGContext初始化参数,固定使用通用RGBA格式,不要复用原图的bitmapInfo:

// 替换原有context初始化代码
let contextRef = CGContext(data: &intensities,
                          width: width,
                         height: height,
               bitsPerComponent: 8,
                    bytesPerRow: width * 4,
                          space: CGColorSpaceCreateDeviceRGB(),
                     bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)

内容的提问来源于stack exchange,提问作者NOR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:09:00