CPUImageRGBFilter 实现
参考自: https://github.com/BradLarson/GPUImage
GPUImageRGBFilter: Adjusts the individual RGB channels of an image
- red: Normalized values by which each color channel is multiplied. The range is from 0.0 up, with 1.0 as the default.
- green:
- blue:
对应的Shader:
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp float redAdjustment;
uniform highp float greenAdjustment;
uniform highp float blueAdjustment;
void main()
{
highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
gl_FragColor = vec4(textureColor.r * redAdjustment, textureColor.g * greenAdjustment, textureColor.b * blueAdjustment, textureColor.a);
}
简单解释一下以上Shader.
uniform 声明为只读变量。
varying 声明为读写变量。
highp 为计算精度。这里为高精度。
textureCoordinate为对应的纹理坐标位置即(x,y)
inputImageTexture为输入的纹理图。
texture2D 取对应纹理图所在坐标的像素颜色。
所以整个算法很简单,就是将对应纹理图所在坐标的像素进行相应的 红绿蓝 权重调整。
权重的取值范围为[0,1]
根据以上Shader进行CPU代码转换。
#ifndef ClampToByte
#define ClampToByte(v)(((unsigned) int(v)) < (255) ? (v) : (v < 0) ? int(0) : int(255))
#endif
void CPUImageRGBFilter(unsigned char* Input, unsigned char* Output, int Width, int Height, int Stride, float redAdjustment = 1.0f, float greenAdjustment = 1.0f, float blueAdjustment = 1.0f)
{
int Channels = Stride / Width;
) return;
int numberOfPixels = Width*Height;
unsigned char* scanLineIn = Input;
unsigned char* scanLineOut = Output;
; pixel < numberOfPixels; pixel++) {
scanLineOut[] = ClampToByte(scanLineIn[] * redAdjustment);
scanLineOut[] = ClampToByte(scanLineIn[] * greenAdjustment);
scanLineOut[] = ClampToByte(scanLineIn[] * blueAdjustment);
scanLineIn += Channels;
scanLineOut += Channels;
}
}
转换后可进行建表优化。
即:
void CPUImageRGBFilter(unsigned char* Input, unsigned char* Output, int Width, int Height, int Stride, float redAdjustment = 1.0f, float greenAdjustment = 1.0f, float blueAdjustment = 1.0f)
{
int Channels = Stride / Width;
) return;
unsigned ] = { };
unsigned ] = { };
unsigned ] = { };
; pixel < ; pixel++)
{
AdjustMapR[pixel] = pixel*redAdjustment;
AdjustMapG[pixel] = pixel*greenAdjustment;
AdjustMapB[pixel] = pixel*blueAdjustment;
}
; Y < Height; Y++)
{
unsigned char* scanLineOut = Output + (Y * Stride);
unsigned char* scanLineIn = Input + (Y * Stride);
; X < Width; X++)
{
scanLineOut[] = AdjustMapR[scanLineIn[]];
scanLineOut[] = AdjustMapG[scanLineIn[]];
scanLineOut[] = AdjustMapB[scanLineIn[]];
scanLineIn += Channels;
scanLineOut += Channels;
}
}
}
代码比较简单,一看就明了。
待后续有时间,再通过simd指令集以及thread等方式进行改写。
CPUImageRGBFilter 实现的更多相关文章
- cpuimage 开源之
前年学习opengl做的一个小东西. 原本计划将gpuimage 的算法一个一个转写成cpu版本 c,c++ 版本. gpuimage 项目参考: https://github.com/BradLar ...
随机推荐
- ant使用
摘录于他人精华,原文出处http://www.blogjava.net/hoojo/archive/2013/06/14/400550.html 1.project 节点元素 project 元素是 ...
- Java 基础 程序流程控制 (下)
Java 程序流程控制 (下) 此篇单独对循环结构的知识点进行整理: 之前讲到循环结构分为:for循环,while循环,do...while循环三种最基本的循环结构:在JDK1.5以后的版本还提供了f ...
- Entity Framework入门教程:什么是Entity Framework
Entity Framework简介 Entity Framework是微软提供的一个O/RM(对象关系映射)框架.它基于ADO.NET,为开发人员提供了一种自动化的机制来访问和存储数据库中的数据. ...
- laravel如何向视图传递变量的方法
第一种: public function about(){ $name = "cai" return view("sites.about")->with( ...
- sql将一列数据拼成一个字符串的方法
SELECT STUFF(CONVERT(VARCHAR(500), ( SELECT TOP 10 ',' + BG_Country FROM dbo.BS_Budget FOR XML PATH( ...
- 手机app微信支付后台处理流程
第一步:客户在手机app确认订单,提交订单后,app将订单详情传给后台,后台将订单存入数据库,将存入数据库的id返回给app. 第二步:这时候手机端app会让客户选择哪种付款方式,我们做的是微信,所以 ...
- Linux 内核综述
一.什么是Linux内核: 内核->操作系统中最重要的部分,内核将在系统引导时被装载进RAM,其中包含了很多关键的例程,以操作系统.内核是OS最为关键的部分,人们常将OS(操作系统)与内核等同. ...
- 一个Ruby静态代码分析器 rubocop
A Ruby static code analyzer, based on the community Ruby style guide. http://rubocop.readthedocs.io ...
- JavaWeb 后端 <六> 之 EL & JSTL 学习笔记
一.EL表达式(特别重要)
- 推荐系统那点事 —— 基于Spark MLlib的特征选择
在机器学习中,一般都会按照下面几个步骤:特征提取.数据预处理.特征选择.模型训练.检验优化.那么特征的选择就很关键了,一般模型最后效果的好坏往往都是跟特征的选择有关系的,因为模型本身的参数并没有太多优 ...