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

AlphaBlending multiple images #1890

Open jdev7 opened 9 years ago

jdev7 commented 9 years ago

I'm using GPUImageHoughTransformLineDetector to detect edges of a document in an image. And a GPUImageLineGenerator to draw them over the image.

GPUImagePicture *picture = [[GPUImagePicture alloc]initWithImage:image];
GPUImageHoughTransformLineDetector *hough = [[GPUImageHoughTransformLineDetector alloc]init];
[hough setLineDetectionThreshold:threshold];
[hough setEdgeThreshold:0.9];
[picture addTarget:hough];

GPUImageLineGenerator *lineGenerator = [[GPUImageLineGenerator alloc] init];
[lineGenerator forceProcessingAtSize:CGSizeMake(480.0, 640.0)];
[lineGenerator setLineColorRed:1.0 green:0.0 blue:0.0];

[hough setLinesDetectedBlock:^(GLfloat* lineArray, NSUInteger linesDetected, CMTime frameTime) {
    [lineGenerator renderLinesFromArray:lineArray count:linesDetected frameTime:frameTime];
}];

GPUImageAlphaBlendFilter *blendFilter = [[GPUImageAlphaBlendFilter alloc] init];
[blendFilter forceProcessingAtSize:CGSizeMake(480.0, 640.0)];

GPUImageGammaFilter *gammaFilter = [[GPUImageGammaFilter alloc] init];
[picture addTarget:gammaFilter];
[gammaFilter addTarget:blendFilter];
[lineGenerator addTarget:blendFilter];
[blendFilter useNextFrameForImageCapture];
[picture processImage];

UIImage *result = [blendFilter imageFromCurrentFramebuffer];
return result;

This works fine and returns the image with the red lines overlayed.

Now I want to filter out those lines within the block call, and create a second array of filteredLines, and overlay them over the image with red lines, to visually see which lines are being discarded, but I don't seem to be able to do it.

I've tried creating a second GPUImageLineGenerator with the color lines set to blue, and rendering the filteredLines array and a second GPUImageAlphaBlendFilter to blend the output of the first blendFilter with the result of the second lineGenerator2 like this:

GPUImageAlphaBlendFilter *blendFilter = [[GPUImageAlphaBlendFilter alloc] init];
 [blendFilter forceProcessingAtSize:CGSizeMake(480.0, 640.0)];

GPUImageAlphaBlendFilter *blendFilter2 = [[GPUImageAlphaBlendFilter alloc] init];
[blendFilter2 forceProcessingAtSize:CGSizeMake(480.0, 640.0)];

GPUImageGammaFilter *gammaFilter = [[GPUImageGammaFilter alloc] init];
[picture addTarget:gammaFilter];
[gammaFilter addTarget:blendFilter];
[lineGenerator addTarget:blendFilter];

[blendFilter addTarget:blendFilter2];
[lineGenerator2 addTarget:blendFilter2];

[blendFilter useNextFrameForImageCapture];
[picture processImage];
 UIImage *result = [blendFilter imageFromCurrentFramebuffer];

But the best result I get is all the lines drawn in blue, so I can't compare them. How should I chain these filters??

Besides, I'm not sure if I'm properly understanding the way addTarget works to chain filters, so if there is any tutorial which would help me understand how GPUImage works, I would really appreciate it.

Thanks

BradLarson commented 9 years ago

If you need the image from the second blend filter, you need to capture from blendFilter2. You're only grabbing blendFilter in the above.

Also, are you updating lineGenerator and lineGenerator2 in your setLinesDetectedBlock? That will need to be done as well.

jdev7 commented 9 years ago

Thanks Brad, that is true. But I'm not sure how I should do it. Should it be something like?:

[blendFilter useNextFrameForImageCapture];
[blendFilter2 useNextFrameForImageCapture];
[picture processImage];
UIImage *result = [blendFilter2 imageFromCurrentFramebuffer];

Regarding to the lineGenerator, inside the block I have this two lines:

[lineGenerator renderLinesFromArray:lineArray count:linesDetected frameTime:frameTime];
[lineGenerator2 renderLinesFromArray:filteredLinesArray count:filteredLines frameTime:frameTime];

Is that what you meant? Btw, when I use the 2 lineGenerators, the first is set to paint red the unfiltered Lines, and the second to paint blue the filteredLines, but when it draws the lines, all are blue.