1.简介:
So I want to develop a special filter method for uiimages - my idea is to change from one picture all the colors to black except a certain color, which should keep their appearance.
图片总是很漂亮,所以请查看这张图片以了解我想要实现的目标:
2.解释:
我想应用一个能够在图像中找到特定颜色的过滤器(算法)。该算法必须能够用例如“黑色”替换所有与引用颜色不匹配的颜色。
我开发了一个简单的代码,可以替换任何图像中的特定颜色(具有阈值的颜色范围)。 但是这个解决方案似乎根本不是一种快速有效的方法!
func colorFilter(image: UIImage, findcolor: String, threshold: Int) -> UIImage {
let img: CGImage = image.cgImage!
let context = CGContext(data: nil, width: img.width, height: img.height, bitsPerComponent: 8, bytesPerRow: 4 * img.width, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)!
context.draw(img, in: CGRect(x: 0, y: 0, width: img.width, height: img.height))
let binaryData = context.data!.assumingMemoryBound(to: UInt8.self),
referenceColor = HEXtoHSL(findcolor) // [h, s, l] integer array
for i in 0..<img.height {
for j in 0..<img.width {
let pixel = 4 * (i * img.width + j)
let pixelColor = RGBtoHSL([Int(binaryData[pixel]), Int(binaryData[pixel+1]), Int(binaryData[pixel+2])]) // [h, s, l] integer array
let distance = calculateHSLDistance(pixelColor, referenceColor) // value between 0 and 100
if (distance > threshold) {
let setValue: UInt8 = 255
binaryData[pixel] = setValue; binaryData[pixel+1] = setValue; binaryData[pixel+2] = setValue; binaryData[pixel+3] = 255
}
}
}
let outputImg = context.makeImage()!
return UIImage(cgImage: outputImg, scale: image.scale, orientation: image.imageOrientation)
}
3.代码信息 上面的代码运行良好,但绝对无效。由于所有的计算(尤其是颜色转换等),这段代码花费了很长(太长)的时间,所以看看这个截图:
我的问题 我很确定有一种过滤特定颜色的更简单的解决方案(具有给定的阈值
#c6456f 类似于 #C6476f,...
) 而不是遍历每个像素来比较它的颜色。- 所以我考虑的是像过滤器(CIFilter 方法)这样的东西作为顶层代码的替代方法。
一些注意事项
因此,我不会要求您发布任何包含使用 openCV 库 的建议的回复。我想专门用 Swift 开发这个“算法”。
随时间截取屏幕截图的图像大小分辨率为 500 * 800px
就这些
你真的读到这里了吗? - 不过恭喜 - 如果能帮助我加快代码速度,我们将不胜感激! (也许有更好的方法来获取像素颜色,而不是循环遍历每个像素)提前致谢一百万:)
最佳答案
要做的第一件事 - 分析(测量函数不同部分的时间消耗)。它经常表明时间花在了一些意想不到的地方,并且总是建议将优化工作引向何处。虽然这并不意味着您必须专注于最耗时的事情,但它会告诉您时间花在了哪里。不幸的是,我不熟悉 Swift,所以不能推荐任何特定的工具。
关于遍历所有像素 - 取决于图像结构和您对输入数据的假设。我看到两种可以避免这种情况的情况:
当在您的图像上构建了一些优化的数据结构时(例如,其区域中的一些统计数据)。当您使用具有不同参数的相同(或相似)算法处理相同图像时,这通常是有意义的。如果您只处理每张图像一次,它可能对您没有帮助。
当你知道绿色像素总是成群存在,所以不可能有孤立的单个像素。在这种情况下,您可以跳过一个或多个像素,当您找到一个绿色像素时,分析它的邻域。
关于ios - 自定义图像过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49338586/