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为例:



目录
相关文章
|
8月前
|
算法 计算机视觉 iOS开发
iOS 实时图像处理技术:使用 Core Image 和 Metal 进行高效滤镜应用
【4月更文挑战第8天】 在移动设备上实现高效的图像处理功能是现代应用程序开发中的一个关键需求。苹果的iOS平台提供了Core Image和Metal两大技术,它们为开发者提供了强大的工具来实现复杂的图像处理任务。本文将探讨如何使用Core Image进行基础图像处理,并结合Metal的性能优势,开发出一个自定义的实时图像滤镜。我们将通过创建一个能够动态调整参数并且具有实时反馈效果的滤镜来演示这一过程。
|
算法 iOS开发 计算机视觉
iOS 图像处理 + 人脸检测相关示例 🤖
Faceu脸萌一定是有一套自己的核心算法,所以它会说“有人模仿我的脸...” 最近在研究一些图像处理的技术,其中最常见的应用就要数 “Faceu 脸萌” 了,为了展示更清晰,我选择拆分功能的方式来实现 Demo。
194 0
iOS 图像处理 + 人脸检测相关示例 🤖
|
存储 缓存 数据可视化
Core Image:iOS图像处理技术追踪
Core Image是苹果官方提供的图像处理框架,通过丰富的built-in(内置)或自定义Filter(过滤器)高效处理静态图片、动态图片或视频。开发者还可以通过构造Filter链或自定义Core Image Kernel来实现更丰富的效果。 在WWDC20中,苹果官方针对Core Image技术在以下三方面做了优化:Core Image对视频/动图的支持、基于Metal构建Core Image (CI) Kernel以及Core Image的Debug支持。 这三方面会在下文逐一提到,文末笔者也会浅谈Core Image在手淘图片库中的应用可能以及对Core Image技术的展望。
1909 0
|
计算机视觉 iOS开发
|
计算机视觉 iOS开发
|
iOS开发 计算机视觉
|
算法 iOS开发 计算机视觉
IOS: Quartz2D图像处理
Quartz2D 图像处理   本文将为大家介绍常见的IOS图像处理操作包括以下四部分:旋转,缩放,裁剪以及像素和UIImage之间的转化,主要使用的知识是quartz2D。Quartz2D是CoreGraphics框架中的一个重要组成部分,可以完成几乎所有的2D图像绘制,处理功能。
968 0

热门文章

最新文章