最快的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

时间: 2024-10-10 18:12:13

最快的3x3中值模糊的相关文章

OpenCV中值模糊方法

效果图 源码 KqwOpenCVBlurDemo 步骤 将获取到的Bitmap图片转成Mat对象 // Bitmap转为Mat Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4); Utils.bitmapToMat(bitmap, src); 调用OpenCV的中值模糊方法 // 中值模糊方法 Imgproc.medianBlur(src, src, 33); 将处理完的Mat数据转成Bitmap对象

Emgu-WPF学习使用-中值模糊

原文:Emgu-WPF学习使用-中值模糊 实现效果: 实现途径: 前提:Image File-> System.Drawing.Bitmap->Image<Bgr, byte> string sFile = GlobalVar.DATAS_PATH + "Samples/Test1.png"; BitmapImage oOriginBitSrc = new BitmapImage(new Uri(sFile)); System.Drawing.Image oIm

灰度图像--图像增强 中值滤波

学习DIP第32天 转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些论坛转载后,图像无法正常显示,无法正常表达本人观点,对此表示很不满意.有些网站转载了我的博文,很开心的是自己写的东西被更多人看到了,但不开心的是这段话被去掉了,也没标明转载来源,虽然这并没有版权保护,但感觉还是不太好,出于尊重文章作者的劳动,转载请标明出处!!!! 文章代码已托管,欢迎共同开发:https://github.com/Tony-Tan/DIPpro

中值滤波与图像锐化

本文主要包括以下内容 中值滤波及其改进算法 图像锐化, 包括梯度算子.拉普拉斯算子.高提升滤波和高斯-拉普拉斯变换 本章的典型囊例分析 对椒盐噪声的平滑效果比较 Laplacian与LoG算子的锐化效果比较 中值滤波 中值滤波本质上是一种统计排序滤波器. 对于原图像中某点(i,j), 中值滤波以该点为中 心的邻域内的所有像素的统计排序中值作为(i, j) 点的响应. 中值不同于均值, 是指排序队列中位于中间位置的元素的值,例如=采用3x3 中值滤披 器, 某点.(i,j) 的8 个邻域的一系列像

Atitit &#160;&#160;图像处理&#160;平滑&#160;也称&#160;模糊,&#160;归一化块滤波、高斯滤波、中值滤波、双边滤波)

Atitit   图像处理 平滑 也称 模糊, 归一化块滤波.高斯滤波.中值滤波.双边滤波) 是一项简单且使用频率很高的图像处理方法 用途 去噪 去雾 各种线性滤波器对图像进行平滑处理,相关OpenCV函数如下: 归一化块滤波器 (Normalized Box Filter) § 最简单的滤波器, 输出像素值是核窗口内像素值的 均值 ( 所有像素加权系数相等) § 高斯滤波器 (Gaussian Filter) § 最有用的滤波器 (尽管不是最快的). 高斯滤波是将输入数组的每一个像素点与 高斯

opencv3 图片模糊操作-均值滤波 高斯滤波 中值滤波 双边滤波

#include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; //均值滤波模糊处理int demo_blur(){ char win1[] = "window1"; char win2[] = "window2"; Mat img1, img2; img1 = imread("D://images//4.jpg&quo

均值滤波,中值滤波,最大最小值滤波

http://blog.csdn.net/fastbox/article/details/7984721 讨论如何使用卷积作为数学工具来处理图像,实现图像的滤波,其方法包含以下几种,均值 滤波,中值滤波,最大最小值滤波,关于什么是卷积以及理解卷积在图像处理中作用参见这 里–http://blog.csdn.net/jia20003/article/details/7038938 均值滤波: 均值滤波,是图像处理中最常用的手段,从频率域观点来看均值滤波是一种低通滤波器,高 频信号将会去掉,因此可以

中值滤波

中值滤波是一种典型的非线性滤波技术,在一定条件下可以克服线性滤波器(如均值滤波)带来的图像细节模糊. 优点:消除杂散噪声点而不会或较小程度地造成边缘模糊. 缺点:对于图像中含有较多点.线.尖角细节的,不适宜采用中值滤波. 基本思想:将模板(如方形.线形.十字形.菱形等)中的像素值从小到大排序,将中值代替模板中间的或者指定位置的像素值. 下面给出模板为3x3大小方形的中值滤波C++源代码: /**************中值滤波************** //Luma for( y = 1; y

图像平滑技术之盒滤波、均值滤波、中值滤波、高斯滤波、双边滤波的原理概要及OpenCV代码实现

图像平滑是指直接对源图像的每个像素数据做邻域运算以达到平滑图像的目的.实质上主要就是通达卷积核算子实现的,卷积核算子的相关知识大家可以参考我写的博文http://blog.csdn.net/wenhao_ir/article/details/51691410 图像平滑也称为模糊或滤波,是图像处理中常用的技术之一,进行平滑处理时需要用到滤波器核(其实就是卷积核算子),根据滤波器核函数来实现不同的滤波技术.下面介绍几种 常用的图像平滑方法的大概原理及OpenCV下的实现代码. 一.盒滤波(均值滤波)