图像处理之基础---彩色转灰度算法优化

File:      StudyRGB2Gray.txt
Name:      彩色转灰度算法彻底学习
Author:    zyl910
Version:   V1.0
Updata:    2006-5-22

一、基础

  对于彩色转灰度,有一个很著名的心理学公式:
Gray = R*0.299 + G*0.587 + B*0.114

二、整数算法

  而实际应用时,希望避免低速的浮点运算,所以需要整数算法。
  注意到系数都是3位精度的没有,我们可以将它们缩放1000倍来实现整数运算算法:
Gray = (R*299 + G*587 + B*114 + 500) / 1000

  RGB一般是8位精度,现在缩放1000倍,所以上面的运算是32位整型的运算。注意后面那个除法是整数除法,所以需要加上500来实现四舍五入。
  就是由于该算法需要32位运算,所以该公式的另一个变种很流行:
Gray = (R*30 + G*59 + B*11 + 50) / 100

  但是,虽说上一个公式是32位整数运算,但是根据80x86体系的整数乘除指令的特点,是可以用16位整数乘除指令来运算的。而且现在32位早普及了(AMD64都出来了),所以推荐使用上一个公式。

三、整数移位算法

  上面的整数算法已经很快了,但是有一点仍制约速度,就是最后的那个除法。移位比除法快多了,所以可以将系数缩放成 2的整数幂。
  习惯上使用16位精度,2的16次幂是65536,所以这样计算系数:
0.299 * 65536 = 19595.264 ≈ 19595
0.587 * 65536 + (0.264) = 38469.632 + 0.264 = 38469.896 ≈ 38469
0.114 * 65536 + (0.896) =  7471.104 + 0.896 = 7472

  可能很多人看见了,我所使用的舍入方式不是四舍五入。四舍五入会有较大的误差,应该将以前的计算结果的误差一起计算进去,舍入方式是去尾法:

  写成表达式是:
Gray = (R*19595 + G*38469 + B*7472) >> 16

  2至20位精度的系数:
Gray = (R*1 + G*2 + B*1) >> 2
Gray = (R*2 + G*5 + B*1) >> 3
Gray = (R*4 + G*10 + B*2) >> 4
Gray = (R*9 + G*19 + B*4) >> 5
Gray = (R*19 + G*37 + B*8) >> 6
Gray = (R*38 + G*75 + B*15) >> 7
Gray = (R*76 + G*150 + B*30) >> 8
Gray = (R*153 + G*300 + B*59) >> 9
Gray = (R*306 + G*601 + B*117) >> 10
Gray = (R*612 + G*1202 + B*234) >> 11
Gray = (R*1224 + G*2405 + B*467) >> 12
Gray = (R*2449 + G*4809 + B*934) >> 13
Gray = (R*4898 + G*9618 + B*1868) >> 14
Gray = (R*9797 + G*19235 + B*3736) >> 15
Gray = (R*19595 + G*38469 + B*7472) >> 16
Gray = (R*39190 + G*76939 + B*14943) >> 17
Gray = (R*78381 + G*153878 + B*29885) >> 18
Gray = (R*156762 + G*307757 + B*59769) >> 19
Gray = (R*313524 + G*615514 + B*119538) >> 20

  仔细观察上面的表格,这些精度实际上是一样的:3与4、7与8、10与11、13与14、19与20
  所以16位运算下最好的计算公式是使用7位精度,比先前那个系数缩放100倍的精度高,而且速度快:
Gray = (R*38 + G*75 + B*15) >> 7

  其实最有意思的还是那个2位精度的,完全可以移位优化:
Gray = (R + (WORD)G<<1 + B) >> 2

  由于误差很大,所以做图像处理绝不用该公式(最常用的是16位精度)。但对于游戏编程,场景经常变化,用户一般不可能观察到颜色的细微差别,所以最常用的是2位精度。

http://blog.csdn.net/zyl910/article/details/749752

http://bbs.csdn.net/topics/280041280

时间: 2024-12-17 00:05:31

图像处理之基础---彩色转灰度算法优化的相关文章

图像处理之基础---卷积及其快速算法的C++实现

头文件: /* * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected] * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation,

C#彩色图片灰度化算法实例

本文实例讲述了C#彩色图片灰度化实现方法.分享给大家供大家参考.具体方法如下: 主要功能代码如下: 代码如下: public static Bitmap MakeGrayscale(Bitmap original) { //create a blank bitmap the same size as original Bitmap newBitmap = new Bitmap(original.Width, original.Height); //get a graphics object fr

图像处理之基础---卷积,滤波,平滑

/*今天师弟来问我,CV的书里到处都是卷积,滤波,平滑……这些概念到底是什么意思,有什么区别和联系,瞬间晕菜了,学了这么久CV,卷积,滤波,平滑……这些概念每天都念叨好几遍,可是心里也就只明白个大概的意思,赶紧google之~ 发现自己以前了解的真的很不全面,在此做一些总结,以后对这种基本概念要深刻学习了~*/ 1.图像卷积(模板) (1).使用模板处理图像相关概念: 模板:矩阵方块,其数学含义是一种卷积运算. 卷积运算:可看作是加权求和的过程,使用到的图像区域中的每个像素分别于卷积核(权矩阵)

SQL Server 聚合函数算法优化技巧

Sql server聚合函数在实际工作中应对各种需求使用的还是很广泛的,对于聚合函数的优化自然也就成为了一个重点,一个程序优化的好不好直接决定了这个程序的声明周期.Sql server聚合函数对一组值执行计算并返回单一的值.聚合函数对一组值执行计算,并返回单个值.除了 COUNT 以外,聚合函数都会忽略空值. 聚合函数经常与 SELECT 语句的 GROUP BY 子句一起使用. v1.写在前面 如果有对Sql server聚合函数不熟或者忘记了的可以看我之前的一片博客.sql server 基

剪枝算法(算法优化)

一:剪枝策略的寻找的方法 1)微观方法:从问题本身出发,发现剪枝条件 2)宏观方法:从整体出发,发现剪枝条件. 3)注意提高效率,这是关键,最重要的. 总之,剪枝策略,属于算法优化范畴:通常应用在DFS 和 BFS 搜索算法中:剪枝策略就是寻找过滤条件,提前减少不必要的搜索路径. 二:剪枝算法(算法优化) 1.简介 在搜索算法中优化中,剪枝,就是通过某种判断,避免一些不必要的遍历过程,形象的说,就是剪去了搜索树中的某些"枝条",故称剪枝.应用剪枝优化的核心问题是设计剪枝判断方法,即确定

图像处理之基础---频域分析

1.频域值得坐标轴 1.在傅里叶变换中,低频主要决定图像在平滑区域中总体灰度级的现实,而高频决定图像细节部分,如边缘和噪声: 滤波器: 使低频通过而使高频衰减的滤波器称为“低通滤波器” 相反特性的滤波器 称为“高通滤波器” 被低通滤波的图像比原始图像少了一些尖锐的细节部分,因为高频部分已被衰减.同样,被高通滤波的图像在平滑区域 中将减少一些灰度 级的变化,并突出过渡(边缘)灰度级的细节.这样的图像将更为锐化 preference:http://www.cnblogs.com/itchq/p/38

差分进化算法优化集成参数

一.差分进化的思想 差分进化是在遗传算法的基础上发展而来的,与遗传算法相似,有变异.交叉.选择等操作,但是实现简单,收敛速度快.差分进化的过程是随机生成一个初始化群体,经过交叉.变异.选择三个操作,反复迭代,保留有用的个体,寻找最优解. 差分进化利用了贪婪的思想,在每一次的迭代中,保留最优解.通过当前种群个体跟经过交叉.变异后的个体以适应度值为标准,进行比较,保留最优的个体. (1)初始化 (2)变异 (3)交叉 (4)选择 其中,F是变异因子,用来控制两个随机个体差分向量的缩放程度.CR是交叉

性能优化——算法优化

背景 由于某种原因,我们系统需要记录另一个系统中一个表里的id.但是,当我们记录完了以后,别人系统可能会删除那个表里的一些数据,这样的话,我们这边就多了一些无效数据,所以,我们必须的找到这些无效的id,然后将其删除. 开始,我们的实现是这样:我们将记录下来的所有id放在一个list里,然后传到另一个系统,他将他们已经删除的id返回.具体处理代码如下: <pre name="code" class="java">public String findDele

温故知新,基础复习(快速排序及优化)

温故知新,基础复习(快速排序及优化) 使用了三值取中和插排优化 #include<stdio.h> #define InsertSortNumber 10 void InsertSort(int Arra[],unsigned int LowIndex,unsigned int HighIndex) { printf("low=%d,high=%d\n",LowIndex,HighIndex); for (unsigned int i = LowIndex + 1; i &