ios - 自定义图像过滤器

标签 ios swift image algorithm image-processing

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.

图片总是很漂亮,所以请查看这张图片以了解我想要实现的目标:

img

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.代码信息 上面的代码运行良好,但绝对无效。由于所有的计算(尤其是颜色转换等),这段代码花费了很长(太长)的时间,所以看看这个截图:

img


  1. 我的问题 我很确定有一种过滤特定颜色的更简单的解决方案(具有给定的阈值 #c6456f 类似于 #C6476f,... ) 而不是遍历每个像素来比较它的颜色。

    • 所以我考虑的是像过滤器(CIFilter 方法)这样的东西作为顶层代码的替代方法。
  2. 一些注意事项

    • 因此,我不会要求您发布任何包含使用 openCV 库 的建议的回复。我想专门用 Swift 开发这个“算法”。

    • 随时间截取屏幕截图的图像大小分辨率为 500 * 800px

  3. 就这些

你真的读到这里了吗? - 不过恭喜 - 如果能帮助我加快代码速度,我们将不胜感激! (也许有更好的方法来获取像素颜色,而不是循环遍历每个像素)提前致谢一百万:)

最佳答案

要做的第一件事 - 分析(测量函数不同部分的时间消耗)。它经常表明时间花在了一些意想不到的地方,并且总是建议将优化工作引向何处。虽然这并不意味着您必须专注于最耗时的事情,但它会告诉您时间花在了哪里。不幸的是,我不熟悉 Swift,所以不能推荐任何特定的工具。

关于遍历所有像素 - 取决于图像结构和您对输入数据的假设。我看到两种可以避免这种情况的情况:

  1. 当在您的图像上构建了一些优化的数据结构时(例如,其区域中的一些统计数据)。当您使用具有不同参数的相同(或相似)算法处理相同图像时,这通常是有意义的。如果您只处理每张图像一次,它可能对您没有帮助。

  2. 当你知道绿色像素总是成群存在,所以不可能有孤立的单个像素。在这种情况下,您可以跳过一个或多个像素,当您找到一个绿色像素时,分析它的邻域。

关于ios - 自定义图像过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49338586/

相关文章:

html - 显示在一行中的列表中的图像

java - 使用java中的其他正常数据值将图像从servlet检索到jsp

iOS 静态库私有(private)方法和属性

ios - 改变火的方向

IOS dispatch_get_main_queue()被多次调用

ios - 从单元格中的 super View 中删除 View

swift - 检查用户是否已经在 SwiftyStoreKit 中购买了产品

ios - 在 Swift 中使用 UIScrollView 无限循环滚动

ios - 带撤消的 CGBitmapContextCreate 效果不佳

ios - 在 iOS 10.1 Xamarin(iOS) 中设置 StatusBar 样式的错误