BradLarson / GPUImage

An open source iOS framework for GPU-based image and video processing
http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework
BSD 3-Clause "New" or "Revised" License
20.23k stars 4.61k forks source link

GPUImageToneCurveFilter not providing filtered/effected image #340

Open SrikanthKabadi opened 12 years ago

SrikanthKabadi commented 12 years ago

Hi. I am using GPUImageToneCurveFilter to add Curve tone for R, G and B. This is what I am doing, but I am not getting the filtered/effected image. The image remains original. Where am I going wrong?

#define ZeroToOneScale(x) x/255.0f

GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:mainImageView.image];
GPUImageToneCurveFilter *stillImageFilter = [[GPUImageToneCurveFilter alloc] init];

[stillImageSource addTarget:stillImageFilter];

[stillImageFilter setRedControlPoints:[NSArray arrayWithObjects:
                                      [NSValue valueWithCGPoint:CGPointMake(0.0, 0.0)],
                                      [NSValue valueWithCGPoint:CGPointMake(0.125, 0.25)],
                                      [NSValue valueWithCGPoint:CGPointMake(0.5, 0.5)],
                                      [NSValue valueWithCGPoint:CGPointMake(0.75, 0.675)],
                                      [NSValue valueWithCGPoint:CGPointMake(0.875, 0.75)],
                                      [NSValue valueWithCGPoint:CGPointMake(1.0, 1.0)],
                                      nil]];

[stillImageFilter setRedControlPoints:[NSArray arrayWithObjects:[NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(0), ZeroToOneScale(23))], [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(133), ZeroToOneScale(138))], [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(209), ZeroToOneScale(227))] , [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(254), ZeroToOneScale(227))], nil]];

[stillImageFilter setGreenControlPoints:[NSArray arrayWithObjects:[NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(0), ZeroToOneScale(59))], [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(33), ZeroToOneScale(59))], [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(166), ZeroToOneScale(170))] , [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(220), ZeroToOneScale(234))], [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(255), ZeroToOneScale(234))], nil]];

[stillImageFilter setBlueControlPoints:[NSArray arrayWithObjects:[NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(0), ZeroToOneScale(3))], [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(20), ZeroToOneScale(3))], [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(129), ZeroToOneScale(123))] , [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(189), ZeroToOneScale(216))], nil]];

[stillImageSource processImage];

[mainImageView setImage:[stillImageFilter imageFromCurrentlyProcessedOutput]];

But if I use this code to apply effect for Red, I get filtered/effected image.

[stillImageFilter setRedControlPoints:[NSArray arrayWithObjects:[NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(0), ZeroToOneScale(23))], [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(133), ZeroToOneScale(138))], [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(209), ZeroToOneScale(227))] , [NSValue valueWithCGPoint:CGPointMake(ZeroToOneScale(254), ZeroToOneScale(227))], nil]];
BradLarson commented 12 years ago

As you can tell from the many issues here about it, there are problems with the tone curve filter. I have some code that might fix some of this, but I'll only be able to look at it this weekend.

nostef commented 12 years ago

The image remains unchanged because the end points are not 1, specifically 255/255.

SrikanthKabadi commented 12 years ago

Actually the issue was with #define ZeroToOneScale(x) x/255.0f This returns the float value with more than 2 decimal points. Then manually converted to 2 decimal places and executed the same code. It worked. But I am not getting expected result. Program image Output differs from actual output from Adobe Photoshop.

SrikanthKabadi commented 12 years ago

@BradLarson Thank you so much.

nostef commented 12 years ago

The decimal points aren't an issue. I regularly send data as '(int between 0-255) / 255.0f) and it works fine. Something else must be the problem in your code. Specifically what for sure is a problem is that you didn't add the ending point.

The end point must be CGPointMake(1, (float between 0-1)).

nostef commented 12 years ago

Paste your code, your desired output and the GPUImage tone curve output.

SrikanthKabadi commented 12 years ago

@nostef This is my code.

GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:originalImage smoothlyScaleOutput:YES];
GPUImageToneCurveFilter *stillImageFilter = [[GPUImageToneCurveFilter alloc] init];
[stillImageSource addTarget:stillImageFilter];
[stillImageFilter setRedControlPoints:
 [NSArray arrayWithObjects: 
  [NSValue valueWithCGPoint:[self createPointArray:0 yvalue:23]],
  [NSValue valueWithCGPoint:[self createPointArray:113 yvalue:138]],
  [NSValue valueWithCGPoint:[self createPointArray:209 yvalue:227]],
  [NSValue valueWithCGPoint:[self createPointArray:254 yvalue:227]],
  nil]];

[stillImageFilter setGreenControlPoints:
 [NSArray arrayWithObjects: 
  [NSValue valueWithCGPoint:[self createPointArray:0 yvalue:59]],
  [NSValue valueWithCGPoint:[self createPointArray:33 yvalue:59]],
  [NSValue valueWithCGPoint:[self createPointArray:166 yvalue:170]],
  [NSValue valueWithCGPoint:[self createPointArray:222 yvalue:234]],
  [NSValue valueWithCGPoint:[self createPointArray:255 yvalue:234]],
  nil]];

[stillImageFilter setBlueControlPoints:
 [NSArray arrayWithObjects: 
  [NSValue valueWithCGPoint:[self createPointArray:0 yvalue:3]],
  [NSValue valueWithCGPoint:[self createPointArray:20 yvalue:3]],
  [NSValue valueWithCGPoint:[self createPointArray:129 yvalue:123]],
  [NSValue valueWithCGPoint:[self createPointArray:189 yvalue:216]],
  nil]];

[stillImageSource processImage];
[mainImageView setImage:[stillImageFilter imageFromCurrentlyProcessedOutput]];

[stillImageSource release];
[stillImageFilter release];

Desired output is http://dl.dropbox.com/u/14661827/For%20Test/Desired.png

GPUimage tone curve output is http://dl.dropbox.com/u/14661827/For%20Test/GPUImage%20output.png

nostef commented 12 years ago

Start by adding to both BlueControlPoints and RedControlPoints the last 255 x point.

eg: [stillImageFilter setBlueControlPoints: [NSArray arrayWithObjects: [NSValue valueWithCGPoint:[self createPointArray:0 yvalue:3]], [NSValue valueWithCGPoint:[self createPointArray:20 yvalue:3]], [NSValue valueWithCGPoint:[self createPointArray:129 yvalue:123]], [NSValue valueWithCGPoint:[self createPointArray:189 yvalue:216]], [NSValue valueWithCGPoint:[self createPointArray:255 yvalue:255]], nil]];

SrikanthKabadi commented 12 years ago

By doing this, its becoming much worse. You can see the result here. http://dl.dropbox.com/u/14661827/For%20Test/New%20Result.png