2014-10-28 31 views
5

sto convertendo ciimage a monocromatica, con clipping CICrop e funzionante Sobel per rilevare bordi, #if sezione in fondo viene utilizzato provocareCIImage (IOS): Aggiunta 3x3 convoluzione dopo un filtro monocromatico ripristina qualche colore

per visualizzare
CIImage *ci = [[CIImage alloc] initWithCGImage:uiImage.CGImage]; 

CIImage *gray = [CIFilter filterWithName:@"CIColorMonochrome" keysAndValues: 
     @"inputImage", ci, @"inputColor", [[CIColor alloc] initWithColor:[UIColor whiteColor]], 
     nil].outputImage; 



CGRect rect = [ci extent]; 
rect.origin = CGPointZero; 

CGRect cropRectLeft = CGRectMake(0, 0, rect.size.width * 0.2, rect.size.height); 
CIVector *cropRect = [CIVector vectorWithX:rect.origin.x Y:rect.origin.y Z:rect.size.width* 0.2 W:rect.size.height]; 
CIImage *left = [gray imageByCroppingToRect:cropRectLeft]; 

CIFilter *cropFilter = [CIFilter filterWithName:@"CICrop"]; 

[cropFilter setValue:left forKey:@"inputImage"]; 
[cropFilter setValue:cropRect forKey:@"inputRectangle"]; 

// The sobel convoloution will produce an image that is 0.5,0.5,0.5,0.5 whereever the image is flat 
// On edges the image will contain values that deviate from that based on the strength and 
// direction of the edge 
const double g = 1.; 
const CGFloat weights[] = { 1*g, 0, -1*g, 
    2*g, 0, -2*g, 
    1*g, 0, -1*g}; 
left = [CIFilter filterWithName:@"CIConvolution3X3" keysAndValues: 
     @"inputImage", cropFilter.outputImage, 
     @"inputWeights", [CIVector vectorWithValues:weights count:9], 
     @"inputBias", @0.5, 
     nil].outputImage; 

#define VISUALHELP 1 
#if VISUALHELP 
CGImageRef imageRefLeft = [gcicontext createCGImage:left fromRect:cropRectLeft]; 
CGContextDrawImage(context, cropRectLeft, imageRefLeft); 
CGImageRelease(imageRefLeft); 
#endif 

Ora ogni volta 3x3 convoluzione non fa parte del ciimage conduttura la porzione dell'immagine corro rilevamento dei bordi sulla presenta grigi, ma ogni volta CIConvolution3X3 postfix fa parte della pipeline di elaborazione i colori appaiono magicamente indietro. Questo succede non importa se uso il prefisso CIColorMonochrome o CIPhotoEffectMono per rimuovere il colore. Qualche idea su come mantenere il colore fino in fondo alla pipeline? tnx

UPD: non sorprendentemente esecuzione un kernel monocromatico grezzo personalizzato come questo

kernel vec4 gray(sampler image) 
{ 
    vec4 s = sample(image, samplerCoord(image)); 
    float r = (s.r * .299 + s.g * .587 + s.b * 0.114) * s.a; 
    s = vec4(r, r, r, 1); 
    return s; 
} 

invece di utilizzare filtri mono standard da risultati mela esattamente nello stesso problema con il colore ritorno quando 3x3 convoluzione fa parte del mio ci pipeline

risposta

4

Questo problema è che le operazioni di convoluzione CI (ad esempio CIConvolution3X3, CIConvolution5X5 e CIGaussianBlur) operano su tutti e quattro i canali dell'immagine di input. Ciò significa che, nell'esempio di codice, il canale alfa risultante sarà 0,5 dove probabilmente si desidera che sia 1.0. Prova ad aggiungere un kernel semplice dopo la convoluzione per riportare l'alpha a 1.

+0

Sembra promettente. – Bobjt

2

followup: ho rinunciato a coreimage per questo compito. sembra che l'utilizzo di due istanze di CIFilter o CIKernel causi un conflitto. Qualcuno da qualche parte nelle viscere coreimage sembra manipolare lo stato gles in modo errato e, quindi, il reverse engineering ciò che è andato storto finisce più costoso dell'usare qualcosa di diverso dall'immagine core (con filtri ci personalizzati che funzionano solo su ios8) gpuimage non sembra così buggato e più facile da eseguire/eseguire il debug (nessuna affiliazione da parte mia)

+0

Sembra un bug grave. [Lo hai archiviato con Apple?] (Http://bugreport.apple.com) – rickster

+0

no. Non l'ho archiviato (ho 3 bug in là 2 dei quali sono prontamente ignorati da Apple). Sei il benvenuto a file. –