大家肯定都用過PS進行摳圖(扣圖),而在Swift中,使用代碼也可以實現摳圖功能。
1,要把一個人物或物體從背景中摳出來,通常有兩種辦法:
(2)使用openCv邊緣檢測:復雜背景情況也適用,默認摳圖不夠精確
2,下面使用第一種方案把下面的小貓摳出來,放置到雪地背景上。
3,如何使用Core Image摳圖
對於純色背景,可以直接把背景色給消除,這樣剩下的便是主體了。要消除背景色,可以使用CIColorCube濾鏡。
而CIColorCube濾鏡需要一張cube映射表,這張表其實就是張顏色表(3D顏色查找表),把你想消除的顏色的alpha值設置為0,其他的顏色不變,Core Image將會把圖像數據上的顏色映射為表中的顏色,以此來達到消除某種顏色的目的。
4,代表顏色值區域的HSV(Hue值)圖
通過這個可以很方便的查看RGB顏色對應的HSV值。比如小貓背景都是藍色的(只不過深淺不一),我們只需要把HSV在210到240這段顏色去處即可。
5,下面是樣例效果圖
為便於比較,我這邊分別做了“只摳圖”,以及“摳圖並更換背景”兩個功能。(真是毫無PS痕跡)
6,代碼如下:
(1)首先創建Cube Map表
新建一個“C File”文件CubeMap.c,會Xcode會自動生成對應的頭文件CubeMap.h,還有連接頭文件(Bridging Header文件)。各文件裡代碼如下:
6,代碼如下:
(1)首先創建Cube Map表
新建一個“C File”文件CubeMap.c,會Xcode會自動生成對應的頭文件CubeMap.h,還有連接頭文件(Bridging Header文件)。各文件裡代碼如下:
import UIKit
class ViewController: UIViewController{
@IBOutlet weak var imageView: UIImageView!
//圖片原圖
lazy var originalImage: UIImage = {
return UIImage(named: "cat.jpg")
}()!
lazy var context: CIContext = {
return CIContext(options: nil)
}()
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = originalImage
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//摳圖
@IBAction func cutOut(sender: AnyObject) {
let cubeMap = createCubeMap(210,240)
let data = NSData(bytesNoCopy: cubeMap.data, length: Int(cubeMap.length),
freeWhenDone: true)
//消除某種顏色
let colorCubeFilter = CIFilter(name: "CIColorCube")!
colorCubeFilter.setValue(cubeMap.dimension, forKey: "inputCubeDimension")
colorCubeFilter.setValue(data, forKey: "inputCubeData")
colorCubeFilter.setValue(CIImage(image: originalImage), forKey: kCIInputImageKey)
let outputImage = colorCubeFilter.outputImage
let cgImage = context.createCGImage(outputImage!, fromRect: outputImage!.extent)
imageView.image = UIImage(CGImage: cgImage)
}
//摳圖並合成
@IBAction func cutOutAndCompose(sender: AnyObject) {
let cubeMap = createCubeMap(210,240)
let data = NSData(bytesNoCopy: cubeMap.data, length: Int(cubeMap.length),
freeWhenDone: true)
//消除某種顏色
let colorCubeFilter = CIFilter(name: "CIColorCube")!
colorCubeFilter.setValue(cubeMap.dimension, forKey: "inputCubeDimension")
colorCubeFilter.setValue(data, forKey: "inputCubeData")
colorCubeFilter.setValue(CIImage(image: originalImage), forKey: kCIInputImageKey)
var outputImage = colorCubeFilter.outputImage
//與背景圖合成
let sourceOverCompositingFilter = CIFilter(name: "CISourceOverCompositing")!
sourceOverCompositingFilter.setValue(outputImage, forKey: kCIInputImageKey)
sourceOverCompositingFilter.setValue(CIImage(image: UIImage(named: "bg.jpg")!),
forKey: kCIInputBackgroundImageKey)
outputImage = sourceOverCompositingFilter.outputImage
let cgImage = context.createCGImage(outputImage!, fromRect: outputImage!.extent)
imageView.image = UIImage(CGImage: cgImage)
}
//還原圖片
@IBAction func resetImage(sender: AnyObject) {
self.imageView.image = originalImage
}
}