c# 高斯模糊
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Diagnostics; namespace Adrian.PhotoX.Lib
{
[Serializable]
public enum BlurType
{
Both,
HorizontalOnly,
VerticalOnly,
} [Serializable]
public class GaussianBlur
{
private int _radius = ;
private int[] _kernel;
private int _kernelSum;
private int[,] _multable;
private BlurType _blurType; public GaussianBlur()
{
PreCalculateSomeStuff();
} public GaussianBlur(int radius)
{
_radius = radius;
PreCalculateSomeStuff();
} private void PreCalculateSomeStuff()
{
int sz = _radius * + ;
_kernel = new int[sz];
_multable = new int[sz, ];
for (int i = ; i <= _radius; i++)
{
int szi = _radius - i;
int szj = _radius + i;
_kernel[szj] = _kernel[szi] = (szi + ) * (szi + );
_kernelSum += (_kernel[szj] + _kernel[szi]);
for (int j = ; j < ; j++)
{
_multable[szj, j] = _multable[szi, j] = _kernel[szj] * j;
}
}
_kernel[_radius] = (_radius + ) * (_radius + );
_kernelSum += _kernel[_radius];
for (int j = ; j < ; j++)
{
_multable[_radius, j] = _kernel[_radius] * j;
}
} public long t1;
public long t2;
public long t3;
public long t4; public Bitmap ProcessImage(Image inputImage)
{
Bitmap origin = new Bitmap(inputImage);
Bitmap blurred = new Bitmap(inputImage.Width, inputImage.Height); using (RawBitmap src = new RawBitmap(origin))
{
using (RawBitmap dest = new RawBitmap(blurred))
{
int pixelCount = src.Width * src.Height;
//Stopwatch sw = new Stopwatch();
//sw.Start();
int[] b = new int[pixelCount];
int[] g = new int[pixelCount];
int[] r = new int[pixelCount]; int[] b2 = new int[pixelCount];
int[] g2 = new int[pixelCount];
int[] r2 = new int[pixelCount];
//sw.Stop();
//t1 = sw.ElapsedMilliseconds; int offset = src.GetOffset();
int index = ;
unsafe
{
//sw.Reset();
//sw.Start(); byte* ptr = src.Begin;
for (int i = ; i < src.Height; i++)
{
for (int j = ; j < src.Width; j++)
{
b[index] = *ptr;
ptr++;
g[index] = *ptr;
ptr++;
r[index] = *ptr;
ptr++; ++index;
}
ptr += offset;
} //sw.Stop();
//t2 = sw.ElapsedMilliseconds; int bsum;
int gsum;
int rsum;
int read;
int start = ;
index = ; //sw.Reset();
//sw.Start(); if (_blurType != BlurType.VerticalOnly)
{
for (int i = ; i < src.Height; i++)
{
for (int j = ; j < src.Width; j++)
{
bsum = gsum = rsum = ;
read = index - _radius; for (int z = ; z < _kernel.Length; z++)
{
//if (read >= start && read < start + src.Width)
//{
// bsum += _multable[z, b[read]];
// gsum += _multable[z, g[read]];
// rsum += _multable[z, r[read]];
// sum += _kernel[z];
//} if (read < start)
{
bsum += _multable[z, b[start]];
gsum += _multable[z, g[start]];
rsum += _multable[z, r[start]];
}
else if (read > start + src.Width - )
{
int idx = start + src.Width - ;
bsum += _multable[z, b[idx]];
gsum += _multable[z, g[idx]];
rsum += _multable[z, r[idx]];
}
else
{
bsum += _multable[z, b[read]];
gsum += _multable[z, g[read]];
rsum += _multable[z, r[read]];
}
++read;
} //b2[index] = (bsum / sum);
//g2[index] = (gsum / sum);
//r2[index] = (rsum / sum); b2[index] = (bsum / _kernelSum);
g2[index] = (gsum / _kernelSum);
r2[index] = (rsum / _kernelSum); if (_blurType == BlurType.HorizontalOnly)
{
//byte* pcell = dest[j, i];
//*pcell = (byte)(bsum / sum);
//pcell++;
//*pcell = (byte)(gsum / sum);
//pcell++;
//*pcell = (byte)(rsum / sum);
//pcell++; byte* pcell = dest[j, i];
*pcell = (byte)(bsum / _kernelSum);
pcell++;
*pcell = (byte)(gsum / _kernelSum);
pcell++;
*pcell = (byte)(rsum / _kernelSum);
pcell++;
} ++index;
}
start += src.Width;
}
}
if (_blurType == BlurType.HorizontalOnly)
{
return blurred;
} //sw.Stop();
//t3 = sw.ElapsedMilliseconds; //sw.Reset();
//sw.Start(); int tempy;
for (int i = ; i < src.Height; i++)
{
int y = i - _radius;
start = y * src.Width;
for (int j = ; j < src.Width; j++)
{
bsum = gsum = rsum = ;
read = start + j;
tempy = y;
for (int z = ; z < _kernel.Length; z++)
{
//if (tempy >= 0 && tempy < src.Height)
//{
// if (_blurType == BlurType.VerticalOnly)
// {
// bsum += _multable[z, b[read]];
// gsum += _multable[z, g[read]];
// rsum += _multable[z, r[read]];
// }
// else
// {
// bsum += _multable[z, b2[read]];
// gsum += _multable[z, g2[read]];
// rsum += _multable[z, r2[read]];
// }
// sum += _kernel[z];
//} if (_blurType == BlurType.VerticalOnly)
{
if (tempy < )
{
bsum += _multable[z, b[j]];
gsum += _multable[z, g[j]];
rsum += _multable[z, r[j]];
}
else if (tempy > src.Height - )
{
int idx = pixelCount - (src.Width - j);
bsum += _multable[z, b[idx]];
gsum += _multable[z, g[idx]];
rsum += _multable[z, r[idx]];
}
else
{
bsum += _multable[z, b[read]];
gsum += _multable[z, g[read]];
rsum += _multable[z, r[read]];
}
}
else
{
if (tempy < )
{
bsum += _multable[z, b2[j]];
gsum += _multable[z, g2[j]];
rsum += _multable[z, r2[j]];
}
else if (tempy > src.Height - )
{
int idx = pixelCount - (src.Width - j);
bsum += _multable[z, b2[idx]];
gsum += _multable[z, g2[idx]];
rsum += _multable[z, r2[idx]];
}
else
{
bsum += _multable[z, b2[read]];
gsum += _multable[z, g2[read]];
rsum += _multable[z, r2[read]];
}
} read += src.Width;
++tempy;
} byte* pcell = dest[j, i]; //pcell[0] = (byte)(bsum / sum);
//pcell[1] = (byte)(gsum / sum);
//pcell[2] = (byte)(rsum / sum); pcell[] = (byte)(bsum / _kernelSum);
pcell[] = (byte)(gsum / _kernelSum);
pcell[] = (byte)(rsum / _kernelSum);
}
}
//sw.Stop();
//t4 = sw.ElapsedMilliseconds;
}
}
} return blurred;
} public int Radius
{
get { return _radius; }
set
{
if (value < )
{
throw new InvalidOperationException("Radius must be greater then 0");
}
_radius = value; }
} public BlurType BlurType
{
get { return _blurType; }
set
{
_blurType = value;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging; namespace Adrian.PhotoX.Lib
{
public unsafe class RawBitmap : IDisposable
{
private Bitmap _originBitmap;
private BitmapData _bitmapData;
private byte* _begin; public RawBitmap(Bitmap originBitmap)
{
_originBitmap = originBitmap;
_bitmapData = _originBitmap.LockBits(new Rectangle(, , _originBitmap.Width, _originBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
_begin = (byte*)(void*)_bitmapData.Scan0;
} #region IDisposable Members public void Dispose()
{
_originBitmap.UnlockBits(_bitmapData);
} #endregion public unsafe byte* Begin
{
get { return _begin; }
} public unsafe byte* this[int x,int y]
{
get
{
return _begin + y * (_bitmapData.Stride) + x * ;
}
} public unsafe byte* this[int x, int y, int offset]
{
get
{
return _begin + y * (_bitmapData.Stride) + x * + offset;
}
} //public unsafe void SetColor(int x, int y, int color)
//{
// *(int*)(_begin + y * (_bitmapData.Stride) + x * 3) = color;
//} public int Stride
{
get { return _bitmapData.Stride; }
} public int Width
{
get { return _bitmapData.Width; }
} public int Height
{
get { return _bitmapData.Height; }
} public int GetOffset()
{
return _bitmapData.Stride - _bitmapData.Width * ;
} public Bitmap OriginBitmap
{
get { return _originBitmap; }
}
}
}
调用示例
Bitmap bitmap = new Bitmap(pictureBox1.Image);
//AForge.Imaging.Filters.GaussianBlur gs = new AForge.Imaging.Filters.GaussianBlur();
//AForge.Imaging.Filters.GaussianBlur filter = new AForge.Imaging.Filters.GaussianBlur(5, 15);
//filter.ApplyInPlace(bitmap);
GaussianBlur gs = new GaussianBlur();
pictureBox2.Image = gs.ProcessImage(bitmap);
c# 高斯模糊的更多相关文章
- Android开发学习之路-动态高斯模糊怎么做
什么是高斯模糊? 高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop.GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪 ...
- EasyPR--开发详解(3)高斯模糊、灰度化和Sobel算子
在上篇文章中我们了解了PlateLocate的过程中的所有步骤.在本篇文章中我们对前3个步骤,分别是高斯模糊.灰度化和Sobel算子进行分析. 一.高斯模糊 1.目标 对图像去噪,为边缘检测算法做准备 ...
- Android 图片滤镜工具——高斯模糊
===================高斯模糊========================= 创建一个 ImageFilter 类(滤镜工具),代码如下: import android.graph ...
- .net版高斯模糊算法
最近挺多人找高斯算法,本人贴上一个高斯模糊算法类,希望可以帮助到大家.算法的效率还是可以接受的. #region 高斯模糊算法 /// <summary> /// 高斯模糊算法 /// & ...
- 高斯模糊算法的 C++ 实现
2008 年在一个 PS 讨论群里,有网友不解 Photoshop 的高斯模糊中的半径是什么含义,因此当时我写了这篇文章: 对Photoshop高斯模糊滤镜的算法总结: 在那篇文章中,主要讲解了高斯模 ...
- Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途
Atitit Gaussian Blur 高斯模糊 的原理and实现and 用途 1.1. 高斯模糊 的原理(周边像素的平均值+正态分布的权重1 1.2. 高斯模糊 的用途(磨皮,毛玻璃效果,背景虚化 ...
- opencv 简单模糊和高斯模糊 cvSmooth
cv::Mat 是C++版OpenCV的新结构. cvSmooth() 是老版 C API. 没有把C接口与C + + 结合. 建议你们也可以花一些时间看一下介绍. 同样,你如果查看opencv/mo ...
- 半径无关单核单线程最快速高斯模糊实现(附完整C代码)
之前,俺也发过不少快速高斯模糊算法. 俺一般认为,只要处理一千六百万像素彩色图片,在2.2GHz的CPU上单核单线程超过1秒的算法,都是不快的. 之前发的几个算法,在俺2.2GHz的CPU上耗时都会超 ...
- 传统高斯模糊与优化算法(附完整C++代码)
高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop.GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次 ...
- iOS开发小技巧--高斯模糊框架的应用
事件背景:彩票项目中点击检查更新之后的操作,高斯模糊效果并弹出HUD 注意:在应用别人的框架的时候,最好封装一下下. 新建一个类 继承自高斯模糊的类. 使用方法:新建一个高斯模糊类的View,添加到 ...
随机推荐
- 浅谈NoSQL之MongoDB数据库
对于SQL数据库(关系型数据库)我们大家都有所了解,比如MySQL,sqlserver,oracle等数据库.在日常的开发过程中我们遇到服务器端的数据存储时几乎第一反应就是使用SQL据库像我们最常见的 ...
- Fabricate equation(dfs + 模拟)
Fabricate equation Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Other ...
- 行人检測之HOG特征(Histograms of Oriented Gradients)
之前的文章行人计数.计次提到HOG特征这个概念,这两天看了一下原版的论文,了解了一下HOG特征的原理,并依据自己的理解将这种方法的流程写了下来,假设有不正确的地方欢迎指正. HOG(Histogram ...
- LabView 下载与安装
labview2014是目前labview软件的最新版本,新版本增加了多个VI服务器对象,增加了多个vi脚本对象,增加了labview第三方许可和激活工具包,同时针对程序框图.编辑环境.应用程序生成器 ...
- scrapy使用crontab定时任务不能自动执行的调试
在用crontab进行定时任务时,发现任务并没有执行.而手动bash yourshell.sh时可以正常的执行程序.以下是个人的解决流程. 一.将错误打印打out.log */10 * * * * b ...
- Hacker(九)----黑客攻防前准备1
黑客在入侵Internet中其他电脑之前,需要做一系列准备工作,包括在电脑中安装虚拟机.准备常用的工具软件及掌握常用的攻击方法. 一.在计算机中搭建虚拟环境 无论时攻击还是训练,黑客都不会拿实体计算机 ...
- URI, URL, and URN
URI: uniform resource identifier,统一资源标识符,用来唯一的标识一个资源. URL: uniform resource locator,统一资源定位器,它是一种具体的U ...
- unity 打包 windows 运行 紫色 粉红色
unity下建立了个小demo,在editer里面运行正常.如下 但是一旦打包发布到android或者windows下就出现了类似这种情况 这种一般是由于材质贴图的缺失,一般来说选定的默认贴图的话会打 ...
- css样式书写顺序
这里推荐先写显示属性,再写自身属性,再写文字属性:并不代表非得按这个顺序写,但这种写法可以使css结构更清晰易读,修改起来比较方便. 而且在团队项目中能更好地提高效率. //显示属性 display ...
- web 前端 shopnc项目 首页分类一开始做前端,我是拒绝的
看图别说话 经过几小时的折腾 主要还是靠耐心