opencv - Remove background from Image & take only Image part for save in iOS -


this need achieve:

  • take image camera or gallery
  • remove background image & save it
  • background should black or white
  • also need remove shadow along background

result example:

original image

enter image description here

result image

enter image description here

this have tried:

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]; 

its work on white background. not more effective. need achieve exact result have placed in above images.

i have referred references:

ios how mask image background color

how remove background of image in iphone app?

changing background color of captured image camera white

can me achieve ?

any references or highly appreciated.

thanks in advance.

generally, rule of thumb, more different background color other colors, easier split image fore- , background. in such case, @chris suggested, possible use simple chroma key implementation. below quick implementation of keying described on wikipedia (it's written in c++ translating objective-c should easy):

/**  * @brief separate foreground background using simple chroma keying.  *  * @param imagebgr   image monochrome background  * @param chromabgr  color of background (using channel order bgr , range [0, 255])  * @param tinner     inner threshold, color distances below value counted foreground  * @param touter     outer threshold, color distances above value counted background  *  * @return  mask (0 - background, 255 - foreground, [1, 255] - partially fore- , background)  *  * details can 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 image ycrcb.     // 2. measure euclidean distances of color in ycrbr chroma value.     // 3. categorize pixels:     //   * color distances below inner threshold count foreground; mask value = 0     //   * color distances above outer threshold count background; mask value = 255     //   * color distances between inner , outer threshold linearly interpolated; mask value = [0, 255]      assert( tinner <= touter );      // convert 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 single bgr value ycrcb.      // build mask.     cv::mat1b mask = cv::mat1b::zeros( imagesize );     const cv::vec3d key( chromaycrcb[ 0 ], chromaycrcb[ 1 ], chromaycrcb[ 2 ] );      ( int y = 0; y < imagesize.height; ++y )     {         ( 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 part of background.                 mask( y, x ) = 0;             }             else if ( distance > touter )             {                 // current pixel part of foreground.                 mask( y, x ) = 255;             }             else             {                 // current pixel partially part both, fore- , background; interpolate linearly.                 // compute interpolation factor , clip value 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; } 

a working code example can found in github gist.

unfortunately, example not stick rule of thumb. since foreground , background vary in intensity difficult (or impossible) find single global set of parameters separation:

  1. black line around object no holes inside object (tinner=50, touter=90) mask 1 background substitution 1

  2. no black line around object holes inside object (tinner=100, touter=170) mask 2 background substitution 2

so, if cannot change background of images more complicated approach required. however, quick , simple example implementation bit out of scope, may want related areas of image segmentation , alpha matting.


Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -