`

iOS中的图像处理(二)——卷积运算

    博客分类:
  • IOS
iOS 
阅读更多

关于图像处理中的卷积运算,这里有两份简明扼要的介绍:文一文二

其中,可能的一种卷积运算代码如下:

- (UIImage*)applyConvolution:(NSArray*)kernel
{
	CGImageRef inImage = self.CGImage;
	CFDataRef m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage));  
	CFDataRef m_OutDataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage));  
	UInt8 * m_PixelBuf = (UInt8 *) CFDataGetBytePtr(m_DataRef);  
	UInt8 * m_OutPixelBuf = (UInt8 *) CFDataGetBytePtr(m_OutDataRef);  
	
	int h = CGImageGetHeight(inImage);
	int w = CGImageGetWidth(inImage);
	
	int kh = [kernel count] / 2;
	int kw = [[kernel objectAtIndex:0] count] / 2;
	int i = 0, j = 0, n = 0, m = 0;
	
	for (i = 0; i < h; i++) {
		for (j = 0; j < w; j++) {
			int outIndex = (i*w*4) + (j*4);
			double r = 0, g = 0, b = 0;
			for (n = -kh; n <= kh; n++) {
				for (m = -kw; m <= kw; m++) {
					if (i + n >= 0 && i + n < h) {
						if (j + m >= 0 && j + m < w) {
							double f = [[[kernel objectAtIndex:(n + kh)] objectAtIndex:(m + kw)] doubleValue];
							if (f == 0) {continue;}
							int inIndex = ((i+n)*w*4) + ((j+m)*4);
							r += m_PixelBuf[inIndex] * f;
							g += m_PixelBuf[inIndex + 1] * f;
							b += m_PixelBuf[inIndex + 2] * f;
						}
					}
				}
			}
			m_OutPixelBuf[outIndex]     = SAFECOLOR((int)r);
			m_OutPixelBuf[outIndex + 1] = SAFECOLOR((int)g);
			m_OutPixelBuf[outIndex + 2] = SAFECOLOR((int)b);
			m_OutPixelBuf[outIndex + 3] = 255;
		}
	}
	
	CGContextRef ctx = CGBitmapContextCreate(m_OutPixelBuf,
											 CGImageGetWidth(inImage),
											 CGImageGetHeight(inImage),
											 CGImageGetBitsPerComponent(inImage),
											 CGImageGetBytesPerRow(inImage),
											 CGImageGetColorSpace(inImage),
											 CGImageGetBitmapInfo(inImage)
											 );
	
	CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
	CGContextRelease(ctx);
	UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
	CGImageRelease(imageRef);
	CFRelease(m_DataRef);
    CFRelease(m_OutDataRef);
    
	return finalImage;
}

方法的参数kernel是卷积运算中的卷积核,下面是几种滤镜的卷积核:

#pragma mark - 
#pragma mark - Basic Convolutions

/* Reference : 
 * http://docs.gimp.org/en/plug-in-convmatrix.html 
 */

- (UIImage *)sharpen
{
//	double dKernel[5][5] = {
//		{0,  0.0, -1.0,  0.0, 0},
//		{0, -1.0,  5.0, -1.0, 0},
//		{0,  0.0, -1.0,  0.0, 0}
//    };
    
    double dKernel[5][5] = { 
		{0, 0.0, -0.2,  0.0, 0},
		{0, -0.2, 1.8, -0.2, 0},
		{0, 0.0, -0.2,  0.0, 0}
    };
    
	NSMutableArray *kernel = [[[NSMutableArray alloc] initWithCapacity:5] autorelease];
	for (int i = 0; i < 5; i++) {
		NSMutableArray *row = [[[NSMutableArray alloc] initWithCapacity:5] autorelease];
		for (int j = 0; j < 5; j++) {
			[row addObject:[NSNumber numberWithDouble:dKernel[i][j]]];
		}
		[kernel addObject:row];
	}
	return [self applyConvolution:kernel];
}

- (UIImage *)edgeEnhance
{
	double dKernel[5][5] = {
		{0,  0.0,  0.0,  0.0, 0},
		{0, -1.0,  1.0,  0.0, 0},
		{0,  0.0,  0.0,  0.0, 0}
    };
    
	NSMutableArray *kernel = [[[NSMutableArray alloc] initWithCapacity:5] autorelease];
	for (int i = 0; i < 5; i++) {
		NSMutableArray *row = [[[NSMutableArray alloc] initWithCapacity:5] autorelease];
		for (int j = 0; j < 5; j++) {
			[row addObject:[NSNumber numberWithDouble:dKernel[i][j]]];
		}
		[kernel addObject:row];
	}
    
	return [self applyConvolution:kernel];
}

- (UIImage *)edgeDetect
{
	double dKernel[5][5] = {
		{0,  0.0,  1.0,  0.0, 0},
		{0,  1.0, -4.0,  1.0, 0},
		{0,  0.0,  1.0,  0.0, 0}
    };
    
	NSMutableArray *kernel = [[[NSMutableArray alloc] initWithCapacity:5] autorelease];
	for (int i = 0; i < 5; i++) {
		NSMutableArray *row = [[[NSMutableArray alloc] initWithCapacity:5] autorelease];
		for (int j = 0; j < 5; j++) {
			[row addObject:[NSNumber numberWithDouble:dKernel[i][j]]];
		}
		[kernel addObject:row];
	}
    
	return [self applyConvolution:kernel];
}

- (UIImage *)emboss
{
	double dKernel[5][5] = {
		{0, -2.0, -1.0,  0.0, 0},
		{0, -1.0,  1.0,  1.0, 0},
		{0,  0.0,  1.0,  2.0, 0}
    };
    
	NSMutableArray *kernel = [[[NSMutableArray alloc] initWithCapacity:5] autorelease];
	for (int i = 0; i < 5; i++) {
		NSMutableArray *row = [[[NSMutableArray alloc] initWithCapacity:5] autorelease];
		for (int j = 0; j < 5; j++) {
			[row addObject:[NSNumber numberWithDouble:dKernel[i][j]]];
		}
		[kernel addObject:row];
	}
    
	return [self applyConvolution:kernel];
}

在此基础上,我Google了下Photoshop中对照片进行黑白处理的简单步骤:

  1. 去色
  2. 调整对比度
  3. 高斯模糊
  4. 浮雕效果
  5. 边缘检测
  6. 调整对比度
  7. 调整亮度
  8. 反相

我按步骤实现了相应代码:

return [[[[[[[[originImage desaturate]
                          changeContrastByFactor:1.5]
                         gaussianBlur:1.3] emboss]
                       edgeDetect]
                      changeContrastByFactor:1.5]
                     changeBrightnessByFactor:1.5]
                    invert];

可惜效果有点粗糙,照片仍旧以 上一篇文章中的Andy为例:



更多详细信息请查看java教程网 http://www.itchm.com/forum-59-1.html
分享到:
评论

相关推荐

    设置图片的模糊

    在图像处理中,卷积是一种将输入图像与一个滤波器(或称核)进行运算的过程,滤波器的权重由高斯函数给出。高斯函数是一种连续的概率密度函数,形状类似钟形曲线,具有对称性,其标准差决定了模糊的程度。 在iOS...

    ConvolutionExplorer:Swift 中的 vImage Accelerate 卷积过滤器

    在 iOS 和 macOS 开发中,Apple 提供了一个强大的底层框架——Accelerate,它包括了 vImage 模块,专门用于执行高效的图像处理任务,如卷积操作。本项目“ConvolutionExplorer”是一个 Swift 应用,旨在演示如何利用...

    Opencv Tutorial

    离散傅立叶变换是一种重要的数学工具,在图像处理和信号处理中有着广泛的应用。本章详细介绍了如何使用 OpenCV 实现离散傅立叶变换及其逆变换。 **2.9 使用 XML 和 YAML 文件进行文件输入输出** OpenCV 提供了读写...

    opencv_tutorials

    ### OpenCV Tutorials知识点概述 #### 一、OpenCV简介与安装 **1.1 安装在Linux系统上** - **环境准备:** ...以上内容覆盖了OpenCV的核心功能和图像处理模块中的主要知识点,希望对学习OpenCV有所帮助。

    opencv_tutorials2.4.3

    - **编写代码**:利用 OpenCV 的功能进行 iOS 图像处理应用开发。 #### 二、核心模块——基础功能 ##### 2.1 Mat 类——基本图像容器 - **Mat 类介绍**:存储图像数据的基本类。 - **创建 Mat 对象**:通过构造函数...

Global site tag (gtag.js) - Google Analytics