构建图像生成应用与电影推荐系统
立即解锁
发布时间: 2025-08-30 00:33:53 阅读量: 5 订阅数: 13 AIGC 

# 构建图像生成应用与电影推荐系统
## 1. 构建图像生成应用
### 1.1 应用概述
我们要构建一个应用,该应用使用 10 个 GAN 模型来请求生成 0 到 9 的数字图像,每个模型生成一个数字。
### 1.2 操作步骤
1. **启动 Xcode**:打开 Xcode 开发环境。
2. **创建新项目**:选择 Single View App 模板创建一个新的 iOS 应用项目。
3. **添加模型**:将之前创建的 10 个 GAN 模型拖入项目中,将 0 模型重命名为 MnistGan,其余保持不变。
4. **设计 UI**:打开 Main.storyboard 文件,创建包含以下组件的 UI:
- 10 个 UIImageView,每行封装在一个单独的 UIView 中。
- 一个 UINavigationBar,带有 UINavigationItem 用于显示应用标题。
- 一个 UIButton 用于触发图像生成。
5. **添加约束**:确保为 UI 元素添加适当的约束。
6. **连接 UI 出口**:在代码中连接 UI 对象的出口,代码如下:
```swift
@IBOutlet weak var generateButton: UIButton!
@IBOutlet weak var imageViewOne: UIImageView!
@IBOutlet weak var imageViewTwo: UIImageView!
@IBOutlet weak var imageViewThree: UIImageView!
@IBOutlet weak var imageViewFour: UIImageView!
@IBOutlet weak var imageViewFive: UIImageView!
@IBOutlet weak var imageViewSix: UIImageView!
@IBOutlet weak var imageViewSeven: UIImageView!
@IBOutlet weak var imageViewEight: UIImageView!
@IBOutlet weak var imageViewNine: UIImageView!
@IBOutlet weak var imageViewZero: UIImageView!
```
7. **连接按钮动作**:为 UIButton 连接动作,代码如下:
```swift
@IBAction func generateButtonPressed(_ sender: Any) {
generateNewImages()
}
```
8. **添加变量**:添加存储 UIImageView 和 GAN 模型的数组,代码如下:
```swift
private var imageViews: [UIImageView] = []
private var ganModels: [ImageGenerator] = [
MnistGan(modelName: "MnistGan"),
MnistGan(modelName: "MnistGan1"),
MnistGan(modelName: "MnistGan2"),
MnistGan(modelName: "MnistGan3"),
MnistGan(modelName: "MnistGan4"),
MnistGan(modelName: "MnistGan5"),
MnistGan(modelName: "MnistGan6"),
MnistGan(modelName: "MnistGan7"),
MnistGan(modelName: "MnistGan8"),
MnistGan(modelName: "MnistGan9"),
]
```
9. **重写 viewDidLoad() 函数**:将 UIImageView 的 IBOutlets 映射到图像视图数组,并生成新图像,代码如下:
```swift
override func viewDidLoad() {
super.viewDidLoad()
self.imageViews = [
imageViewZero, imageViewOne, imageViewTwo, imageViewThree,
imageViewFour, imageViewFive, imageViewSix, imageViewSeven,
imageViewEight, imageViewNine,
]
generateNewImages()
}
```
10. **生成图像函数**:遍历模型数组,请求每个模型生成图像,并将生成的图像设置到相应的 UIImageView 中,代码如下:
```swift
private func generateNewImages() {
for index in 0..<10 {
let ganModel = ganModels[index]
DispatchQueue.main.async {
let generatedImage = ganModel.prediction()
self.imageViews[index].image = generatedImage
}
}
}
```
### 1.3 创建 Models.swift 文件
在项目中创建一个名为 Models.swift 的文件,执行以下操作:
1. **导入必要的库**:
```swift
import CoreML
import UIKit
```
2. **定义 ImageGenerator 协议**:
```swift
public protocol ImageGenerator {
func prediction() -> UIImage?
}
```
3. **扩展 MnistGan 类**:使其遵循 ImageGenerator 协议,并实现 prediction() 函数,代码如下:
```swift
extension MnistGan : ImageGenerator {
// Initialise the MnistGan class using the name of a compiled model
convenience init(modelName: String) {
let bundle = Bundle(for: MnistGan.self)
let url = bundle.url(
forResource: modelName, withExtension:"mlmodelc")!
try! self.init(contentsOf: url)
}
// Generate an image, using an array of random noise; the number
// displayed in the image will depend upon which model was loaded
func prediction() -> UIImage? {
if let noiseArray = MLMultiArray.getRandomNoise(),
let output = try? self.prediction(
input: MnistGanInput(input1: noiseArray)) {
return UIImage(data: output.output1)
}
return nil
}
}
```
### 1.4 创建 Utils.swift 文件
在项目中创建一个名为 Utils.swift 的文件,执行以下操作:
1. **导入必要的库**:
```swift
import UIKit
import CoreML
import Foundation
```
2. **扩展 MLMultiArray**:添加获取随机噪声的函数,代码如下:
```swift
extension MLMultiArray {
static func getRandomNoise(length: NSNumber = 100) -> MLMultiArray? {
guard let input = try? MLMultiArray(
shape: [length], dataType: .double) else {
return nil
}
for index in 0..<Int(truncating: length) {
input[index] = NSNumber(value: Double.random(in: -1.0...1.0))
}
return input
}
}
```
3. **扩展 UInt8**:添加从 8 位无符号整数获取字节数组的函数,代码如下:
```swift
extension UInt8 {
static func makeByteArray<T>(from value: T) -> [UInt8] {
var value = value
return withUnsafeBytes(of: &value) { Array($0) }
}
}
```
4. **扩展 UIImage**:添加两个便利初始化器,用于从 MLMultiArray 和字节数组初始化 UIImage,代码如下:
```swift
extension UIImage {
convenience init?(data: MLMultiArray) {
assert(data.shape.count == 3)
assert(data.shape[0] == 1)
let height = data.shape[1].intValue
let width = data.shape[2].intValue
var byteData: [UInt8] = []
for xIndex in 0..<width {
for yIndex in 0..<height {
let pixelValue =
Float32(truncating: data[xIndex * height + yIndex])
let byteOut: UInt8 = UInt8((pixelValue * 127.5) + 127.5)
byteData.append(byteOut)
}
}
self.init(
data: byteData,
width: width,
height: height,
components: 1
)
}
convenience init?(
data: [UInt8],
width: Int,
height: Int,
components: Int) {
let dataSize = (width * height * components * 8)
guard let cfData = CFDataCreate(nil, data, dataSize / 8),
let provider = CGDataProvider(data: cfData),
let cgImage = CGImage.makeFrom(
dataProvider: provider,
width: width,
height: height,
components: components) else {
return nil
}
self.init(cgImage: cgImage)
}
}
```
5. **扩展 CGImage**:添加从 CGDataProvider 和宽度、高度参数返回 CGImage 的函数,代码如下:
```swift
extension CGImage {
static func makeFrom(dataProvider: CGDataProvider,
width: Int,
height: Int,
components: Int) -> CGImage? {
if components != 1 && components != 3 { return nil }
let bitMapInfo: CGBitmapInfo = .byteOrder16Little
let bitsPerComponent = 8
let colorSpace: CGColorSpace = (components == 1) ?
CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB()
return CGImage(
width: width,
height: height,
bitsPerComponent: bitsPerComponent,
bitsPerPixel: bitsPerComponent * components,
bytesPerRow: ((bitsPerComponent * components) / 8) * width,
space: colorSpace,
bitmapInfo: bitMapInfo,
provider: dataProvider ,
decode: nil,
shouldInterpolate: false,
intent: CGColorRenderingIntent.defaultIntent)
}
}
```
### 1.5 总结
完成上述步骤后,在模拟器中启动应用,点击 Generate 按钮,应该
0
0
复制全文
相关推荐









