【问题标题】:Swift UIImage .jpegData() and .pngData() changes image sizeSwift UIImage .jpegData() 和 .pngData() 改变图像大小
【发布时间】:2022-01-16 08:46:15
【问题描述】:

我正在使用 Swift 的 Vision Framework 进行深度学习,并希望使用 REST API 将输入图像上传到后端 - 为此,我使用本机 swift 的 jpegData()pngData() 函数将我的 UIImage 转换为 MultipartFormData优惠。

我使用session.sessionPreset = .vga640x480 在我的应用程序中指定要处理的图像大小。

我在后端看到不同大小的图像 - 我能够在应用程序中确认这一点,因为从图像转换而来的 UIImage(imageData) 大小不同。

这就是我将图像转换为multipartData 的方式-

let multipartData = MultipartFormData()
if let imageData = self.image?.jpegData(compressionQuality: 1.0) {
    multipartData.append(imageData, withName: "image", fileName: "image.jpeg", mimeType: "image/jpeg")
}

这是我在 Xcode 调试器中看到的 -

【问题讨论】:

  • 你知道scale是什么意思吗? :) 您已将点大小转换为像素大小。
  • 您的图像显然是 640×480 点,比例为 2,结果为 1280×960 像素。我们可以将您指向用于调整大小的例程,或者更好地以 1 的比例捕获原始文件。例如,如果使用 UIGraphicsImageRenderer 捕获,则在此处指定比例,然后不需要后续调整大小。
  • 感谢详细的解释!将sessionPreset 用作vga640x480 的最初目的是使原始图像“缩小”到 (640, 480) 的大小,因为我不需要 (1280, 960) 进行处理。如果我的图像是比例为 2 的 640x480 点,我的深度学习模型是否仍需要与比例为 1 的 1280x960 点相同的处理方式?
  • 目前,我从函数中得到pixelBuffer - didOutput sampleBuffer: CMSampleBuffer 通过使用pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) 然后CIImage(cvPixelBuffer: pixelBuffer) 我的视觉模型使用。处理这个问题的更好方法是什么,以便我可以继续使用尺寸(640、480)的图像?非常感谢您的帮助!
  • png 和 jpeg 使用不同的压缩算法,所以你有不同的尺寸。

标签: ios swift uiimage coreml vision


【解决方案1】:

以下内容看起来很直观,但体现了您所描述的行为,即最终以 Data 表示的图像具有不正确的 scale 和像素大小:

let ciImage = CIImage(cvImageBuffer: pixelBuffer) // 640×480
let image = UIImage(ciImage: ciImage)             // says it is 640×480 with scale of 1
guard let data = image.pngData() else { ... }     // but if you extract `Data` and then recreate image from that, the size will be off by a multiple of your device’s scale

但是,如果您通过CGImage 创建它,您将得到正确的结果:

let ciImage = CIImage(cvImageBuffer: pixelBuffer)
let ciContext = CIContext()
guard let cgImage = ciContext.createCGImage(ciImage, from: ciImage.extent) else { return }
let image = UIImage(cgImage: cgImage)

你问:

如果我的图像是比例为 2 的 640×480 点,我的深度学习模型是否仍需要与比例为 1 的 1280×960 点的处理方式相同?

就模型而言,640×480pt @ 2× 与 1280×960pt @ 1× 之间没有区别。

问题是 640×480pt @ 2× 是否比 640×480pt @ 1× 更好:在这种情况下,该模型无疑会产生更好的结果,尽管可能更慢,但图像分辨率更高(虽然在 2× 时,资产大约大四倍/上传速度慢;在 3 倍设备上,大约大九倍)。

但是,如果您查看由直接 CIImage » UIImage 进程生成的较大资产,您会发现它并没有真正捕获 1280×960 的快照,而是捕获了 640×480 并放大(有些平滑),因此您确实没有更详细的资产要处理,并且不太可能产生更好的结果。因此,您将支付较大资产的罚款,但可能没有任何好处。

如果您需要更大图像的更好结果,我会将预设更改为更高的分辨率,但仍然避免使用上面共享的基于CIContext/CGImage 的 sn-p 进行基于 scale 的调整。

【讨论】:

    猜你喜欢
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    相关资源
    最近更新 更多