2013-04-24 84 views
1

我在iOS中繪製幾個灰度圖像。灰度圖像的值具有最小值和最大值,即對於範圍[41,244]中的8位值。如何在Core圖像中通過CIFilter更改最小值或最大值?

我想更改最小值或最大值。我想知道如何設置this list中的過濾器以更改最小值以及如何設置this list中的過濾器以更改最大值?

也許下面的繪圖將很好看:

[1。讀取原始灰度數據] - > [2。創建CGImageRef] - > [3。在GPU中加載參考]

現在,在iOS 6中可以實時應用GPU中的濾波器。對1或2進行操作對我來說非常緩慢,因爲在一秒鐘內我應該畫出100張圖像。所以我需要在GPU中使用CIFilter。我知道如何過濾圖像。但是什麼過濾器可以做我的工作?

一些示例代碼對我很有用。

回答

4

CIToneCurve應該適合這種事情。

- (UIImage*) applyToneCurveToImage:(UIImage*)image 
{ 
    CIContext* context = self.context; 
    CIImage* ciImage = [[CIImage alloc] initWithImage:image]; 

    CIFilter* filter = 
     [CIFilter filterWithName:@"CIToneCurve" 
        keysAndValues: 
       kCIInputImageKey, ciImage, 
        @"inputPoint0",[CIVector vectorWithX:0.00 Y:0.3] 
       ,@"inputPoint1",[CIVector vectorWithX:0.25 Y:0.4] 
       ,@"inputPoint2",[CIVector vectorWithX:0.50 Y:0.5] 
       ,@"inputPoint3",[CIVector vectorWithX:0.75 Y:0.6] 
       ,@"inputPoint4",[CIVector vectorWithX:1.00 Y:0.7] 
       ,nil]; 

    CIImage* result = [filter valueForKey:kCIOutputImageKey]; 

    CGImageRef cgImage = [context createCGImage:result 
              fromRect:[result extent]]; 
    UIImage* filteredImage = [UIImage imageWithCGImage:cgImage]; 
    CGImageRelease(cgImage); 
    return filteredImage; 
} 

self.context可以是CPU或GPU(EAGL)上下文。這些點描述了一條色調曲線。 X是輸入值,Y是輸出值。在這個例子中,我們正在減小斜率,從而降低對比度。您也可以保持斜率不變,但切斷極端值,以減少最大值和最小值。

以下是在iPad mini上處理100幅圖像的一些測量結果(平均每個設置有四個讀數)。你會發現GPU不是魔術,大約60-65%的時間只是運動圖像數據。這些示例以UIImage開始和結束。我用CGImage得到了非常相似的結果。

       57x57px png 640x800px jpeg 
UIImage->CIImage->UIImage (no filtering)  
         CPU 0.57s  2.83s 
         GPU 0.36s  2.83s  
UIImage->CIImage->CIFilter->UIImage 
         CPU 0.75s  4.38s  
         GPU 0.58s  4.32s  

更新

對於Window and Level調整與窗口範圍之外的輸入零個值,要實現這樣的事情:

enter image description here

CGFloat w; //window 
CGFloat l; //level 

       @"inputPoint0",[CIVector vectorWithX:0.0 Y:0.0] 
      ,@"inputPoint1",[CIVector vectorWithX:l-w/2 Y:0.0] 
      ,@"inputPoint2",[CIVector vectorWithX:l+w/2 Y:1.0] 
      ,@"inputPoint3",[CIVector vectorWithX:l+w/2 Y:0.0] 
      ,@"inputPoint4",[CIVector vectorWithX:1.0 Y:0.0] 

在實踐中這是行不通的。這些點描述了一條樣條曲線,它不能很好地適應方向的急劇變化,如b-c-d。 (同樣點c和d(2和3)不能共享相同的x值,因此在任何情況下,您都必須稍微增加以使dx = cx * 1.01)

如果您使用多點步篩選器。第一個過濾器使用CIToneCurve apprpriately(這是正確的窗口/級別算法,而不會試圖將您的最大級別降低到零)。

enter image description here

 CIFilter* filter = 
     [CIFilter filterWithName:@"CIToneCurve" 
        keysAndValues: 
       kCIInputImageKey, ciImage, 
       @"inputPoint0",[CIVector vectorWithX:0.0 Y:0.0] 
      ,@"inputPoint1",[CIVector vectorWithX:l-w/2 Y:0.0] 
      ,@"inputPoint2",[CIVector vectorWithX:l  Y:0.5] 
      ,@"inputPoint3",[CIVector vectorWithX:l+w/2 Y:1.0] 
      ,@"inputPoint4",[CIVector vectorWithX:1.0 Y:1.0] 

我們使過濾器的副本,我們將在最後一步再需要它:

 filter2 = [filter copy]; 

應用CIColorControls過濾器,以最大限度地提高結果的對比度和亮度

 filter = [CIFilter filterWithName:@"CIColorControls" 
          keysAndValues:kCIInputImageKey, 
        [filter valueForKey:kCIOutputImageKey], nil]; 

     [filter setValue:[NSNumber numberWithFloat:-1] 
        forKey:@"inputBrightness"]; 
     [filter setValue:[NSNumber numberWithFloat:4] 
        forKey:@"inputContrast"]; 

現在郵寄給1位調色板

 filter = [CIFilter filterWithName:@"CIColorPosterize" 
          keysAndValues:kCIInputImageKey, 
        [filter valueForKey:kCIOutputImageKey], nil]; 

     [filter setValue:@2 forKey:@"inputLevels"]; 

反轉結果

 filter = [CIFilter filterWithName:@"CIColorInvert" 
          keysAndValues:kCIInputImageKey, 
        [filter valueForKey:kCIOutputImageKey], nil]; 

現在我們用這個結果作爲與窗口/拉平圖像的面具,讓所有的M​​AX-白色水平得到降低到黑色。

 filter = [CIFilter filterWithName:@"CIDarkenBlendMode" 
          keysAndValues:kCIInputImageKey, 
        [ filter valueForKey:kCIOutputImageKey], nil]; 

     [filter setValue:[filter2 valueForKey:kCIOutputImageKey] 
        forKey:@"inputBackgroundImage"]; 

enter image description here

濾波器1 CIToneCurve

enter image description here

過濾器2 CIColorControls

enter image description here

過濾器3 CIColorPosterize

enter image description here

過濾器4 CIColorInvert

enter image description here

filter5 CIDarkenBlendMode

enter image description here

如果你看看Brad Larson的GPUImage,你會發現GPUImageLuminanceThresholdFilter會更好地代替2-> 5的過濾器。

+0

其實我想對灰色raw的每個值應用[線性公式](http://blogs.mathworks.com/steve/2006/02/17/all-about-pixel-colors-window-level)數據,當數值超出窗口時,我想將其設置爲零。所以輸入是窗口和水平值,輸出是計算值。你有沒有做過這樣的事情? – 2013-06-15 07:22:09

+0

@MilanoFili,看我更新的回答 – foundry 2013-06-15 22:45:54

+0

完美的例子和答案。謝謝。 – 2013-06-16 08:46:40

0

對於CIFilter中的每個影響,我們都有最小值和最大值。或者我們可以在代碼中修復這個值如果你想修復繪圖我們通過使用UISlider爲滑塊給定最小值和最大值作爲該過濾器的範圍,然後我們可以對該滑塊進行操作,因此當用戶移動時效果也會自動改變。

相關問題