光线补偿算法的实现

最近扒拉了一些光线补偿算法的实现,可能是能力比较有限,看到的大多是是基于Face detection in color images是这篇论文的实现。
从效果上来看,的确起到了明亮、美白的效果。但是从代码本身来看,最终的结果只是分别对各通道进行一个有控制的伸展。只不过这个伸展的弹性是“自适应”的,这里我就疑问:这样就能够起到去除影音的效果了吗?还是所谓光线补偿并不是为了取得这样的一个效果。

#include "stdafx.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <stdio.h>
#include <io.h>
#include <iostream>
#include <stdio.h>
#include "GObeautifyhelper.h" //算法库
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <math.h>
#include <string>
#include <time.h>
using namespace cv;
using namespace std;

int main()
{
                Mat src = imread( "F:\\my\\head_src_2.jpg" );
                imshow( "原始图片" ,src);
                Mat dst=src.clone();
                 ////////////////////////////////////////////////////////////////////////// Face detection in color images
                 //////////////////////////////////////////////////////////////////////////根据高光区域直方图计算进行光线补偿
                 const float thresholdco = 0.05;
                 const int thresholdnum = 100;

                 int histogram[256] = {0};
                 for(int i=0;i<dst.rows;i++)
                {
                                 for(int j=0;j<dst.cols;j++)
                                {
                                                 int b = dst.at<Vec3b>(i,j)[0];
                                                 int g = dst.at<Vec3b>(i,j)[1];
                                                 int r = dst.at<Vec3b>(i,j)[2];
                                                 //计算灰度值
                                                 int gray = (r*299+g*587+b*114)/1000;
                                                histogram[gray]++;
                                }
                }

                 int calnum =0;
                 int total = dst.rows * dst.cols ;
                 int num;
                 //下面的循环得到满足系数thresholdco的临界灰度级
                 for(int i =0;i<256;i++)
                {
                                 if((float )calnum/total < thresholdco) //得到前5%的高亮像素。
                                {
                                                calnum+= histogram[255-i];//histogram保存的是某一灰度值的像素个数,calnum是边界灰度之上的像素数
                                                num = i;
                                }
                                 else
                                                 break;
                }
                 int averagegray = 0;
                calnum =0;
                 //得到满足条件的象素总的灰度值
                 for(int i = 255;i>=255-num;i--)
                {
                                averagegray += histogram[i]*i; //总的像素的个数*灰度值
                                calnum += histogram[i]; //总的像素数
                }
                averagegray /=calnum;
                 //得到光线补偿的系数
                 float co = 255.0/(float )averagegray;

                 for(int i=0;i<dst.rows;i++)
                {
                                 for(int j=0;j<dst.cols;j++)
                                {
                                    dst.at<Vec3b>(i,j)[0]= CLAMP0255(co*dst.at<Vec3b>(i,j)[0]+0.5);
                                                dst.at<Vec3b>(i,j)[1]=CLAMP0255(co*dst.at<Vec3b>(i,j)[1]+0.5);
                                                dst.at<Vec3b>(i,j)[2]=CLAMP0255(co*dst.at<Vec3b>(i,j)[2]+0.5);

                                }
                }
                imshow( "Face detection in color images" ,dst);

                cv::waitKey();
                 return 0;
}

  


中提到了这样一段


它的前半段看上去很像这种直方图的方法,但是后面一段非常NB地指出“模拟人视觉的视敏相应曲线”,并且给出了计算公式。所以这种方法最终也只是一种视网膜增强算法,当然它包含了将过大过小的区域进行压缩的部分。

时间: 2024-08-27 13:18:36

光线补偿算法的实现的相关文章

万年历算法的实现(C语言--gcc编译)

/** cal.c * * 现行的格里历是从儒略历演化而来的.儒略历每4年一个润年,润年366天,平年365天.* 如果从公元1年算的话,那么凡是能够被4整除的都是润年.从天文角度看,儒略历这种 * 历法是有误差的,到16世纪误差已经达到了10天.1582年,罗马教皇对儒略历进行了 * 一次校定,该年的10-5到10-14这10天被抹掉,并规定凡不能被400整除的世纪年不再 * 算为润年,校定之后的儒略历即为现行的格里历. * * 但是英国直到1752年才开始使用格里历,此时时间误差已经达到了1

搜索引擎--范例:中英文混杂分词算法的实现--正向最大匹配算法的原理和实现

纯中文和中英文混杂的唯一区别是,分词的时候你如何辨别一个字符是英文字符还是孩子字符, 人眼很容易区分,但是对于计算机来说就没那么容易了,只要能辨别出中文字符和英文的字符,分词本身就不是一个难题 1:文本的编码问题: utf8:windows下,以utf8格式保存的文本是一个3个字节(以16进制)的BOM的,并且你不知道一个汉字是否是用3位表示,但是英文适合ascii编码一样的 ascii:英文一位,中文两位,并且中文的第一个字节的值是大于128和,不会和英文混淆,推荐 unicode:中文基本是

探讨排序算法的实现

排序算法是我们工作中使用最普遍的算法,常见的语言库中基本都会有排序算法的实现,比如c标准库的qsort,stl的sort函数等.本文首先介绍直接插入排序,归并排序,堆排序,快速排序和基数排序等比较排序算法,然后介绍计数排序,基数排序等具有线性时间的排序算法.本文主要讨论算法的实现方法,并不会过多介绍基本理论. 评价一个排序算法优劣适用与否,一般需要从三个方面来分析 时间复杂度.用比较操作和移动操作数的最高次项表示,由于在实际应用中最在乎的是运行时间的上限,所以一般取输入最坏情况的下的运行时间作为

Bug2算法的实现(RobotBASIC环境中仿真)

移动机器人智能的一个重要标志就是自主导航,而实现机器人自主导航有个基本要求--避障.之前简单介绍过Bug避障算法,但仅仅了解大致理论而不亲自动手实现一遍很难有深刻的印象,只能说似懂非懂.我不是天才,不能看几遍就理解理论中的奥妙,只能在别人大谈XX理论XX算法的时候,自己一个人苦逼的面对错误的程序问为什么... 下面开始动手来实现一下简单的Bug2避障算法.由于算法中涉及到机器人与外界环境的交互,因此需要选择一个仿真软件.常用的移动机器人仿真软件主要有Gazebo.V-rep.Webots.MRD

软考笔记第六天之各排序算法的实现

对于前面的排序算法,用c#来实现 直接插入排序: 每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序.第一趟比较前两个数,然后把第二个数按大小插入到有序表中: 第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中:依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程.直接插入排序属于稳定的排序,最坏时间复杂性为O(n^2),空间复杂度为O(1).直接插入排序是由两层嵌套循环组成的.外层循环标识并决定待比较的数值.内层循环为待比较数值确定其最终位

图像旋转算法的实现

上一篇转载的文章(http://blog.csdn.net/carson2005/article/details/36900161)介绍了图像旋转的原理,这里给出代码实现,具体原理请参考上面的链接: 实现代码: void ImgRotate(cv::Mat imgIn, float theta, cv::Mat& imgOut) { int oldWidth = imgIn.cols; int oldHeight = imgIn.rows; // 源图四个角的坐标(以图像中心为坐标系原点) fl

Canny边缘检测算法的实现

Canny原理 Canny的原理就不细说了,冈萨雷斯的<数字图像处理>(第三版)P463~465讲解的比较清楚,主要就四个步骤: 1. 对图像进行高斯滤波 2. 计算梯度大小和梯度方向 3. 对梯度幅值图像进行非极大抑制 4. 双阈值处理和连接性分析(通常这一步与非极大抑制并行,详见下面的代码) 下面重点说一下非极大抑制. 非极大抑制 对一幅图像计算梯度大小和梯度方向后,需要进行非极大抑制,一般都是通过计算梯度方向,沿着梯度方向,判断该像素点的梯度大小是否是极大值.这里主要说一下方向的判断.

Python 排序算法的实现

冒泡排序: 1 def bubble(l): 2 length = len(l) 3 for i in range(length): 4 for j in range(i+1, length): 5 if l[i] > l[j]: 6 l[i], l[j] = l[j], l[i] 7 print l 选择排序: 1 def select(l): 2 length = len(l) 3 for i in range(length): 4 minn = i 5 for j in range(i+1

数组正负元素前后移动算法的实现(以0为分界线)

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump