Detect Finger nail and Overlay color - OpenCV, Vision, AR iOS Swift

35 Views Asked by At

I am trying to detect the nails from the image of hands and try to overlay detected nail area with colour. I have been trying different approaches using OpenCV , Vision but nothing worked out till date.

Below is the opencv method that I have been using..

+ (UIImage *)detectAndColorNailsInImage:(UIImage *)image withColor:(UIColor *)color {
cv::Mat inputMat;
UIImageToMat(image, inputMat);

// Convert the image to grayscale
cv::Mat grayscaleMat;
cv::cvtColor(inputMat, grayscaleMat, cv::COLOR_BGR2GRAY);

// Apply Gaussian blur to reduce noise
cv::Mat blurredMat;
cv::GaussianBlur(grayscaleMat, blurredMat, cv::Size(5, 5), 0);

// Apply thresholding to extract nails
cv::Mat thresholdMat;
cv::threshold(grayscaleMat, thresholdMat, 100, 255, cv::THRESH_TRIANGLE);
UIImage *outpqutImage = MatToUIImage(thresholdMat);

// Find contours
std::vector<std::vector<cv::Point>> contours;
cv::findContours(thresholdMat, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);

// Draw contours on the original image
for (int i = 0; i < contours.size(); ++i) {
    // Calculate contour area
    double area = cv::contourArea(contours[i]);

    // If the contour area is smaller than a threshold, it's likely not a nail
    if (area < 100) {
        continue;
    }

    // Draw contours with the specified color
    cv::drawContours(inputMat, contours, i, cv::Scalar(255, 0, 0), 2);
}

UIImage *outputImage = MatToUIImage(inputMat);
return outputImage;}

And also I have been trying to use vision method as below

    func vision(){
    var rgbaIn = UIImage(named: "nail2.jpeg")!

    guard let ciImage = CIImage(image: rgbaIn) else {
        // Handle error
        return
    }

    let request = VNDetectHumanHandPoseRequest()
    let handler = VNImageRequestHandler(ciImage: ciImage)
    do {
        try handler.perform([request])
    } catch {
        print("Error: \(error)")
        return
    }
    guard let observations = request.results else {
        // No hand pose observations found
        
        return
    }
    
    for observation in observations {
        guard let handLandmarks = try? observation.recognizedPoints(.all) else {
            continue
        }
        
        // Iterate through the recognized hand landmarks
        for (jointName, points) in handLandmarks {
            // Check if the joint corresponds to a finger tip
            if jointName == .indexTip || jointName == .middleTip || jointName == .ringTip || jointName == .littleTip {
                // Iterate through the detected points for this joint
                rgbaIn = overlayColor(on: rgbaIn, at: points.location, color: UIColor.red)
                print(rgbaIn)
            }
        }

        // Use the overlayedImage for further processing or display
    }

}

    // Function to overlay color on the image at a specific position
func overlayColor(on image: UIImage, at position: CGPoint, color: UIColor) -> UIImage {
    // Begin image context
    UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale)
    defer { UIGraphicsEndImageContext() }
    
    // Draw the original image
    image.draw(at: .zero)
    
    // Set the color
    color.setFill()
    
    // Create a CGRect with a small size (representing the nail)
    let nailRect = CGRect(x: position.x - 5, y: position.y - 5, width: 50  , height: 50)
    
    // Fill the CGRect with color
    UIRectFill(nailRect)
    
    // Get the overlaid image from the context
    guard let overlayedImage = UIGraphicsGetImageFromCurrentImageContext() else {
        return image
    }
    
    return overlayedImage
}

for the both above methods there is not suitable outcomes.! Any help or direction will be appreciated. Thank you.

0

There are 0 best solutions below