zoukankan      html  css  js  c++  java
  • 最快的3x3中值模糊

    10.1国庆后,知名博主:laviewpbt  http://www.cnblogs.com/Imageshop/

    发起了一个优化3x3中值模糊的小活动。

    俺也参加其中,今天博主laviewpbt  共享了一份不错的CLAHE代码。

    free精神,真心为其点赞。

    故俺也分享这份最快的3x3中值模糊的代码。

    ///	编写者: laviewpbt,  编写时间: 2015.10.16, 联系QQ: 33184777
    
    /// <summary>
    /// 快速的实现3*3大小的中值模糊,边缘1像素未做处理。(2015.10.12日)
    /// </summary>
    /// <param name="Src">原始数据。</param>
    /// <param name="Dest">目标数据。</param>
    /// 百度: Fast median search_ an ANSI C implementation.html
    /// 优化版本: 落羽の殇  联系QQ:200759103
    
    static unsigned int*    pixGreater = NULL;
    static unsigned int*    pixLess = NULL;
    static unsigned int cmpTable[256 * 256 * 2] = { 0 };
    class  autoCmpTable
    {
    public:
    	autoCmpTable() {
    		unsigned int    x, y, p;
    		unsigned int tableLength = 256 * 256;
    		pixGreater = cmpTable;
    		pixLess = cmpTable + tableLength;
    		for (x = 0; x < 256; x++) {
    			for (y = 0; y < 256; y++) {
    				p = x + y * 256;
    				if (x > y)
    				{
    					pixLess[p] = x;
    					pixGreater[p] = y;
    				}
    				else
    				{
    					pixGreater[p] = x;
    					pixLess[p] = y;
    				}
    			}
    		}
    	}
    };
    static  autoCmpTable initCmpTable;
    
    IS_RET __stdcall Fastest33MedianBlur(TMatrix *Src, TMatrix *Dest)
    { 
    	if (Src == NULL || Dest == NULL) return IS_RET_ERR_NULLREFERENCE;
    	if (Src->Data == NULL || Dest->Data == NULL) return IS_RET_ERR_NULLREFERENCE;
    	if (Src->Width != Dest->Width || Src->Height != Dest->Height || Src->Channel != Dest->Channel || Src->Depth != Dest->Depth || Src->WidthStep != Dest->WidthStep) return IS_RET_ERR_PARAMISMATCH;
    	if (Src->Depth != IS_DEPTH_8U || Dest->Depth != IS_DEPTH_8U) return IS_RET_ERR_NOTSUPPORTED;
    	IS_RET Ret = IS_RET_OK;
    
    
    	if (!pixGreater&&!pixLess)
    	{
    		return IS_RET_ERR_NOTSUPPORTED;
    	}
    	if (Src->Data == Dest->Data)
    	{
    		TMatrix *Clone = NULL;
    		Ret = IS_CloneMatrix(Src, &Clone);
    		if (Ret != IS_RET_OK) return Ret;
    		Ret = Fastest33MedianBlur(Clone, Dest);
    		IS_FreeMatrix(&Clone);
    		return Ret;
    	}
    	unsigned int X, Y, Width = Src->Width, Height = Src->Height;
    	unsigned char *LineP0, *LineP1, *LineP2, *LinePD;
    	unsigned int srcWidthStep = Src->WidthStep;
    	unsigned int dstWidthStep = Dest->WidthStep;
    	unsigned int srcChannel = Src->Channel;
    	unsigned int dstChannel = Dest->Channel;
    	unsigned char* SrcData = Src->Data;
    	unsigned char* DstData = Dest->Data;
    
    	if (srcChannel == 1)
    	{
    		unsigned    int Gray0, Gray1, Gray2, Gray3, Gray4, Gray5, Gray6, Gray7, Gray8, pos;
    		for (Y = 1; Y < Height - 1; Y++)
    		{
    			LineP0 = SrcData + (Y - 1) * srcWidthStep + 1;
    			LineP1 = LineP0 + srcWidthStep;
    			LineP2 = LineP1 + srcWidthStep;
    			LinePD = DstData + Y *dstWidthStep + 1;
    			for (X = 1; X < Width - 1; X++)
    			{
    				Gray0 = LineP0[X - 1];
    				Gray1 = LineP0[X];
    				Gray2 = LineP0[X + 1];
    				Gray3 = LineP1[X - 1];
    				Gray4 = LineP1[X];
    				Gray5 = LineP2[X + 1];
    				Gray6 = LineP2[X - 1];
    				Gray7 = LineP2[X];
    				Gray8 = LineP2[X + 1];
    				/*    if (Gray1 > Gray2) Swap(Gray1, Gray2);*/
    				pos = Gray1 + Gray2 * 256;
    				Gray2 = pixLess[pos];
    				Gray1 = pixGreater[pos];
    				/* if (Gray4 > Gray5) Swap(Gray4, Gray5);*/
    				pos = Gray4 + Gray5 * 256;
    				Gray5 = pixLess[pos];
    				Gray4 = pixGreater[pos];
    				/* if (Gray7 > Gray8) Swap(Gray7, Gray8);*/
    				pos = Gray7 + Gray8 * 256;
    				Gray8 = pixLess[pos];
    				Gray7 = pixGreater[pos];
    				/*    if (Gray0 > Gray1) Swap(Gray0, Gray1);*/
    				pos = Gray0 + Gray1 * 256;
    				Gray1 = pixLess[pos];
    				Gray0 = pixGreater[pos];
    				/* if (Gray3 > Gray4) Swap(Gray3, Gray4);*/
    				pos = Gray3 + Gray4 * 256;
    				Gray4 = pixLess[pos];
    				Gray3 = pixGreater[pos];
    				/*    if (Gray6 > Gray7) Swap(Gray6, Gray7);*/
    				pos = Gray6 + Gray7 * 256;
    				Gray7 = pixLess[pos];
    				Gray6 = pixGreater[pos];
    				/* if (Gray1 > Gray2) Swap(Gray1, Gray2);*/
    				pos = Gray1 + Gray2 * 256;
    				Gray2 = pixLess[pos];
    				Gray1 = pixGreater[pos];
    				/* if (Gray4 > Gray5) Swap(Gray4, Gray5);*/
    				pos = Gray4 + Gray5 * 256;
    				Gray5 = pixLess[pos];
    				Gray4 = pixGreater[pos];
    				/* if (Gray7 > Gray8) Swap(Gray7, Gray8);*/
    				pos = Gray7 + Gray8 * 256;
    				Gray8 = pixLess[pos];
    				Gray7 = pixGreater[pos];
    				/* if (Gray0 > Gray3) Swap(Gray0, Gray3);*/
    				pos = Gray0 + Gray3 * 256;
    				Gray3 = pixLess[pos];
    				Gray0 = pixGreater[pos];
    				/* if (Gray5 > Gray8) Swap(Gray5, Gray8);*/
    				pos = Gray5 + Gray8 * 256;
    				Gray8 = pixLess[pos];
    				Gray5 = pixGreater[pos];
    				/*    if (Gray4 > Gray7) Swap(Gray4, Gray7);*/
    				pos = Gray4 + Gray7 * 256;
    				Gray7 = pixLess[pos];
    				Gray4 = pixGreater[pos];
    				/* if (Gray3 > Gray6) Swap(Gray3, Gray6);*/
    				pos = Gray3 + Gray6 * 256;
    				Gray6 = pixLess[pos];
    				Gray3 = pixGreater[pos];
    				/* if (Gray1 > Gray4) Swap(Gray1, Gray4);*/
    				pos = Gray1 + Gray4 * 256;
    				Gray4 = pixLess[pos];
    				Gray1 = pixGreater[pos];
    				/*    if (Gray2 > Gray5) Swap(Gray2, Gray5);*/
    				pos = Gray2 + Gray5 * 256;
    				Gray5 = pixLess[pos];
    				Gray2 = pixGreater[pos];
    				/*    if (Gray4 > Gray7) Swap(Gray4, Gray7);*/
    				pos = Gray4 + Gray7 * 256;
    				Gray7 = pixLess[pos];
    				Gray4 = pixGreater[pos];
    				/*    if (Gray4 > Gray2) Swap(Gray4, Gray2);*/
    				pos = Gray4 + Gray2 * 256;
    				Gray2 = pixLess[pos];
    				Gray4 = pixGreater[pos];
    				/* if (Gray6 > Gray4) Swap(Gray6, Gray4);*/
    				pos = Gray6 + Gray4 * 256;
    				Gray4 = pixLess[pos];
    				Gray6 = pixGreater[pos];
    				/*    if (Gray4 > Gray2) Swap(Gray4, Gray2); */
    				pos = Gray4 + Gray2 * 256;
    				Gray2 = pixLess[pos];
    				Gray4 = pixGreater[pos];
    
    				LinePD[1] = Gray4;
    				LinePD++;
    			}
    		}
    		return Ret;
    	}
    	else
    	{
    		TMatrix *Blue = NULL, *Green = NULL, *Red = NULL, *Alpha = NULL;     //    由于C变量如果不初始化,其值是随机值,可能会导致释放时的错误。
    		IS_RET Ret = SplitRGBA(Src, &Blue, &Green, &Red, &Alpha);
    		if (Ret != IS_RET_OK) goto Done24;
    #pragma omp parallel num_threads(3)  
    		{
    #pragma omp sections
       {
    #pragma omp section  
    	{
    		Ret = Fastest33MedianBlur(Blue, Blue);
    	}
    #pragma omp section  
    	{
    		Ret = Fastest33MedianBlur(Green, Green);
    	}
    #pragma omp section  
    	{
    		Ret = Fastest33MedianBlur(Red, Red);
    	}
    
       }
    		}
    		Ret = CombineRGBA(Dest, Blue, Green, Red, Alpha);
    	Done24:
    		IS_FreeMatrix(&Blue);
    		IS_FreeMatrix(&Green);
    		IS_FreeMatrix(&Red);
    		IS_FreeMatrix(&Alpha);
    		return Ret;
    	}
    
    	return Ret;
    }
    

      关于交换法短值快速排序的参考资料见:https://github.com/afniHQ/AFNI/blob/ab8ca253b784ae71401927df88da2bc6e16d07c1/src/cs_qsort_small.h

  • 相关阅读:
    关于如何实现NSNotificationCenter在不同的VC对象之间发送通知
    关于iOS如何实现一个单例
    C++中级-类模板
    C++中级-文件读写
    C++中级-多态
    C++中级-继承
    C++中级-friend关键字访问类中private
    C++中级-(静态成员和对象丶this指针丶常函数和对象、成员函数和对象)
    C++中级-(构造函数,拷贝构造函数,析构函数)
    C++中级-类的封装
  • 原文地址:https://www.cnblogs.com/cpuimage/p/4922032.html
Copyright © 2011-2022 走看看