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,添加到 ...
随机推荐
- DM6437 dsp系列之启动过程全析(2)—AIS文件解析
本文均属自己阅读源码的点滴总结,转账请注明出处谢谢. 欢迎和大家交流.qq:1037701636 email: gzzaigcn2009@163.com,gzzaigcn2012@gmail.com ...
- hdu 4923 Room and Moor (单调栈+思维)
题意: 给一个0和1组成的序列a,要构造一个相同长度的序列b.b要满足非严格单调,且 值为0到1的实数.最后使得 sum((ai-bi)^2)最小. 算法: 首先a序列開始的连续0和末尾的连续1是能 ...
- [Elasticsearch] 部分匹配 (三) - 查询期间的即时搜索
本章翻译自Elasticsearch官方指南的Partial Matching一章. 查询期间的即时搜索(Query-time Search-as-you-type) 如今让我们来看看前缀匹配可以怎样 ...
- TNS-00512: Address already in use-TNS-12542: TNS:address already in use
监听启动或是停止时提示如下错误:TNS-12542: TNS:address already in use TNS-12560: TNS:protocol adapter error TNS-0051 ...
- plsql连接oracal数据库
一般只是作为客户端访问Oracle,并不需要安装庞大的Oracle 免安装客户端使用plsql连接oracal数据库 在本机没有安装oracle和oracle客户端的情况下,可以安装oracle提供的 ...
- java调试一
Eclipse 平台的特色在于内置了 Java 调试器,该调试器提供所有标准调试功能,包括进行单步执行.设置断点和值.检查变量和值以及暂挂和恢复线程的能力.Eclipse 平台工作台(Eclipse ...
- String 字符串相等比较
- PHP读取EXCEL时写入数据乱码解决办法
第一步排除excel读取的数据是不是乱码 EXCEL读取时经常会出现乱码,而我们常用的字符集是UTF-8 ,GB2312(GBK) ,这就需要对编码进行转换,但是又不能对纯数字和英文字符转换,否则会乱 ...
- TeamTalk自定义IM协议的理解
一.TeamTalk自定义IM协议 TeamTalk自定义IM协议是一种基于protocol buffer的消息传递协议,protocol buffer可以自定义消息格式.protocol buffe ...
- Java iText5.5.1 绘制PDF表格
iText下载链接:http://sourceforge.net/projects/itext/files/ 会有两个文件夹:extrajars中的extrajars-2.3.jar文件用于解决中文不 ...