Skip to content

Commit

Permalink
Added binary opening and closing filters.
Browse files Browse the repository at this point in the history
  • Loading branch information
BradLarson committed Jun 3, 2012
1 parent d183c28 commit ba24e68
Showing 8 changed files with 156 additions and 1 deletion.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -168,6 +168,14 @@ Documentation is generated from header comments using appledoc. To build the doc
- **GPUImageCrosshairGenerator**: This draws a series of crosshairs on an image, most often used for identifying machine vision features. It does not take in a standard image like other filters, but a series of points in its -renderCrosshairsFromArray:count: method, which does the actual drawing. You will need to force this filter to render at the particular output size you need.
- *crosshairWidth*: The width, in pixels, of the crosshairs to be drawn onscreen.

- **GPUImageDilationFilter**: This performs an image dilation operation, where the maximum intensity of the red channel in a rectangular neighborhood is used for the intensity of this pixel. The radius of the rectangular area to sample over is specified on initialization, with a range of 1-4 pixels. This is intended for use with grayscale images, and it expands bright regions.

- **GPUImageErosionFilter**: This performs an image erosion operation, where the minimum intensity of the red channel in a rectangular neighborhood is used for the intensity of this pixel. The radius of the rectangular area to sample over is specified on initialization, with a range of 1-4 pixels. This is intended for use with grayscale images, and it expands dark regions.

- **GPUImageOpeningFilter**: This performs an erosion on the red channel of an image, followed by a dilation of the same radius. The radius is set on initialization, with a range of 1-4 pixels. This filters out smaller bright regions.

- **GPUImageClosingFilter**: This performs a dilation on the red channel of an image, followed by an erosion of the same radius. The radius is set on initialization, with a range of 1-4 pixels. This filters out smaller dark regions.

### Blending modes ###

- **GPUImageChromaKeyBlendFilter**: Selectively replaces a color in the first image with the second image
Original file line number Diff line number Diff line change
@@ -33,7 +33,21 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
[blackAndWhiteBoxImage processImage];
UIImage *dilationImage = [dilationFilter imageFromCurrentlyProcessedOutput];
[self saveImage:dilationImage fileName:@"Dilation4.png"];


GPUImageOpeningFilter *openingFilter = [[GPUImageOpeningFilter alloc] initWithRadius:4];
[blackAndWhiteBoxImage removeAllTargets];
[blackAndWhiteBoxImage addTarget:openingFilter];
[blackAndWhiteBoxImage processImage];
UIImage *openingImage = [openingFilter imageFromCurrentlyProcessedOutput];
[self saveImage:openingImage fileName:@"Opening4.png"];

GPUImageClosingFilter *closingFilter = [[GPUImageClosingFilter alloc] initWithRadius:4];
[blackAndWhiteBoxImage removeAllTargets];
[blackAndWhiteBoxImage addTarget:closingFilter];
[blackAndWhiteBoxImage processImage];
UIImage *closingImage = [closingFilter imageFromCurrentlyProcessedOutput];
[self saveImage:closingImage fileName:@"Closing4.png"];

return YES;
}

16 changes: 16 additions & 0 deletions framework/GPUImage.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
@@ -39,6 +39,10 @@
BC01E833155CA5E2004C75C3 /* GPUImage3x3TextureSamplingFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC01E831155CA5E1004C75C3 /* GPUImage3x3TextureSamplingFilter.m */; };
BC0690B8157C0C28009274F9 /* GPUImageTwoPassTextureSamplingFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0690B6157C0C27009274F9 /* GPUImageTwoPassTextureSamplingFilter.h */; };
BC0690B9157C0C28009274F9 /* GPUImageTwoPassTextureSamplingFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0690B7157C0C28009274F9 /* GPUImageTwoPassTextureSamplingFilter.m */; };
BC0690BD157C1B38009274F9 /* GPUImageOpeningFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0690BB157C1B37009274F9 /* GPUImageOpeningFilter.h */; };
BC0690BE157C1B38009274F9 /* GPUImageOpeningFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0690BC157C1B38009274F9 /* GPUImageOpeningFilter.m */; };
BC0690C1157C2368009274F9 /* GPUImageClosingFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BC0690BF157C2366009274F9 /* GPUImageClosingFilter.h */; };
BC0690C2157C2368009274F9 /* GPUImageClosingFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC0690C0157C2367009274F9 /* GPUImageClosingFilter.m */; };
BC114898155AF65400F107AF /* GPUImageTwoInputFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BC114896155AF65400F107AF /* GPUImageTwoInputFilter.h */; };
BC114899155AF65400F107AF /* GPUImageTwoInputFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC114897155AF65400F107AF /* GPUImageTwoInputFilter.m */; };
BC1A47F514FC759D00D552E8 /* GPUImageGaussianBlurFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D04CB7B14FB2A29001D6733 /* GPUImageGaussianBlurFilter.m */; };
@@ -273,6 +277,10 @@
BC01E831155CA5E1004C75C3 /* GPUImage3x3TextureSamplingFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImage3x3TextureSamplingFilter.m; path = Source/GPUImage3x3TextureSamplingFilter.m; sourceTree = SOURCE_ROOT; };
BC0690B6157C0C27009274F9 /* GPUImageTwoPassTextureSamplingFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageTwoPassTextureSamplingFilter.h; path = Source/GPUImageTwoPassTextureSamplingFilter.h; sourceTree = SOURCE_ROOT; };
BC0690B7157C0C28009274F9 /* GPUImageTwoPassTextureSamplingFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageTwoPassTextureSamplingFilter.m; path = Source/GPUImageTwoPassTextureSamplingFilter.m; sourceTree = SOURCE_ROOT; };
BC0690BB157C1B37009274F9 /* GPUImageOpeningFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageOpeningFilter.h; path = Source/GPUImageOpeningFilter.h; sourceTree = SOURCE_ROOT; };
BC0690BC157C1B38009274F9 /* GPUImageOpeningFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageOpeningFilter.m; path = Source/GPUImageOpeningFilter.m; sourceTree = SOURCE_ROOT; };
BC0690BF157C2366009274F9 /* GPUImageClosingFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageClosingFilter.h; path = Source/GPUImageClosingFilter.h; sourceTree = SOURCE_ROOT; };
BC0690C0157C2367009274F9 /* GPUImageClosingFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageClosingFilter.m; path = Source/GPUImageClosingFilter.m; sourceTree = SOURCE_ROOT; };
BC114896155AF65400F107AF /* GPUImageTwoInputFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageTwoInputFilter.h; path = Source/GPUImageTwoInputFilter.h; sourceTree = SOURCE_ROOT; };
BC114897155AF65400F107AF /* GPUImageTwoInputFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageTwoInputFilter.m; path = Source/GPUImageTwoInputFilter.m; sourceTree = SOURCE_ROOT; };
BC1B715514F49DAA00ACA2AB /* GPUImageRawDataOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageRawDataOutput.h; path = Source/GPUImageRawDataOutput.h; sourceTree = SOURCE_ROOT; };
@@ -749,6 +757,10 @@
BC56D849157ADA4F00CC9C1E /* GPUImageDilationFilter.m */,
BC56D84D157ADA6F00CC9C1E /* GPUImageErosionFilter.h */,
BC56D84E157ADA6F00CC9C1E /* GPUImageErosionFilter.m */,
BC0690BB157C1B37009274F9 /* GPUImageOpeningFilter.h */,
BC0690BC157C1B38009274F9 /* GPUImageOpeningFilter.m */,
BC0690BF157C2366009274F9 /* GPUImageClosingFilter.h */,
BC0690C0157C2367009274F9 /* GPUImageClosingFilter.m */,
);
name = "Image processing";
sourceTree = "<group>";
@@ -942,6 +954,8 @@
BC56D84A157ADA4F00CC9C1E /* GPUImageDilationFilter.h in Headers */,
BC56D84F157ADA6F00CC9C1E /* GPUImageErosionFilter.h in Headers */,
BC0690B8157C0C28009274F9 /* GPUImageTwoPassTextureSamplingFilter.h in Headers */,
BC0690BD157C1B38009274F9 /* GPUImageOpeningFilter.h in Headers */,
BC0690C1157C2368009274F9 /* GPUImageClosingFilter.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1158,6 +1172,8 @@
BC56D84B157ADA4F00CC9C1E /* GPUImageDilationFilter.m in Sources */,
BC56D850157ADA6F00CC9C1E /* GPUImageErosionFilter.m in Sources */,
BC0690B9157C0C28009274F9 /* GPUImageTwoPassTextureSamplingFilter.m in Sources */,
BC0690BE157C1B38009274F9 /* GPUImageOpeningFilter.m in Sources */,
BC0690C2157C2368009274F9 /* GPUImageClosingFilter.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
2 changes: 2 additions & 0 deletions framework/Source/GPUImage.h
Original file line number Diff line number Diff line change
@@ -94,3 +94,5 @@
#import "GPUImageShiTomasiFeatureDetectionFilter.h"
#import "GPUImageErosionFilter.h"
#import "GPUImageDilationFilter.h"
#import "GPUImageOpeningFilter.h"
#import "GPUImageClosingFilter.h"
17 changes: 17 additions & 0 deletions framework/Source/GPUImageClosingFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#import "GPUImageFilterGroup.h"

@class GPUImageErosionFilter;
@class GPUImageDilationFilter;

// A filter that first performs a dilation on the red channel of an image, followed by an erosion of the same radius.
// This helps to filter out smaller dark elements.

@interface GPUImageClosingFilter : GPUImageFilterGroup
{
GPUImageErosionFilter *erosionFilter;
GPUImageDilationFilter *dilationFilter;
}

- (id)initWithRadius:(NSUInteger)radius;

@end
41 changes: 41 additions & 0 deletions framework/Source/GPUImageClosingFilter.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#import "GPUImageClosingFilter.h"
#import "GPUImageErosionFilter.h"
#import "GPUImageDilationFilter.h"

@implementation GPUImageClosingFilter

- (id)init;
{
if (!(self = [self initWithRadius:1]))
{
return nil;
}

return self;
}

- (id)initWithRadius:(NSUInteger)radius;
{
if (!(self = [super init]))
{
return nil;
}

// First pass: dilation
dilationFilter = [[GPUImageDilationFilter alloc] initWithRadius:radius];
[self addFilter:dilationFilter];

// Second pass: erosion
erosionFilter = [[GPUImageErosionFilter alloc] initWithRadius:radius];
[self addFilter:erosionFilter];

[dilationFilter addTarget:erosionFilter];

self.initialFilters = [NSArray arrayWithObjects:dilationFilter, nil];
self.terminalFilter = erosionFilter;

return self;
}


@end
17 changes: 17 additions & 0 deletions framework/Source/GPUImageOpeningFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#import "GPUImageFilterGroup.h"

@class GPUImageErosionFilter;
@class GPUImageDilationFilter;

// A filter that first performs an erosion on the red channel of an image, followed by a dilation of the same radius.
// This helps to filter out smaller bright elements.

@interface GPUImageOpeningFilter : GPUImageFilterGroup
{
GPUImageErosionFilter *erosionFilter;
GPUImageDilationFilter *dilationFilter;
}

- (id)initWithRadius:(NSUInteger)radius;

@end
40 changes: 40 additions & 0 deletions framework/Source/GPUImageOpeningFilter.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#import "GPUImageOpeningFilter.h"
#import "GPUImageErosionFilter.h"
#import "GPUImageDilationFilter.h"

@implementation GPUImageOpeningFilter

- (id)init;
{
if (!(self = [self initWithRadius:1]))
{
return nil;
}

return self;
}

- (id)initWithRadius:(NSUInteger)radius;
{
if (!(self = [super init]))
{
return nil;
}

// First pass: erosion
erosionFilter = [[GPUImageErosionFilter alloc] initWithRadius:radius];
[self addFilter:erosionFilter];

// Second pass: dilation
dilationFilter = [[GPUImageDilationFilter alloc] initWithRadius:radius];
[self addFilter:dilationFilter];

[erosionFilter addTarget:dilationFilter];

self.initialFilters = [NSArray arrayWithObjects:erosionFilter, nil];
self.terminalFilter = dilationFilter;

return self;
}

@end

0 comments on commit ba24e68

Please sign in to comment.