原文:http://blog.csdn.net/zwlq1314521/article/details/50455782
滤镜有很多开源代码包,imageshop,tinyimage,还有安卓的源码包,看过安卓的源码包,感觉还有很大的提升空间.
http://blog.csdn.NET/jingwen3699/article/details/7770287 这个博客有介绍,看看你就知道,至少针对图像遍历像素有很多加速的方法可用.
列出我整理出的速度最快的几个,基于OpenCV
- /*adjust brightness and contract
- 查找表
- */
- void cast_LUT(const cv::Mat& src, cv::Mat& dst,unsigned char(&r_lookup)[256],unsigned char(&g_lookup)[256],
- unsigned char(&b_lookup)[256],IMAGE_CHANNELMODE mode)
- {
- uchar* srcData = src.data;
- if(dst.empty()){
- dst.create(src.size(),src.type());
- }
- uchar* dstData = dst.data;
- int size = src.rows * src.cols * 3;
- switch (mode){
- case IMAGE_CHANEL_RGB:
- {
- //经测试,这种遍历像素的方法时最快的,而且比较安全
- for (int i = 0; i < size-3; i+=3)
- {
- dstData[i] = b_lookup[srcData[i]];
- dstData[i+1] = g_lookup[srcData[i+1]];
- dstData[i+2] = r_lookup[srcData[i+2]];
- }
- break;
- }
- case IMAGE_CHANEL_B:
- {
- for (int i = 0; i < size-3; i+=3)
- {
- dstData[i] = b_lookup[srcData[i]];
- }
- break;
- }
- case IMAGE_CHANEL_G:
- {
- for (int i = 0; i < size-3; i+=3)
- {
- dstData[i] = g_lookup[srcData[i+1]];
- }
- break;
- }
- case IMAGE_CHANEL_R:
- {
- for (int i = 0; i < size-3; i+=3)
- {
- dstData[i] = r_lookup[srcData[i+2]];
- }
- break;
- }
- }
- }
- //这个是利用opencv里的LUT查找表来实现的亮度和对比度调节
- void adjustBrightContract(const cv::Mat &src, cv::Mat &dst, float brightFactor, float contractFactor)
- {
- IMAGE_ASSERT_VOID(brightFactor >= -1.0 && brightFactor <= 1.0);
- IMAGE_ASSERT_VOID(contractFactor >= -1.0 && contractFactor <= 1.0);
- float delta = 1 + brightFactor;
- float beta = 1 + contractFactor;
- cv::Mat lookup(1,256,CV_8UC1);
- uchar* pData = lookup.data;
- //生成查找表
- for(int i = 0;i < 256;i++)
- {
- pData[i] = cv::saturate_cast<uchar>(i * delta);//bright
- pData[i] = cv::saturate_cast<uchar>(thresholdc + (i - thresholdc) * beta);//contract
- }
- cv::LUT(src,lookup,dst);
- }
- //接下来时自动色阶的
- void adjustcolorLevel(cv::Mat& src,cv::Mat& dst,int blackThreshold,int whiteThreshold,float gamma,IMAGE_CHANNELMODE mode)
- {
- IMAGE_ASSERT_VOID(blackThreshold>= 0 && whiteThreshold>blackThreshold && whiteThreshold<=255);
- IMAGE_ASSERT_VOID(gamma >= 0.0 && gamma <= 10.0);
- unsigned char lookup[256];
- // cv::Mat lookup(1,256,CV_8UC1);
- uchar*pData = lookup;
- //smaller than blackThreshold will be set to 0
- for (int i = 0; i < blackThreshold; i ++)
- {
- pData[i] = 0;
- }
- //between using gamma correct
- float ig = (gamma == 0.0) ? 0.0 : 1 / gamma;
- float threshold = (float)(whiteThreshold - blackThreshold);
- for (int i = blackThreshold; i < whiteThreshold; i++)
- {
- pData[i] = cv::saturate_cast<uchar>( pow((i-blackThreshold)/threshold,ig)*255);
- }
- //big than whiteThreshold will be set to 255
- for (int i = whiteThreshold; i < 256; i++)
- {
- pData[i] = 255;
- }
- //自己写的LUT
- cast_LUT(src,dst,lookup,lookup,lookup,mode);
- //cv::LUT(src,lookup,dst);
- }