How to change the skin color of face from the source image in ios?

后端 未结 6 403
失恋的感觉
失恋的感觉 2021-01-31 21:45

MY code: How to manage RGB value for differet shades of face,and how to apply? this code will change the color of face along with hair,but i want 1.only face to be colored excl

相关标签:
6条回答
  • 2021-01-31 21:51

    make the face and the hair as objects. object have color and have a global method to change their colors. then in your main,make both objects (hair, face) and specify what you want to color exactly. This is the right approach. hope it helps!

    0 讨论(0)
  • 2021-01-31 21:52

    CFDataGetBytePtr According to the docs, it Returns a read-only pointer to the bytes of a CFData object., are you sure you're not looking for CFDataGetBytes which Copies the byte contents of a CFData object to an external buffer. In which case you'll have to allocate your buffer to contain width * height * bpp. Once you have this copy, you can manipulate it anyway you want to create the new picture.

    Pixel Selection According to your question, I seem to understand that you want to change skin color from White to Black. Your current code iterates over every pixel to change its color. You should evaluate the "distance" between the pixel color and what you're looking for, and if it's below a certain threshold process it. It might be easier to perform the operation in HSV than by dealing with RGB colors

    0 讨论(0)
  • 2021-01-31 21:56

    Try Masking the image ... it will help to change the specific range of colors defined in mask

    Code:

    - (UIImage *)doctorTheImage:(UIImage *)originalImage
    {
    
       const float brownsMask[6] = {85, 255, 85, 255, 85, 255};
    
    
        UIImageView *imageView = [[UIImageView alloc] initWithImage:originalImage];
    
        UIGraphicsBeginImageContext(originalImage.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        CGContextSetRGBFillColor (context, 1.0,1.0, 1.0, 1);
    
    
        CGContextFillRect(context, CGRectMake(0, 0, imageView.image.size.width, imageView.image.size.height));
    
        CGImageRef brownRef = CGImageCreateWithMaskingColors(imageView.image.CGImage, brownsMask);
    
        CGRect imageRect = CGRectMake(0, 0, imageView.image.size.width, imageView.image.size.height);
    
        CGContextTranslateCTM(context, 0, imageView.image.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
        //CGImageRef whiteRef = CGImageCreateWithMaskingColors(brownRef, whiteMask);
        CGContextDrawImage (context, imageRect, brownRef);
    
        //[originalImage drawInRect:CGRectMake(0, 0, imageView.image.size.width, imageView.image.size.height)];
    
        CGImageRelease(brownRef);
       // CGImageRelease(whiteRef);
    
        UIImage *doctoredImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return doctoredImage;
    }
    
    0 讨论(0)
  • 2021-01-31 22:01

    The quick answer is to change your ORs:

                if( ( (R>0)&&(R<260) ) || ((G>0)&&(G<210)) || ((B>0) && (B<170)))
    

    to ANDs:

                if( ( (R>0)&&(R<260) ) && ((G>0)&&(G<210)) && ((B>0) && (B<170)))
    

    Then adjust your RGB ranges to approximate the range of skin tones in the image (try with some sliders in your UI).

    By the way, I presume you know that this:

            rawData[ii+1]=R;//13;
            rawData[ii+2]=G;//43;
            rawData[ii+3]=value;//63
    

    is assigning the red channel to the green channel, the green channel to the blue channel, and value to the ALPHA channel. I don't expect that is what you want.

    Also your needToModified image is probably intended to be the same image as firstImageV.image, which is not reflected in your code as it is now.

    This approach will only work if your identified colour ranges are wholly and only present in flesh regions of the image.

    A long answer could look at more sophisticated selection of colour ranges, alternative ways of selecting image regions, the use of CIFilter or the openCV framework...

    0 讨论(0)
  • 2021-01-31 22:01

    1) Get a CGPath of face where you want to apply your algorithm. 2) Get width of CGimage.

    int width = CGImageGetWidth(image);
    

    3) Get pixel CGPoint of currently processing pixel. Check for the condition before applying your algorithm. And then apply your condition. That's it. Here is the sample portion of code.

    CGFloat pointY = (int)(i/4)/(int)width;
    CGFloat pointX = (int)(i/4)%(int)width;
    CGPoint point = CGPointMake(pointX, pointY);
    
    if (CGPathContainsPoint(yourFacePath, NULL, point, NO))
    {
        if( ( (R>0)&&(R<260) ) || ((G>0)&&(G<210))||((B>0) && (B<170)))
        {
            rawData[ii+1]=R;//13;
            rawData[ii+2]=G;//43;
            rawData[ii+3]=value;//63
        }
    }
    
    0 讨论(0)
  • 2021-01-31 22:08

    Try to use GPUImage Framework by Brad Larson:

    https://github.com/BradLarson/GPUImage

    This is very powerful framework for working with images.

    Read this question:

    GPUImage create a custom Filter that change selected colors

    Hope it helps!

    0 讨论(0)
提交回复
热议问题