Eliminar el background de la image y tomar solo la parte de la image para save en iOS

Esto es lo que necesito lograr:

  • Tome la image de la camera o Galería
  • Eliminar el background de la image y savelo
  • El background debe ser cualquier cosa negro o blanco
  • También es necesario eliminar la sombra junto con el background.

Ejemplo de resultado:

Imagen original

introduzca la descripción de la imagen aquí

Imagen de resultado

introduzca la descripción de la imagen aquí

Esto es lo que he intentado:

CGFloat colorMasking[6]={222,255,222,255,222,255}; CGImageRef imageRef = CGImageCreateWithMaskingColors([IMG CGImage], colorMasking); UIImage *resultThumbImage = [UIImage imageWithCGImage:imageRef scale:ThumbImage.scale orientation:IMG.imageOrientation]; 

Solo funciona en background blanco. No es más efectivo Necesito get el resultado exacto que he colocado en las imágenes de arriba.

También he referido algunas references:

iOS cómo enmascarar el color de background de la image

¿Cómo eliminar el background de la image en la aplicación iphone?

Cambiar el color de background de una image capturada de la camera a blanca

¿Alguien me puede ayudar a lograr esto?

Cualquier reference o será muy apreciada.

Gracias por adelantado.

En general, como regla general, cuanto más diferente sea el color de background de todos los demás colors, más fácil será dividir la image en fore y en segundo plano. En tal caso, como @Chris ya sugirió, es posible usar una simple implementación de key de chroma. A continuación se muestra mi implementación rápida de las keys descritas en Wikipedia (está escrito en C ++ pero traducirlo a Objective-C debería ser fácil):

 /** * @brief Separate foreground from background using simple chroma keying. * * @param imageBGR Image with monochrome background * @param chromaBGR Color of the background (using channel order BGR and range [0, 255]) * @param tInner Inner threshold, color distances below this value will be counted as foreground * @param tOuter Outer threshold, color distances above this value will be counted as background * * @return Mask (0 - background, 255 - foreground, [1, 255] - partially fore- and background) * * Details can be found on [Wikipedia][1]. * * [1]: https://en.wikipedia.org/wiki/Chroma_key#Programming */ cv::Mat1b chromaKey( const cv::Mat3b & imageBGR, cv::Scalar chromaBGR, double tInner, double tOuter ) { // Basic outline: // // 1. Convert the image to YCrCb. // 2. Measure Euclidean distances of color in YCrBr to chroma value. // 3. Categorize pixels: // * color distances below inner threshold count as foreground; mask value = 0 // * color distances above outer threshold count as background; mask value = 255 // * color distances between inner and outer threshold a linearly interpolated; mask value = [0, 255] assert( tInner <= tOuter ); // Convert to YCrCb. assert( ! imageBGR.empty() ); cv::Size imageSize = imageBGR.size(); cv::Mat3b imageYCrCb; cv::cvtColor( imageBGR, imageYCrCb, cv::COLOR_BGR2YCrCb ); cv::Scalar chromaYCrCb = bgr2ycrcb( chromaBGR ); // Convert a single BGR value to YCrCb. // Build the mask. cv::Mat1b mask = cv::Mat1b::zeros( imageSize ); const cv::Vec3d key( chromaYCrCb[ 0 ], chromaYCrCb[ 1 ], chromaYCrCb[ 2 ] ); for ( int y = 0; y < imageSize.height; ++y ) { for ( int x = 0; x < imageSize.width; ++x ) { const cv::Vec3d color( imageYCrCb( y, x )[ 0 ], imageYCrCb( y, x )[ 1 ], imageYCrCb( y, x )[ 2 ] ); double distance = cv::norm( key - color ); if ( distance < tInner ) { // Current pixel is fully part of the background. mask( y, x ) = 0; } else if ( distance > tOuter ) { // Current pixel is fully part of the foreground. mask( y, x ) = 255; } else { // Current pixel is partially part both, fore- and background; interpolate linearly. // Compute the interpolation factor and clip its value to the range [0, 255]. double d1 = distance - tInner; double d2 = tOuter - tInner; uint8_t alpha = static_cast< uint8_t >( 255. * ( d1 / d2 ) ); mask( y, x ) = alpha; } } } return mask; } 

Se puede encontrar un ejemplo de código completo en este Github Gist .

Desafortunadamente, su ejemplo no se ajusta a esa regla general. Dado que el primer plano y el background solo varían en intensidad, es difícil (o incluso imposible) encontrar un único set global de parameters para una buena separación:

  1. Línea negra alnetworkingedor del object pero sin agujeros en el interior del object ( tInner=50 , tOuter=90 ) máscara 1sustitución de fondo 1

  2. No hay línea negra alnetworkingedor del object, sino agujeros dentro del object ( tInner=100 , tOuter=170 ) máscara 2sustitución de fondo 2

Entonces, si no puede cambiar el background de sus imágenes, se requiere un enfoque más complicado. Sin embargo, una implementación de ejemplo rápida y simple está un poco fuera de scope, pero es posible que desee search en áreas relacionadas de segmentación de imágenes y alfombras alfa .

Creo que necesitas usar un cromakey, aunque estás escogiendo negro, creo que debería funcionar.

Un rápido google apareció con esto