2013-04-26 10 views
14

Mój kod: Jak zarządzać wartością RGB dla różnych odcieni twarzy i jak złożyć wniosek? ten kod zmieni kolor twarzy wraz z włosami, ale chcę, aby 1.nie twarz być kolorowe z wyłączeniem włosów.Jak zmienić kolor skóry twarzy z obrazu źródłowego w ios?

-(void)changeSkinColorValue:(float)value WithImage:(UIImage*)needToModified 
    { 

     CGContextRef ctx; 

     CGImageRef imageRef = needToModified.CGImage; 
     NSUInteger width = CGImageGetWidth(imageRef); 
     NSUInteger height = CGImageGetHeight(imageRef); 
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
     //unsigned char *rawData = malloc(firstImageV.image.size.height * firstImageV.image.size.width * 10); 

     CFMutableDataRef m_DataRef = CFDataCreateMutableCopy(0, 0,CGDataProviderCopyData(CGImageGetDataProvider(firstImageV.image.CGImage))); 
     UInt8 *rawData = (UInt8 *) CFDataGetMutableBytePtr(m_DataRef); 
     int length = CFDataGetLength(m_DataRef); 
     NSUInteger bytesPerPixel = 4; 
     NSUInteger bytesPerRow = bytesPerPixel * firstImageV.image.size.width; 
     NSUInteger bitsPerComponent = 8; 

       CGContextRef context1 = CGBitmapContextCreate(rawData, firstImageV.image.size.width, firstImageV.image.size.height, bitsPerComponent, bytesPerRow, colorSpace,      kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
     CGColorSpaceRelease(colorSpace); 

     CGContextDrawImage(context1, CGRectMake(0, 0, firstImageV.image.size.width, firstImageV.image.size.height), imageRef); 

     NSLog(@"%d::%d",width,height); 


     // for(int ii = 0 ; ii < 250 ; ii+=4) 
     //{ 

      for(int ii = 0 ; ii < length ; ii+=4) 
      { 
      //NSLog(@"Raw data %s",rawData); 

      int R = rawData[ii]; 
      int G = rawData[ii+1]; 
      int B = rawData[ii+2]; 

      //  NSLog(@"%d %d %d", R, G, B); 
      //if(((R>60)&&(R<237)) || ((G>10)&&(G<120))||((B>4) && (B<120))) 
       //  if(((R>100)&&(R<186)) || ((G>56)&&(G<130))||((B>30) && (B<120))) 
       //  if(((R>188)&&(R<228)) || ((G>123)&&(G<163))||((B>85) && (B<125))) 
         // if(((R>95)&&(R<260)) || ((G>40)&&(G<210))||((B>20) && (B<170))) 

         //new code...... 

       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 
        } 
       } 


     ctx = CGBitmapContextCreate(rawData, 
          CGImageGetWidth(imageRef), 
          CGImageGetHeight(imageRef), 
          8, 
          CGImageGetBytesPerRow(imageRef), 
          CGImageGetColorSpace(imageRef), 
          kCGImageAlphaPremultipliedLast); 

     imageRef = CGBitmapContextCreateImage(ctx); 
     UIImage* rawImage = [UIImage imageWithCGImage:imageRef]; 
     //UIImageView *ty=[[UIImageView alloc]initWithFrame:CGRectMake(100, 200, 400, 400)]; 
     //ty.image=rawImage; 
     //[self.view addSubview:ty]; 
     [secondImageV setImage:rawImage]; 
     CGContextRelease(context1); 
     CGContextRelease(ctx); 
     free(rawData); 
    } 
+0

Ten kod zmienia nie tylko twarz i włosy, ale cały obraz, prawda? –

+0

@ SAMIR RATHOD możesz mi pomóc w tym samym pytaniu o zmianę koloru twarzy? http://stackoverflow.com/questions/37113740/change-face-color-from-main-color-in-xcode?noredirect=1#comment61769372_37113740 –

Odpowiedz

0

Szybka odpowiedź to zmienić RNO:

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

na łączeniu:

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

następnie dostosować RGB wynosi w przybliżeniu określić zakres odcieni skóry w obrazie (spróbuj z niektórymi suwakami w twoim interfejsie użytkownika).

Nawiasem mówiąc, przypuszczam, wiesz, że to:

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

jest przypisanie kanału czerwonego do zielonego kanału zielonego kanału do kanału niebieskiego i value do kanału alfa. Nie oczekuję, że tego chcesz.

Również prawdopodobnie Twój obraz needToModified ma być taki sam, jak firstImageV.image, który nie jest odzwierciedlony w kodzie takim, jaki jest teraz.

To podejście będzie działać tylko wtedy, gdy zidentyfikowane zakresy kolorów będą w całości i tylko obecne w regionach z miąższem obrazu.

długo odpowiedź może wyglądać na bardziej wyrafinowany dobór zakresów kolorów, alternatywnych sposobów wybierając obszary obrazu, wykorzystania CIFilter lub ramy OpenCV ...

+0

Po zastosowaniu operatora AND pozostawia kilka pikseli z obrazu i koloru wszystkie image.Chcę zmienić tylko kolor skóry. – madhyamika

+1

"To podejście zadziała tylko wtedy, gdy zidentyfikowane zakresy kolorów są w całości i tylko obecne w regionach z ciałem obrazu." ... jest to bardzo prymitywne podejście do wyboru regionu zainteresowania. Naprawdę potrzebujesz czegoś takiego jak narzędzie magicznej różdżki Photoshopa do wybrania sąsiednich podobnych obszarów obrazu i interaktywnego wejścia/interfejsu użytkownika. Proponuję zbadać [openCV] (http://openCV.org) ... – foundry

0

Spróbuj Maskowanie obrazu ... to będzie pomóc zmienić konkretny zakres kolorów zdefiniowanych w masce

Kod:

- (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

CFDataGetBytePtr Według dokumentów zwraca wskaźnik tylko do odczytu dla bajtów obiektu CFData. Czy na pewno nie szukasz CFDataGetBytes, który kopiuje zawartość bajtową obiektu CFData do zewnętrznego bufora. W takim przypadku musisz przydzielić bufor, aby zawierał szerokość * wysokość * bpp. Po uzyskaniu tej kopii możesz nią manipulować, mimo że chcesz utworzyć nowe zdjęcie.

Wybór pikseli Zgodnie z twoim pytaniem, rozumiem, że chcesz zmienić kolor skóry z białego na czarny. Twój aktualny kod iteruje po każdym pikselu, aby zmienić jego kolor.Powinieneś ocenić "odległość" między kolorem piksela a tym, czego szukasz, a jeśli jest poniżej pewnego progu, to go przetwarzaj. Operacja w HSV może być łatwiejsza niż przez operowanie kolorami RGB

0

1) Pobierz CGPath twarzy, w której chcesz zastosować swój algorytm. 2) Uzyskaj szerokość CGimage.

int width = CGImageGetWidth(image); 

3) Uzyskaj piksel CGPoint aktualnie przetwarzanego piksela. Sprawdź warunek przed zastosowaniem algorytmu. A następnie zastosuj swój stan. to jest to! Oto przykładowa część kodu.

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

tworzą twarz i włosy jako obiekty. obiekt ma kolor i ma globalną metodę zmiany kolorów. następnie w głównej części utwórz oba obiekty (włosy, twarz) i określ dokładnie to, co chcesz pokolorować. To jest właściwe podejście. mam nadzieję, że to pomoże!

Powiązane problemy