Zastanawiałem się, czy możliwe jest zabinięcie obrazu (tylko konwertuj na czarno-białe) z podstawowym obrazem?

Zrobiłem to z OpenCV i GPUImage, ale wolałbym używać obrazu jabłkowego, jeśli to możliwe

0
Pascal 15 luty 2017, 18:47

2 odpowiedzi

Najlepsza odpowiedź

Tak. Masz co najmniej dwie opcje, Ciphotoeffectmono lub mały niestandardowy CicoRorkernel.

ciphotoeffecto:

func createMonoImage(image:UIImage) -> UIImage {
    let filter = CIFilter(name: "CIPhotoEffectMono")
    filter!.setValue(CIImage(image: image), forKey: "inputImage")
    let outputImage = filter!.outputImage
    let cgimg = ciCtx.createCGImage(outputImage!, from: (outputImage?.extent)!)
    return UIImage(cgImage: cgimg!)
}

Uwaga, piszę to szybko, może być konieczne zaostrzenie rzeczy do zerowych powrotów.

Cicolorkernel:

Fadetobw Glsl (0,0 czynnikowy kolorowy kolor, 1,0 czynnika nie jest koloru):

kernel vec4 fadeToBW(__sample s, float factor) {
    vec3 lum = vec3(0.299,0.587,0.114);
    vec3 bw = vec3(dot(s.rgb,lum));
    vec3 pixel = s.rgb + (bw - s.rgb) * factor;
    return vec4(pixel,s.a);
}

Poniższy kod Otwiera to jako plik o nazwie fadetobw.cikernel. Możesz także opublikować to jako ciąg bezpośrednio w połączeniu openKernelFile.

Kod Swift:

func createMonoImage(image:UIImage, inputColorFade:NSNumber) -> UIImage {
    let ciKernel = CIColorKernel(string: openKernelFile("FadeToBW"))
    let extent = image.extent
    let arguments = [image, inputColorFade]        
    let outputImage = ciKernel.applyWithExtent(extent, arguments: arguments)
    let cgimg = ciCtx.createCGImage(outputImage!, from: (outputImage?.extent)!)
    return UIImage(cgImage: cgimg!)
}

Ponownie dodaj trochę strażników itp.

4
dfd 15 luty 2017, 17:45

Możesz użyć do tego MetalperFormAnspanceres. I CiimageProcessingkernel. https://developer.apple.com/documentation/coreImage/ciimageProcessornernel

Oto kod potrzebnej klasy.

 class ThresholdImageProcessorKernel: CIImageProcessorKernel {
    static let device = MTLCreateSystemDefaultDevice()
    override class func process(with inputs: [CIImageProcessorInput]?, arguments: [String : Any]?, output: CIImageProcessorOutput) throws {
        guard
            let device = device,
            let commandBuffer = output.metalCommandBuffer,
            let input = inputs?.first,
            let sourceTexture = input.metalTexture,
            let destinationTexture = output.metalTexture,
            let thresholdValue = arguments?["thresholdValue"] as? Float else  {
                return
        }

        let threshold = MPSImageThresholdBinary(
            device: device,
            thresholdValue: thresholdValue,
            maximumValue: 1.0,
            linearGrayColorTransform: nil)

        threshold.encode(
            commandBuffer: commandBuffer,
            sourceTexture: sourceTexture,
            destinationTexture: destinationTexture)
    }
}

I tak można go użyć:

    let context = CIContext(options: nil)

            if let binaryCIImage = try? ThresholdImageProcessorKernel.apply(
                withExtent: croppedCIImage.extent,
                inputs: [croppedCIImage],
                arguments: ["thresholdValue": Float(0.2)]) {
                if let cgImage = context.createCGImage(binaryCIImage, from: binary.extent) {
                    DispatchQueue.main.async {
                        let resultingImage = UIImage(cgImage: cgImage)
                        if resultingImage.size.width > 100 {
                            print("Received an image \(resultingImage.size)")
                        }
                    }
                }
            }
3
Naloiko Eugene 14 luty 2019, 11:12