Αλλαγή Λευκό Pixels σε UIImage

ψήφοι
1

Έχω ένα UIImage το οποίο είναι ένα περίγραμμα, και μία η οποία είναι γεμάτη, τόσο δημιουργήθηκαν από OpenCV, ένα από κομμένα αρπαγή και το άλλο από διαρθρωτικό στοιχείο.

δύο εικόνες μου είναι κάπως έτσι:

εισάγετε

εισάγετε

Είμαι προσπαθεί να αλλάξει το σύνολο των λευκών εικονοστοιχείων στην περιγράφεται εικόνα γιατί θέλω να συγχωνεύσει τις δύο εικόνες μαζί έτσι θα καταλήξουμε με ένα κόκκινο περίγραμμα και λευκό γεμάτο περιοχή στη μέση. Είμαι χρησιμοποιώντας αυτό για να συγχωνεύσει τα δύο μαζί, και γνωρίζω αντί του κόκκινου θα είναι ένα ροζ είδος του χρώματος και γκρι αντί του λευκού αφού είμαι μόνο ανάμειξη μαζί με άλφα.

// Start an image context
UIGraphicsBeginImageContext(grabcutResult.size)

// Create rect for this draw session
let rect = CGRect(x: 0.0, y: 0.0, width: grabcutResult.size.width, height: grabcutResult.size.height)
grabcutResult.draw(in: rect)
redGrabcutOutline.draw(in: rect, blendMode: .normal, alpha: 0.5)

let finalImage = UIGraphicsGetImageFromCurrentImageContext()

και η ιδέα είναι ότι πρέπει να δούμε κάτι σαν αυτό.

εισάγετε

Θέλω να είναι σε θέση να ολοκληρώσει αυτή τη διαδικασία γρήγορα, αλλά οι μόνες λύσεις που έχω βρει είναι είτε για ImageView (η οποία επηρεάζει μόνο το πώς τα πράγματα καθίσταται όχι το υποκείμενο UIImage) ή περιλαμβάνουν looping σε όλο το pixel της εικόνας από pixel.

Είμαι προσπαθεί να βρει μια λύση που θα καλύψει μόνο όλα τα λευκά εικονοστοιχεία στο περίγραμμα σε κόκκινο, χωρίς να χρειάζεται να βρόχο σε όλο το pixel της εικόνας από pixel, καθώς είναι πολύ αργή.

Στην ιδανική περίπτωση θα ήταν καλό αν θα μπορούσα να πάρω OpenCV να επιστρέψει μόνο ένα κόκκινο περίγραμμα αντί του λευκού, αλλά δεν νομίζω ότι είναι δυνατόν του να αλλάξει αυτή (ίσως im λάθος).

Χρησιμοποιώντας ταχεία btw ... αλλά κάθε βοήθεια είναι ευπρόσδεκτη, ευχαριστώ εκ των προτέρων.

Δημοσιεύθηκε 09/10/2019 στις 18:54
πηγή χρήστη
Σε άλλες γλώσσες...                            


3 απαντήσεις

ψήφοι
0

Αυτό μπορεί να λειτουργήσει για σας - χρησιμοποιώντας μόνο Swift code ...

extension UIImage {

    func maskWithColor(color: UIColor) -> UIImage? {

        let maskingColors: [CGFloat] = [1, 255, 1, 255, 1, 255]
        let bounds = CGRect(origin: .zero, size: size)

        let maskImage = cgImage!
        var returnImage: UIImage?

        // make sure image has no alpha channel
        let rFormat = UIGraphicsImageRendererFormat()
        rFormat.opaque = true
        let renderer = UIGraphicsImageRenderer(size: size, format: rFormat)
        let noAlphaImage = renderer.image {
            (context) in
            self.draw(at: .zero)
        }

        let noAlphaCGRef = noAlphaImage.cgImage

        if let imgRefCopy = noAlphaCGRef?.copy(maskingColorComponents: maskingColors) {

            let rFormat = UIGraphicsImageRendererFormat()
            rFormat.opaque = false
            let renderer = UIGraphicsImageRenderer(size: size, format: rFormat)
            returnImage = renderer.image {
                (context) in
                context.cgContext.clip(to: bounds, mask: maskImage)
                context.cgContext.setFillColor(color.cgColor)
                context.cgContext.fill(bounds)
                context.cgContext.draw(imgRefCopy, in: bounds)
            }

        }
        return returnImage
    }

}

Η επέκταση αυτή επιστρέφει ένα UIImageμε λευκά αντικαταστάθηκε με το πέρασε UIColor, και το μαύρο «φόντο» άλλαξε σε διαφανές.

Χρησιμοποιήστε το με αυτόν τον τρόπο:

// change filled white star to gray with transparent background
let modFilledImage = filledImage.maskWithColor(color: UIColor(red: 200, green: 200, blue: 200))

// change outlined white star to red with transparent background
let modOutlineImage = outlineImage.maskWithColor(color: UIColor.red)

// combine the images on a black background

Εδώ είναι ένα πλήρες παράδειγμα, χρησιμοποιώντας δύο αρχικές εικόνες σας (το μεγαλύτερο μέρος του κώδικα δημιουργεί τις απόψεις εικόνα για να δείτε τα αποτελέσματα):

extension UIImage {

    func maskWithColor(color: UIColor) -> UIImage? {

        let maskingColors: [CGFloat] = [1, 255, 1, 255, 1, 255]
        let bounds = CGRect(origin: .zero, size: size)

        let maskImage = cgImage!
        var returnImage: UIImage?

        // make sure image has no alpha channel
        let rFormat = UIGraphicsImageRendererFormat()
        rFormat.opaque = true
        let renderer = UIGraphicsImageRenderer(size: size, format: rFormat)
        let noAlphaImage = renderer.image {
            (context) in
            self.draw(at: .zero)
        }

        let noAlphaCGRef = noAlphaImage.cgImage

        if let imgRefCopy = noAlphaCGRef?.copy(maskingColorComponents: maskingColors) {

            let rFormat = UIGraphicsImageRendererFormat()
            rFormat.opaque = false
            let renderer = UIGraphicsImageRenderer(size: size, format: rFormat)
            returnImage = renderer.image {
                (context) in
                context.cgContext.clip(to: bounds, mask: maskImage)
                context.cgContext.setFillColor(color.cgColor)
                context.cgContext.fill(bounds)
                context.cgContext.draw(imgRefCopy, in: bounds)
            }

        }
        return returnImage
    }

}

class MaskWorkViewController: UIViewController {

    let origFilledImgView: UIImageView = {
        let v = UIImageView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.contentMode = .center
        return v
    }()

    let origOutlineImgView: UIImageView = {
        let v = UIImageView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.contentMode = .center
        return v
    }()

    let modifiedFilledImgView: UIImageView = {
        let v = UIImageView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.contentMode = .center
        return v
    }()

    let modifiedOutlineImgView: UIImageView = {
        let v = UIImageView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.contentMode = .center
        return v
    }()

    let combinedImgView: UIImageView = {
        let v = UIImageView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.contentMode = .center
        return v
    }()

    let origStack: UIStackView = {
        let v = UIStackView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.axis = .horizontal
        v.spacing = 20
        return v
    }()

    let modifiedStack: UIStackView = {
        let v = UIStackView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.axis = .horizontal
        v.spacing = 20
        return v
    }()

    let mainStack: UIStackView = {
        let v = UIStackView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.axis = .vertical
        v.alignment = .center
        v.spacing = 10
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let filledImage = UIImage(named: "StarFill"),
            let outlineImage = UIImage(named: "StarEdge") else {
                return
        }

        var modifiedFilledImage: UIImage = UIImage()
        var modifiedOutlineImage: UIImage = UIImage()
        var combinedImage: UIImage = UIImage()

        // for both original images, replace white with color
        // and make black transparent
        if let modFilledImage = filledImage.maskWithColor(color: UIColor(red: 200, green: 200, blue: 200)),
            let modOutlineImage = outlineImage.maskWithColor(color: UIColor.red) {

            modifiedFilledImage = modFilledImage
            modifiedOutlineImage = modOutlineImage

            let rFormat = UIGraphicsImageRendererFormat()
            rFormat.opaque = true

            let renderer = UIGraphicsImageRenderer(size: modifiedFilledImage.size, format: rFormat)

            // combine modified images on black background
            combinedImage = renderer.image {
                (context) in
                context.cgContext.setFillColor(UIColor.black.cgColor)
                context.cgContext.fill(CGRect(origin: .zero, size: modifiedFilledImage.size))
                modifiedFilledImage.draw(at: .zero)
                modifiedOutlineImage.draw(at: .zero)
            }

        }

        // setup image views and set .image properties
        setupUI(filledImage.size)

        origFilledImgView.image = filledImage
        origOutlineImgView.image = outlineImage

        modifiedFilledImgView.image = modifiedFilledImage
        modifiedOutlineImgView.image = modifiedOutlineImage

        combinedImgView.image = combinedImage

    }

    func setupUI(_ imageSize: CGSize) -> Void {

        origStack.addArrangedSubview(origFilledImgView)
        origStack.addArrangedSubview(origOutlineImgView)

        modifiedStack.addArrangedSubview(modifiedFilledImgView)
        modifiedStack.addArrangedSubview(modifiedOutlineImgView)

        var lbl = UILabel()
        lbl.textAlignment = .center
        lbl.text = "Original Images"

        mainStack.addArrangedSubview(lbl)

        mainStack.addArrangedSubview(origStack)

        lbl = UILabel()
        lbl.textAlignment = .center
        lbl.numberOfLines = 0
        lbl.text = "Modified Images\n(UIImageViews have Green Background)"

        mainStack.addArrangedSubview(lbl)

        mainStack.addArrangedSubview(modifiedStack)

        lbl = UILabel()
        lbl.textAlignment = .center
        lbl.text = "Combined on Black Background"

        mainStack.addArrangedSubview(lbl)

        mainStack.addArrangedSubview(combinedImgView)

        view.addSubview(mainStack)

        NSLayoutConstraint.activate([

            mainStack.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20.0),
            mainStack.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0.0),

        ])

        [origFilledImgView, origOutlineImgView, modifiedFilledImgView, modifiedOutlineImgView, combinedImgView].forEach {

            $0.backgroundColor = .green

            NSLayoutConstraint.activate([

                $0.widthAnchor.constraint(equalToConstant: imageSize.width),
                $0.heightAnchor.constraint(equalToConstant: imageSize.height),

            ])

        }

    }

}

Και το αποτέλεσμα, που δείχνει το πρωτότυπο, τροποποιημένη και την τελική συνδυασμένη εικόνα ... θέα Image έχουν πράσινο υπόβαθρο για να δείξει τις διαφανείς περιοχές:

εισάγετε περιγραφή της εικόνας εδώ

Απαντήθηκε 14/10/2019 στις 19:12
πηγή χρήστη

ψήφοι
0

Η ιδέα είναι να bitwise-orτα δύο μάσκες μαζί που «συγχωνεύει» τις δύο μάσκες. Δεδομένου ότι αυτή η νέα συνδυασμένη κλίμακα του γκρι εικόνα εξακολουθεί να είναι ένα ενιαίο (1 καναλιού) εικόνα, θα πρέπει να το μετατρέψετε σε ένα 3-κανάλι, ώστε να μπορούμε να εφαρμόσετε χρώμα στην εικόνα. Τέλος, το χρώμα της μάσκας περίγραμμα με κόκκινο χρώμα για να πάρει αποτέλεσμα μας

εισάγετε περιγραφή της εικόνας εδώ

Μου εφαρμοστεί σε Python OpenCV, αλλά μπορείτε να προσαρμόσετε την ίδια ιδέα με το Swift

import cv2

# Read in images as grayscale
full = cv2.imread('1.png', 0)
outline = cv2.imread('2.png', 0)

# Bitwise-or masks
combine = cv2.bitwise_or(full, outline)

# Combine to 3 color channel and color outline red
combine = cv2.merge([combine, combine, combine])
combine[outline > 120] = (57,0,204)

cv2.imshow('combine', combine)
cv2.waitKey()

Benchmarks χρησιμοποιώντας IPython

In [3]: %timeit combine()
782 µs ± 10.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Χρησιμοποιώντας τη λειτουργία vectorized της NumPy, φαίνεται να είναι αρκετά γρήγορος

Απαντήθηκε 10/10/2019 στις 00:31
πηγή χρήστη

ψήφοι
0

δοκιμάστε αυτό:

public func maskWithColor2( color:UIColor) -> UIImage {

    UIGraphicsBeginImageContextWithOptions(self.size, false, UIScreen.main.scale)
    let context = UIGraphicsGetCurrentContext()!

    color.setFill()

    context.translateBy(x: 0, y: self.size.height)
    context.scaleBy(x: 1.0, y: -1.0)

    let rect = CGRect(x: 0.0, y: 0.0, width: self.size.width, height: self.size.height)
    context.draw(self.cgImage!, in: rect)

    context.setBlendMode(CGBlendMode.sourceIn)
    context.addRect(rect)
    context.drawPath(using: CGPathDrawingMode.fill)

    let coloredImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return coloredImage!
}
Απαντήθηκε 09/10/2019 στις 19:44
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more