C#神经网络编程
作者:Matt R. Cole
出版社:机械工业出版社
ISBN:9787111629382
VIP会员免费
(仅需0.8元/天)
¥ 45.0
温馨提示: 价值40000元的1000本电子书,VIP会员随意看哦!
电子书推荐
-
C#数字图像处理算法典型实例-pdf(高清)+代码 评分:
C#数字图像处理算法典型实例 赵春江- pdf(买书送的扫描版,比盗版的书清晰)+代码
上传时间:2017-11 大小:69.31MB
- 18.31MB
C#数字图像处理算法典型实例(赵春江)光盘内容
2014-06-13C#数字图像处理算法典型实例(赵春江)光盘内容,非常完整,代码有助学习
- 1.94MB
C#数字图像处理算法典型实例
2019-04-18C#数字图像处理算法典型实例,提供大家学习参考,有不会的可以私信我,没有积分下载的也可以私信我要资源
- 132.42MB
C#数字图像处理算法典型实例.iso
2019-09-24C#数字图像处理算法典型实例随书光盘 精选数字图像处理领域中的一些应用实例,以理论和实践相结合的方式,系统地介绍了如何使用C#进行数字图像处理。 C#数字图像处理算法典型实例共11章,分别讲述了图像的点运算、几何运算、数学形态学图像处理方法、频率变换、图像平滑与去噪、边缘检测、图像分割、图像压缩编码和彩色图像处理等相关技术。本书的光盘中附有相关章节的实现代码,可供广大的读者参考、阅读。 C#数字图像处理算法典型实例内容丰富,叙述详细,实用性强,适合于数字图像处理工作者阅读参考。 C#数字图像处理算法典型实例目录: 第1章 绪论 1.1 数字图像处理概述 1.2 C#概述 1.2.1 C#特点 1.2.2 WinForm编程 1.2.3 GDI+ 1.3 补充说明 第2章 C#数字图像处理的3种方法 2.1 C#图像处理基础 2.1.1 Bitmap类 2.1.2 BitmapData类 2.1.3 Graphics类 2.2 彩色图像灰度化 2.3 彩色图像灰度化编程实例 2.3.1 使用图像 2.3.2 图像处理的3种方法 2.4 小结 第3章 点运算及直方图 3.1 灰度直方图 3.1.1 灰度直方图定义 3.1.2 灰度直方图编程实例 3.2 线性点运算 3.2.1 线性点运算定义 3.2.2 线性点运算编程实例 3.3 全等级直方图灰度拉伸 3.3.1 灰度拉伸定义 3.3.2 灰度拉伸编程实例 3.4 直方图均衡化 3.4.1 直方图均衡化定义 3.4.2 直方图均衡化编程实例 3.5 直方图匹配 3.5.1 直方图匹配定义 3.5.2 直方图匹配编程实例 3.6 小结 第4章 几何运算 4.1 图像平移 4.1.1 图像平移定义 4.1.2 图像平移编程实例 4.2 图像镜像 4.2.1 图像镜像变换定义 4.2.2 图像镜像编程实现 4.3 图像缩放 4.3.1 图像缩放定义 4.3.2 灰度插值法 4.3.3 图像缩放编程实例 4.4 图像旋转 4.4.1 图像旋转定义 4.4.2 图像旋转编程实现 4.5 小结 第5章 数学形态学图像处理 5.1 图像腐蚀运算 5.1.1 图像腐蚀运算定义 5.1.2 图像腐蚀运算编程实例 5.2 图像膨胀运算 5.2.1 图像膨胀运算定义 5.2.2 图像膨胀运算编程实例 5.3 图像开运算与闭运算 5.3.1 图像开运算与闭运算定义 5.3.2 图像开运算编程实例 5.3.3 图像闭运算编程实例 5.4 击中击不中变换 5.4.1 击中击不中变换定义 5.4.2 击中击不中变换编程实例 5.5 小结 第6章 频率变换 6.1 二维离散傅里叶变换 6.2 快速傅里叶变换 6.2.1 快速傅里叶变换概述 6.2.2 快速傅里叶变换编程实例 6.3 幅度图像和相位图像 6.4 频率成分滤波 6.4.1 频率成分滤波原理 6.4.2 频率成分滤波编程实例 6.5 频率方位滤波 6.5.1 频率方位滤波原理 6.5.2 频率方位滤波编程实例 6.6 小结 第7章 图像平滑与去噪 7.1 噪声模型 7.1.1 噪声概述 7.1.2 噪声模型编程实例 7.2 均值滤波与中值滤波 7.2.1 均值滤波与中值滤波原理 7.2.2 均值滤波与中值滤波编程实例 7.3 灰度形态学滤波 7.3.1 灰度形态学原理 7.3.2 灰度形态学去噪原理 7.3.3 灰度形态学去噪编程实现 7.4 小波变换去噪 7.4.1 小波变换概述 7.4.2 小波变换去噪原理 7.4.3 小波变换去噪编程实例 7.5 高斯低通滤波 7.5.1 高斯低通滤波原理 7.5.2 高斯低通滤波编程实例 7.6 统计滤波 7.6.1 统计滤波原理 7.6.2 统计滤波编程实例 7.7 小结 第8章 边缘检测 8.1 模板算子法 8.1.1 模板算子法原理 8.1.2 模板算子法编程实例 8.2 高斯算子 8.2.1 高斯算子原理 8.2.2 高斯算子编程实例 8.3 Canny算子 8.3.1 Canny边缘检测原理 8.3.2 Canny算子编程实例 8.4 形态学边缘检测 8.4.1 形态学边缘检测原理 8.4.2 形态学边缘检测编程实例 8.5 小波变换边缘检测 8.5.1 小波变换边缘检测原理 8.5.2 小波变换边缘检测编程实例 8.6 金字塔方法 8.6.1 金字塔方法原理 8.6.2 金字塔方法编程实例 8.7 小结 第9章 图像分割 9.1 Hough变换 9.1.1 Hough变换原理 9.1.2 Hough变换编程实例 9.2 阈值法 9.2.1 自动阈值选择法原理 9.2.2 阈值分割法编程实例 9.3 特征空间聚类法 9.3.1 K-均值聚类法原理 9.3.2 ISODATA聚类法原理 9.3.3 特征空间聚类法编程实例 9.4 松弛迭代法 9.4.1 松弛迭代法原理 9.4.2 松弛迭代法编程实例 9.5 小结 第10章 图像压缩编码 10.1 哈夫曼编码 10.1.1 哈夫曼编码原理 10.1.2 哈夫曼编码编程实例 10.2 香农编码 10.2.1 香农编码原理 10.2.2 香农编码编程实例 10.3 香农-弗诺编码 10.3.1 香农-弗诺编码原理 10.3.2 香农-弗诺编码编程实例 10.4 行程编码 10.4.1 行程编码原理 10.4.2 行程编码编程实例 10.5 LZW编码 10.5.1 LZW编码原理 10.5.2 LZW编码编程实例 10.6 预测编码 10.6.1 DPCM原理 10.6.2 预测编码编程实例 10.7 傅里叶变换编码 10.7.1 傅里叶变换编码原理 10.7.2 傅里叶变换编码编程实例 10.8 小波变换编码 10.8.1 小波变换编码原理 10.8.2 小波变换编码编程实例 10.9 小结 第11章 彩色图像处理 11.1 彩色空间 11.1.1 RGB彩色空间和HSI彩色空间 11.1.2 彩色空间转换编程实例 11.1.3 彩色空间分量调整编程实例 11.2 伪彩色处理 11.2.1 伪彩色处理原理 11.2.2 伪彩色处理编程实例 11.3 彩色图像直方图均衡化 11.3.1 彩色图像直方图均衡化原理 11.3.2 彩色图像直方图均衡化编程实例 11.4 彩色图像平滑处理 11.4.1 彩色图像平滑处理原理 11.4.2 彩色图像平滑处理编程实例 11.5 彩色图像锐化处理 11.5.1 彩色图像锐化处理原理 11.5.2 彩色图像锐化处理编程实例 11.6 彩色图像边缘检测 11.6.1 彩色图像边缘检测原理 11.6.2 彩色图像边缘检测编程实例 11.7 彩色图像分割 11.7.1 彩色图像分割原理 11.7.2 彩色图像分割编程实例 11.8 小结
- 69.93MB
C#语言【数字图像处理算法典型实例】PDF和代码
2019-03-19关于图片的处理 我觉得这可以参考参考 巩固知识点,我也是CSDN自行下载的 积分老贵了这里放一积分 意思下 愿顶
- 1.8MB
c数字图像处理算法典型实例源码.zip
2019-09-16《C#数字图像处理算法典型实例(附光盘)》精选数字图像处理领域中的一些应用实例,以理论和实践相结合的方式,系统地介绍了如何使用C#进行数字图像处理。 共11章,分别讲述了图像的点运算、几何运算、数学形态学图像处理方法、频率变换、图像平滑与去噪、边缘检测、图像分割、图像压缩编码和彩色图像处理等相关技术。《C#数字图像处理算法典型实例(附光盘)》的
- 66.2MB
C#数字图像处理算法典型实例.pdf
2017-04-17C#数字图像处理算法典型实例.pdf 个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
- 16.32MB
C#数字图像处理算法典型实例](随书光盘)
2017-07-12本资源为C#数字图像处理算法典型实例]一书的随书光盘代码,方便大家学习使用
- 223KB
C#数字图像处理经典算法实现程序
2011-11-29用C#写的框体程序,结合《数字图像处理与图像传输》,利用逐行扫描方式,实现图像打开、保存、亮度对比度调节、HSI/RGB调节、二值化、灰度化、线性变换、缩小图片、加噪、四邻域/八邻域平均滤波、Robert/Sobel/Prewitt算子、差分算子、LOG算子等锐化算法、边缘提取,负片变换,单通道显示等等,代码简单清晰,适合C#初学者学习,尽管程序处理较慢,但对于理解图像处理经典算法思想有很大帮助……
- 3.94MB
c#处理图片的算法30种,源码
2018-03-08c#处理图片的30中算法。感觉非常棒,之前学习的时候的资源现在,分享一下,向深度学习c#高级绘图的可以学习下。
- 271KB
Csharp数字图像处理,图像的平滑和边缘检测等等
2011-02-20该程序利用C#编写的,利用拉普拉斯算子高斯算子等进行图像的平滑和锐化,而且保留了源图像,便于进行图像处理后的对比。
- 1018KB
c#图像处理源代码(包含边缘检测,灰度,霍夫等各种变换。。。。)
2010-03-26最新c#图像处理源代码(包含边缘检测,灰度,霍夫等各种变换等各种算法源代码实例。。。)对初学和已有研究者都很有帮助,值得收藏。
- 213.81MB
几个重要的c程序源码.rar
2012-06-112012-06-11 15:22 39,385,694 数字图像处理算法典型实例.pdf 2012-06-11 15:47 65,071 机器人灭火程序.pdf 2012-06-11 15:28 18,087 汇编——时钟.rar 2012-06-11 15:46 83,968 深入分析Linux内核链表.doc 2012-06-...
- 55.55MB
vc++ 应用源码包_5
2012-09-15vc++动态链接库编程之DLL典型实例源代码下载 VC++仿Dreamweaver取色器源代码 VC++挂机锁屏系统源程序 VC++建立桌面或开始菜单快捷方式 VC++界面库编程 SkinMagic 2.21 动态库版本的使用和 Skin++动态库及静态库版本...
- 54.80MB
vc++ 应用源码包_6
2012-09-15vc++动态链接库编程之DLL典型实例源代码下载 VC++仿Dreamweaver取色器源代码 VC++挂机锁屏系统源程序 VC++建立桌面或开始菜单快捷方式 VC++界面库编程 SkinMagic 2.21 动态库版本的使用和 Skin++动态库及静态库版本...
- 257KB
C# 图像处理类(大而全)
2009-05-25C#图片缩放类、将彩色图像变成黑白图像、使图像产生浮雕的效果、图片文件、数据流、Image 类型数据之间的转换 还有各种各样 的操作
- 267KB
基于C#的基础数字图像处理(Visual Studio)
2019-06-26功能丰富,比较简易,适合初学者,便于加工修饰。内容有文件(打开、保存、退出)、点处理(彩色转灰阶、图像取反、图像旋转、图像镜像、均衡化、直方图、亮度变化、直方图扩展)、空频域变换(傅里叶变换、傅里叶反变换、离散余弦变换、离散余弦反变换、巴特沃斯低通滤波、巴特沃斯高通滤波、指数低通滤波、指数高通滤波)、二值化(阈值分割、自适应阈值、全局阈值)、形态学处理(腐蚀、膨胀、开运算、闭运算)、彩色图像处理(均值滤波、中值滤波、高斯滤波、Roberts算子、Laplace算子、Sobel算子、Prewitt算子、伪彩色)、图像操作(图像平移、加噪、缩小、透明变换、色彩平衡)、图像特效等。
- 4.29MB
数字图像处理的应用.ppt 很好的几个例子
2010-01-02数字图像处理的应用.ppt数字图像处理的应用.ppt
- 15.45MB
现代数字图像处理技术提高与应用案例详解-3.22人脸识别补充材料
2014-05-04这个资源是 赵小川老师的 《现代数字图像处理技术提高及应用案例详解》(matlab版)第3.22节——人脸识别中的图像资料,赵老师给出的下载链接中缺少了这一部分,这是我通过email向赵老师索要的,希望可以帮到需要的同学们。
- 4.58MB
现代数字图像处理技术提高及应用案例详解(Matlab版)----源码
2016-10-26现代数字图像处理技术提高及应用案例详解(Matlab版)----源码
- 56.54MB
vc++ 应用源码包_1
2012-09-15vc++动态链接库编程之DLL典型实例源代码下载 VC++仿Dreamweaver取色器源代码 VC++挂机锁屏系统源程序 VC++建立桌面或开始菜单快捷方式 VC++界面库编程 SkinMagic 2.21 动态库版本的使用和 Skin++动态库及静态库版本...
- 43.34MB
vc++ 应用源码包_2
2012-09-15vc++动态链接库编程之DLL典型实例源代码下载 VC++仿Dreamweaver取色器源代码 VC++挂机锁屏系统源程序 VC++建立桌面或开始菜单快捷方式 VC++界面库编程 SkinMagic 2.21 动态库版本的使用和 Skin++动态库及静态库版本...
- 57.5MB
vc++ 应用源码包_3
2012-09-15vc++动态链接库编程之DLL典型实例源代码下载 VC++仿Dreamweaver取色器源代码 VC++挂机锁屏系统源程序 VC++建立桌面或开始菜单快捷方式 VC++界面库编程 SkinMagic 2.21 动态库版本的使用和 Skin++动态库及静态库版本...
- 5.7MB
数字图像处理经典案例代码完整可直接运行
2017-11-30经典完整 数字图像处理 经典案例代码完整可直接运行
- 1.2MB
数字图像处理算法例子,数字图像处理算法例子
2017-10-20using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace edge { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void open_Click(object sender, EventArgs e) { OpenFileDialog opnDlg = new OpenFileDialog(); opnDlg.Filter = "所有图像文件 | *.bmp; *.pcx; *.png; *.jpg; *.gif;" + "*.tif; *.ico; *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf|" + "位图( *.bmp; *.jpg; *.png;...) | *.bmp; *.pcx; *.png; *.jpg; *.gif; *.tif; *.ico|" + "矢量图( *.wmf; *.eps; *.emf;...) | *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf"; opnDlg.Title = "打开图像文件"; opnDlg.ShowHelp = true; if (opnDlg.ShowDialog() == DialogResult.OK) { curFileName = opnDlg.FileName; try { curBitmap = (Bitmap)Image.FromFile(curFileName); } catch (Exception exp) { MessageBox.Show(exp.Message); } } Invalidate(); } private void close_Click(object sender, EventArgs e) { this.Close(); } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; if (curBitmap != null) { g.DrawImage(curBitmap, 160, 20, curBitmap.Width, curBitmap.Height); } } private void mask_Click(object sender, EventArgs e) { if (curBitmap != null) { mask operatorMask = new mask(); if (operatorMask.ShowDialog() == DialogResult.OK) { Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height); System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat); IntPtr ptr = bmpData.Scan0; int bytes = curBitmap.Width * curBitmap.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); int thresholding = operatorMask.GetThresholding; byte flagMask = operatorMask.GetMask; double[] tempArray = new double[bytes]; double gradX, gradY, grad; switch (flagMask) { case 0://Roberts for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { gradX = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - grayValues[i * curBitmap.Width + j]; gradY = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)]; grad = Math.Sqrt(gradX * gradX + gradY * gradY); tempArray[i * curBitmap.Width + j] = grad; } } break; case 1://Prewitt for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { gradX = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] - grayValues[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)]; gradY = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] + grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]; grad = Math.Sqrt(gradX * gradX + gradY * gradY); tempArray[i * curBitmap.Width + j] = grad; } } break; case 2://Sobel for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { gradX = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)]; gradY = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]; grad = Math.Sqrt(gradX * gradX + gradY * gradY); tempArray[i * curBitmap.Width + j] = grad; } } break; case 3://Laplacian1公式(8.4) for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { grad = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - 4 * grayValues[i * curBitmap.Width + j]; tempArray[i * curBitmap.Width + j] = grad; } } break; case 4://Laplacian2公式(8.5) for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { grad = grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] + grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 8 * grayValues[i * curBitmap.Width + j]; tempArray[i * curBitmap.Width + j] = grad; } } break; case 5://Laplacian3公式(8.6) for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { grad = -1 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 4 * grayValues[i * curBitmap.Width + j]; tempArray[i * curBitmap.Width + j] = grad; } } break; case 6://Kirsch for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { grad = 0; gradX = -5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 5 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]; if (gradX > grad) grad = gradX; gradX = 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 5 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]; if (gradX > grad) grad = gradX; gradX = 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]; if (gradX > grad) grad = gradX; gradX = 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]; if (gradX > grad) grad = gradX; gradX = 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - 5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - 5 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]; if (gradX > grad) grad = gradX; gradX = 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - 5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]; if (gradX > grad) grad = gradX; gradX = -5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - 5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]; if (gradX > grad) grad = gradX; gradX = -5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 5 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - 5 * grayValues[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + j] + 3 * grayValues[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]; if (gradX > grad) grad = gradX; tempArray[i * curBitmap.Width + j] = grad; } } break; default: MessageBox.Show("无效!"); break; } if (thresholding == 0)//不进行阈值处理 { for (int i = 0; i < bytes; i++) { if (tempArray[i] < 0) grayValues[i] = 0; else { if (tempArray[i] > 255) grayValues[i] = 255; else grayValues[i] = Convert.ToByte(tempArray[i]); } } } else//阈值处理,生成二值边缘图像 { if (flagMask == 3 || flagMask == 4 || flagMask == 5) { zerocross(ref tempArray, out grayValues, thresholding); } else { for (int i = 0; i < bytes; i++) { if (tempArray[i] > thresholding) grayValues[i] = 255; else grayValues[i] = 0; } } } System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); curBitmap.UnlockBits(bmpData); } Invalidate(); } } private void gaussian_Click(object sender, EventArgs e) { if (curBitmap != null) { gaussian gaussFilter = new gaussian(); if (gaussFilter.ShowDialog() == DialogResult.OK) { Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height); System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat); IntPtr ptr = bmpData.Scan0; int bytes = curBitmap.Width * curBitmap.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); double thresholding = gaussFilter.GetThresholding; double sigma = gaussFilter.GetSigma; bool flag = gaussFilter.GetFlag; double[] filt, tempArray; createFilter(out filt, sigma, flag); conv2(ref grayValues, ref filt, out tempArray); zerocross(ref tempArray, out grayValues, thresholding); System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); curBitmap.UnlockBits(bmpData); } Invalidate(); } } private void zerocross(ref double[] inputImage, out byte[] outImage, double thresh) { outImage = new byte[curBitmap.Width * curBitmap.Height]; for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { if (inputImage[i * curBitmap.Width + j] < 0 && inputImage[((i + 1) % curBitmap.Height) * curBitmap.Width + j] > 0 && Math.Abs(inputImage[i * curBitmap.Width + j] - inputImage[((i + 1) % curBitmap.Height) * curBitmap.Width + j]) > thresh) { outImage[i * curBitmap.Width + j] = 255; } else if (inputImage[i * curBitmap.Width + j] < 0 && inputImage[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] > 0 && Math.Abs(inputImage[i * curBitmap.Width + j] - inputImage[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j]) > thresh) { outImage[i * curBitmap.Width + j] = 255; } else if (inputImage[i * curBitmap.Width + j] < 0 && inputImage[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] > 0 && Math.Abs(inputImage[i * curBitmap.Width + j] - inputImage[i * curBitmap.Width + ((j + 1) % curBitmap.Width)]) > thresh) { outImage[i * curBitmap.Width + j] = 255; } else if (inputImage[i * curBitmap.Width + j] < 0 && inputImage[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] > 0 && Math.Abs(inputImage[i * curBitmap.Width + j] - inputImage[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)]) > thresh) { outImage[i * curBitmap.Width + j] = 255; } else if (inputImage[i * curBitmap.Width + j] == 0) { if (inputImage[((i + 1) % curBitmap.Height) * curBitmap.Width + j] > 0 && inputImage[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] < 0 && Math.Abs(inputImage[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - inputImage[((i + 1) % curBitmap.Height) * curBitmap.Width + j]) > 2 * thresh) { outImage[i * curBitmap.Width + j] = 255; } else if (inputImage[((i + 1) % curBitmap.Height) * curBitmap.Width + j] < 0 && inputImage[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] > 0 && Math.Abs(inputImage[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] - inputImage[((i + 1) % curBitmap.Height) * curBitmap.Width + j]) > 2 * thresh) { outImage[i * curBitmap.Width + j] = 255; } else if (inputImage[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] > 0 && inputImage[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] < 0 && Math.Abs(inputImage[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - inputImage[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)]) > 2 * thresh) { outImage[i * curBitmap.Width + j] = 255; } else if (inputImage[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] < 0 && inputImage[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] > 0 && Math.Abs(inputImage[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] - inputImage[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)]) > 2 * thresh) { outImage[i * curBitmap.Width + j] = 255; } else { outImage[i * curBitmap.Width + j] = 0; } } else { outImage[i * curBitmap.Width + j] = 0; } } } } private void createFilter(out double[] filter, double sigma, bool lod) { double std2 = 2 * sigma * sigma; int radius = Convert.ToInt16(Math.Ceiling(3 * sigma)); int filterWidth = 2 * radius + 1; filter = new double[filterWidth * filterWidth]; double sum = 0, average = 0; if (lod == false) { for (int i = 0; i < radius; i++) { for (int j = 0; j < radius; j++) { int xx = (j - radius) * (j - radius); int yy = (i - radius) * (i - radius); filter[i * filterWidth + j] = (xx + yy - std2) * Math.Exp(-(xx + yy) / std2); sum += 4 * filter[i * filterWidth + j]; } } for (int i = 0; i < radius; i++) { int xx = (i - radius) * (i - radius); filter[i * filterWidth + radius] = (xx - std2) * Math.Exp(-xx / std2); sum += 2 * filter[i * filterWidth + radius]; } for (int j = 0; j < radius; j++) { int yy = (j - radius) * (j - radius); filter[radius * filterWidth + j] = (yy - std2) * Math.Exp(-yy / std2); sum += 2 * filter[radius * filterWidth + j]; } filter[radius * filterWidth + radius] = -std2; sum += filter[radius * filterWidth + radius]; average = sum / filter.Length; for (int i = 0; i < radius; i++) { for (int j = 0; j < radius; j++) { filter[i * filterWidth + j] = filter[i * filterWidth + j] - average; filter[filterWidth - 1 - j + i * filterWidth] = filter[i * filterWidth + j]; filter[filterWidth - 1 - j + (filterWidth - 1 - i) * filterWidth] = filter[i * filterWidth + j]; filter[j + (filterWidth - 1 - i) * filterWidth] = filter[i * filterWidth + j]; } } for (int i = 0; i < radius; i++) { filter[i * filterWidth + radius] = filter[i * filterWidth + radius] - average; filter[(filterWidth - 1 - i) * filterWidth + radius] = filter[i * filterWidth + radius]; } for (int j = 0; j < radius; j++) { filter[radius * filterWidth + j] = filter[radius * filterWidth + j] - average; filter[radius * filterWidth + filterWidth - 1 - j] = filter[radius * filterWidth + j]; } filter[radius * filterWidth + radius] = filter[radius * filterWidth + radius] - average; } else { for (int i = 0; i < radius; i++) { for (int j = 0; j < radius; j++) { int xx = (j - radius) * (j - radius); int yy = (i - radius) * (i - radius); filter[i * filterWidth + j] = 1.6 * Math.Exp(-(xx + yy) * 1.6 * 1.6 / std2) / sigma - Math.Exp(-(xx + yy) / std2) / sigma; sum += 4 * filter[i * filterWidth + j]; } } for (int i = 0; i < radius; i++) { int xx = (i - radius) * (i - radius); filter[i * filterWidth + radius] = 1.6 * Math.Exp(-xx * 1.6 * 1.6 / std2) / sigma - Math.Exp(-xx / std2) / sigma; sum += 2 * filter[i * filterWidth + radius]; } for (int j = 0; j < radius; j++) { int yy = (j - radius) * (j - radius); filter[radius * filterWidth + j] = 1.6 * Math.Exp(-yy * 1.6 * 1.6 / std2) / sigma - Math.Exp(-yy / std2) / sigma; sum += 2 * filter[radius * filterWidth + j]; } filter[radius * filterWidth + radius] = 1.6 / sigma - 1 / sigma; sum += filter[radius * filterWidth + radius]; average = sum / filter.Length; for (int i = 0; i < radius; i++) { for (int j = 0; j < radius; j++) { filter[i * filterWidth + j] = filter[i * filterWidth + j] - average; filter[filterWidth - 1 - j + i * filterWidth] = filter[i * filterWidth + j]; filter[filterWidth - 1 - j + (filterWidth - 1 - i) * filterWidth] = filter[i * filterWidth + j]; filter[j + (filterWidth - 1 - i) * filterWidth] = filter[i * filterWidth + j]; } } for (int i = 0; i < radius; i++) { filter[i * filterWidth + radius] = filter[i * filterWidth + radius] - average; filter[(filterWidth - 1 - i) * filterWidth + radius] = filter[i * filterWidth + radius]; } for (int j = 0; j < radius; j++) { filter[radius * filterWidth + j] = filter[radius * filterWidth + j] - average; filter[radius * filterWidth + filterWidth - 1 - j] = filter[radius * filterWidth + j]; } filter[radius * filterWidth + radius] = filter[radius * filterWidth + radius] - average; } } private void conv2(ref byte[] inputImage, ref double[] mask, out double[] outImage) { int windWidth = Convert.ToInt16(Math.Sqrt(mask.Length)); int radius = windWidth / 2; double temp; outImage = new double[curBitmap.Width * curBitmap.Height]; for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { temp = 0; for (int x = -radius; x <= radius; x++) { for (int y = -radius; y <= radius; y++) { temp += inputImage[((Math.Abs(i + x)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j + y)) % curBitmap.Width] * mask[(x + radius) * windWidth + y + radius]; } } outImage[i * curBitmap.Width + j] = temp; } } } private void canny_Click(object sender, EventArgs e) { if (curBitmap != null) { canny cannyOp = new canny(); if (cannyOp.ShowDialog() == DialogResult.OK) { Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height); System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat); IntPtr ptr = bmpData.Scan0; int bytes = curBitmap.Width * curBitmap.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); byte[] thresholding = new byte[2]; thresholding = cannyOp.GetThresh; double sigma = cannyOp.GetSigma; double[] tempArray;// = new double[bytes]; double[] tempImage = new double[bytes]; double[] grad = new double[bytes]; byte[] aLabel = new byte[bytes]; double[] edgeMap = new double[bytes]; Array.Clear(edgeMap, 0, bytes); double gradX, gradY, angle; int rad = Convert.ToInt16(Math.Ceiling(3 * sigma)); for (int i = 0; i < bytes; i++) tempImage[i] = Convert.ToDouble(grayValues[i]); gaussSmooth(tempImage, out tempArray, sigma); for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { gradX = tempArray[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] + 2 * tempArray[i * curBitmap.Width + ((j + 1) % curBitmap.Width)] + tempArray[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - tempArray[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * tempArray[i * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - tempArray[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)]; gradY = tempArray[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] + 2 * tempArray[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] + tempArray[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] - tempArray[((i + 1) % curBitmap.Height) * curBitmap.Width + ((Math.Abs(j - 1)) % curBitmap.Width)] - 2 * tempArray[((i + 1) % curBitmap.Height) * curBitmap.Width + j] - tempArray[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]; grad[i * curBitmap.Width + j] = Math.Sqrt(gradX * gradX + gradY * gradY); angle = Math.Atan2(gradY, gradX); if ((angle >= -1.178097 && angle < 1.178097) || angle >= 2.748894 || angle < -2.748894) aLabel[i * curBitmap.Width + j] = 0; else if ((angle >= 0.392699 && angle < 1.178097) || (angle >= -2.748894 && angle < -1.963495)) aLabel[i * curBitmap.Width + j] = 1; else if ((angle >= -1.178097 && angle < -0.392699) || (angle >= 1.963495 && angle < 2.748894)) aLabel[i * curBitmap.Width + j] = 2; else aLabel[i * curBitmap.Width + j] = 3; } } for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { switch (aLabel[i * curBitmap.Width + j]) { case 3://水平方向 if (grad[i * curBitmap.Width + j] > grad[((Math.Abs(i - 1))%curBitmap.Height) * curBitmap.Width + j] && grad[i * curBitmap.Width + j] > grad[((i + 1)%curBitmap.Height) * curBitmap.Width + j]) edgeMap[i * curBitmap.Width + j] = grad[i * curBitmap.Width + j]; break; case 2://正45度方向 if (grad[i * curBitmap.Width + j] > grad[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] && grad[i * curBitmap.Width + j] > grad[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]) edgeMap[i * curBitmap.Width + j] = grad[i * curBitmap.Width + j]; break; case 1://负45度方向 if (grad[i * curBitmap.Width + j] > grad[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] && grad[i * curBitmap.Width + j] > grad[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)]) edgeMap[i * curBitmap.Width + j] = grad[i * curBitmap.Width + j]; break; case 0://垂直方向 if (grad[i * curBitmap.Width + j] > grad[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] && grad[i * curBitmap.Width + j] > grad[i * curBitmap.Width + ((j + 1) % curBitmap.Width)]) edgeMap[i * curBitmap.Width + j] = grad[i * curBitmap.Width + j]; break; default: return; } } } Array.Clear(grayValues, 0, bytes); for (int i = 0; i < curBitmap.Height; i++) { for (int j =0; j < curBitmap.Width; j++) { if (edgeMap[i * curBitmap.Width + j] > thresholding[0]) { grayValues[i * curBitmap.Width + j] = 255; traceEdge(i, j, edgeMap, ref grayValues, thresholding[1]); } } } System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); curBitmap.UnlockBits(bmpData); } Invalidate(); } } private void gaussSmooth(double[] inputImage, out double[] outputImage, double sigma) { double std2 = 2 * sigma * sigma; int radius = Convert.ToInt16(Math.Ceiling(3 * sigma)); int filterWidth = 2 * radius + 1; double[] filter = new double[filterWidth]; outputImage = new double[inputImage.Length]; int length = Convert.ToInt16(Math.Sqrt(inputImage.Length)); double[] tempImage = new double[inputImage.Length]; double sum = 0; for (int i = 0; i < filterWidth; i++) { int xx = (i - radius) * (i - radius); filter[i] = Math.Exp(-xx / std2); sum += filter[i]; } for (int i = 0; i < filterWidth; i++) { filter[i] = filter[i] / sum; } for (int i = 0; i < length; i++) { for (int j = 0; j < length; j++) { double temp = 0; for (int k = -radius; k <= radius; k++) { int rem = (Math.Abs(j + k)) % length; temp += inputImage[i * length + rem] * filter[k + radius]; } tempImage[i * length + j] = temp; } } for (int j = 0; j < length; j++) { for (int i = 0; i < length; i++) { double temp = 0; for (int k = -radius; k <= radius; k++) { int rem = (Math.Abs(i + k)) % length; temp += tempImage[rem * length + j] * filter[k + radius]; } outputImage[i * length + j] = temp; } } } private void traceEdge(int k, int l, double[] inputImage, ref byte[] outputImage, byte thrLow) { int[] kOffset = new int[] { 1, 1, 0, -1, -1, -1, 0, 1 }; int[] lOffset = new int[] { 0, 1, 1, 1, 0, -1, -1, -1 }; int kk, ll; for (int p = 0; p < 8; p++) { kk = k + kOffset[p]; kk = Math.Abs(kk) % curBitmap.Height; ll = l + lOffset[p]; ll = Math.Abs(ll) % curBitmap.Width; if (outputImage[ll * curBitmap.Width + kk] != 255) { if (inputImage[ll * curBitmap.Width + kk] > thrLow) { outputImage[ll * curBitmap.Width + kk] = 255; traceEdge(ll, kk, inputImage, ref outputImage, thrLow); } } } } private void morph_Click(object sender, EventArgs e) { if (curBitmap != null) { morphologic grayMor = new morphologic(); if (grayMor.ShowDialog() == DialogResult.OK) { Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height); System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat); IntPtr ptr = bmpData.Scan0; int bytes = curBitmap.Width * curBitmap.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); byte[] tempArray1 = new byte[bytes]; byte[] tempArray2 = new byte[bytes]; bool flag = grayMor.GetMethod; double thresh = grayMor.GetThresh; byte[] struEle = new byte[25]; struEle = grayMor.GetStruction; int temp; tempArray1 = grayDelation(grayValues, struEle, curBitmap.Height, curBitmap.Width); tempArray2 = grayErode(grayValues, struEle, curBitmap.Height, curBitmap.Width); for (int i = 0; i < bytes; i++) { if (flag == false) temp = (tempArray1[i] - tempArray2[i]) / 2; else temp = (tempArray1[i] + tempArray2[i] - 2 * grayValues[i]) / 2; if (temp > thresh) grayValues[i] = 255; else grayValues[i] = 0; } System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); curBitmap.UnlockBits(bmpData); } Invalidate(); } } private byte[] grayDelation(byte[] grayImage, byte[] se, int tHeight, int tWidth) { byte[] tempImage = new byte[grayImage.Length]; for (int i = 0; i < tHeight; i++) { for (int j = 0; j < tWidth; j++) { int[] cou = new int[]{grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + (Math.Abs(j - 2)) % tWidth] * se[0], grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + (Math.Abs(j - 1)) % tWidth] * se[1], grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + j] * se[2], grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + ((j + 1) % tWidth)] * se[3], grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + ((j + 2) % tWidth)] * se[4], grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + (Math.Abs(j - 2) % tWidth)] * se[5], grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + (Math.Abs(j - 1) % tWidth)] * se[6], grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + j] * se[7], grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + ((j + 1) % tWidth)] * se[8], grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + ((j + 2) % tWidth)] * se[9], grayImage[i * tWidth + (Math.Abs(j - 2) % tWidth)] * se[10], grayImage[i * tWidth + (Math.Abs(j - 1) % tWidth)] * se[11], grayImage[i * tWidth + j] * se[12], grayImage[i * tWidth + ((j + 1) % tWidth)] * se[13], grayImage[i * tWidth + ((j + 2) % tWidth)] * se[14], grayImage[((i + 1) % tHeight) * tWidth + (Math.Abs(j - 2) % tWidth)] * se[15], grayImage[((i + 1) % tHeight) * tWidth + (Math.Abs(j - 1) % tWidth)] * se[16], grayImage[((i + 1) % tHeight) * tWidth + j] * se[17], grayImage[((i + 1) % tHeight) * tWidth + ((j + 1) % tWidth)] * se[18], grayImage[((i + 1) % tHeight) * tWidth + ((j + 2) % tWidth)] * se[19], grayImage[((i + 2) % tHeight) * tWidth + (Math.Abs(j - 2) % tWidth)] * se[20], grayImage[((i + 2) % tHeight) * tWidth + (Math.Abs(j - 1) % tWidth)] * se[21], grayImage[((i + 2) % tHeight) * tWidth + j] * se[22], grayImage[((i + 2) % tHeight) * tWidth + ((j + 1) % tWidth)] * se[23], grayImage[((i + 2) % tHeight) * tWidth + ((j + 2) % tWidth)] * se[24]}; int maxim = cou[0]; for (int k = 1; k < 25; k++) { if (cou[k] > maxim) { maxim = cou[k]; } } tempImage[i * tWidth + j] = (byte)maxim; } } return tempImage; } private byte[] grayErode(byte[] grayImage, byte[] se, int tHeight, int tWidth) { byte[] tempImage = new byte[grayImage.Length]; byte[] tempSe = new byte[25]; tempSe = (byte[])se.Clone(); for (int k = 0; k < 25; k++) { if (tempSe[k] == 0) tempSe[k] = 255; } for (int i = 0; i < tHeight; i++) { for (int j = 0; j < tWidth; j++) { int[] cou = new int[]{grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + (Math.Abs(j - 2)) % tWidth] * tempSe[0], grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + (Math.Abs(j - 1)) % tWidth] * tempSe[1], grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + j] * tempSe[2], grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + ((j + 1) % tWidth)] * tempSe[3], grayImage[((Math.Abs(i - 2)) % tHeight) * tWidth + ((j + 2) % tWidth)] * tempSe[4], grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + (Math.Abs(j - 2) % tWidth)] * tempSe[5], grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + (Math.Abs(j - 1) % tWidth)] * tempSe[6], grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + j] * tempSe[7], grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + ((j + 1) % tWidth)] * tempSe[8], grayImage[((Math.Abs(i - 1)) % tHeight) * tWidth + ((j + 2) % tWidth)] * tempSe[9], grayImage[i * tWidth + (Math.Abs(j - 2) % tWidth)] * tempSe[10], grayImage[i * tWidth + (Math.Abs(j - 1) % tWidth)] * tempSe[11], grayImage[i * tWidth + j] * tempSe[12], grayImage[i * tWidth + ((j + 1) % tWidth)] * tempSe[13], grayImage[i * tWidth + ((j + 2) % tWidth)] * tempSe[14], grayImage[((i + 1) % tHeight) * tWidth + (Math.Abs(j - 2) % tWidth)] * tempSe[15], grayImage[((i + 1) % tHeight) * tWidth + (Math.Abs(j - 1) % tWidth)] * tempSe[16], grayImage[((i + 1) % tHeight) * tWidth + j] * tempSe[17], grayImage[((i + 1) % tHeight) * tWidth + ((j + 1) % tWidth)] * tempSe[18], grayImage[((i + 1) % tHeight) * tWidth + ((j + 2) % tWidth)] * tempSe[19], grayImage[((i + 2) % tHeight) * tWidth + (Math.Abs(j - 2) % tWidth)] * tempSe[20], grayImage[((i + 2) % tHeight) * tWidth + (Math.Abs(j - 1) % tWidth)] * tempSe[21], grayImage[((i + 2) % tHeight) * tWidth + j] * tempSe[22], grayImage[((i + 2) % tHeight) * tWidth + ((j + 1) % tWidth)] * tempSe[23], grayImage[((i + 2) % tHeight) * tWidth + ((j + 2) % tWidth)] * tempSe[24]}; int minimum = cou[0]; for (int k = 1; k < 25; k++) { if (cou[k] < minimum) { minimum = cou[k]; } } tempImage[i * tWidth + j] = (byte)minimum; } } return tempImage; } private void wavelet_Click(object sender, EventArgs e) { if (curBitmap != null) { wvl wavelet = new wvl(); if (wavelet.ShowDialog() == DialogResult.OK) { Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height); System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat); IntPtr ptr = bmpData.Scan0; int bytes = curBitmap.Width * curBitmap.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); double[] tempArray1 = new double[bytes]; double[] tempArray2 = new double[bytes]; double[] tempArray3 = new double[bytes]; double[] gradX = new double[bytes]; double[] gradY = new double[bytes]; byte multiscale = wavelet.GetScale; byte[] thresholding = new byte[2]; thresholding = wavelet.GetThresh; for (int i = 0; i < bytes; i++) { tempArray1[i] = Convert.ToDouble(grayValues[i]); } for (int z = 0; z <= multiscale; z++) { double[] p = null; double[] q = null; switch (z) { case 0: p = new double[] { 0.125, 0.375, 0.375, 0.125 }; q = new double[] { -2, 2 }; break; case 1: p = new double[] { 0.125, 0, 0.375, 0, 0.375, 0, 0.125 }; q = new double[] { -2, 0, 2 }; break; case 2: p = new double[] { 0.125, 0, 0, 0, 0.375, 0, 0, 0, 0.375, 0, 0, 0, 0.125 }; q = new double[] { -2, 0, 0, 0, 2 }; break; case 3: p = new double[] { 0.125, 0, 0, 0, 0, 0, 0, 0, 0.375, 0, 0, 0, 0, 0, 0, 0, 0.375, 0, 0, 0, 0, 0, 0, 0, 0.125 }; q = new double[] { -2, 0, 0, 0, 0, 0, 0, 0, 2 }; break; default: return; } int coff = Convert.ToInt16(Math.Pow(2, z) - 1); for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { double[] scl = new double[curBitmap.Width]; double[] wvl = new double[curBitmap.Width]; int temp; scl[j] = 0.0; wvl[j] = 0.0; for (int x = -2 - 2 * coff; x < p.Length - 2 - 2 * coff; x++) { temp = (Math.Abs(j + x)) % curBitmap.Width; scl[j] += p[1 + coff - x] * tempArray1[i * curBitmap.Width + temp]; } for (int x = -1 - coff; x < q.Length - 1 - coff; x++) { temp = (Math.Abs(j + x)) % curBitmap.Width; wvl[j] += q[-x] * tempArray1[i * curBitmap.Width + temp]; } tempArray2[i * curBitmap.Width + j] = scl[j]; gradX[i * curBitmap.Width + j] = wvl[j]; } } for (int i = 0; i < curBitmap.Width; i++) { for (int j = 0; j < curBitmap.Height; j++) { double[] scl = new double[curBitmap.Height]; double[] wvl = new double[curBitmap.Height]; int temp; scl[j] = 0.0; wvl[j] = 0.0; for (int x = -2 - 2 * coff; x < p.Length - 2 - 2 * coff; x++) { temp = (Math.Abs(j + x)) % curBitmap.Height; scl[j] += p[1 + coff - x] * tempArray2[temp * curBitmap.Width + i]; } for (int x = -1 - coff; x < q.Length - 1 - coff; x++) { temp = (Math.Abs(j + x)) % curBitmap.Height; wvl[j] += q[-x] * tempArray1[temp * curBitmap.Width + i]; } tempArray3[j * curBitmap.Width + i] = scl[j]; gradY[j * curBitmap.Width + i] = wvl[j]; } } tempArray1 = (double[])tempArray3.Clone(); } double angle; for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { tempArray1[i * curBitmap.Width + j] = Math.Sqrt(gradX[i * curBitmap.Width + j] * gradX[i * curBitmap.Width + j] + gradY[i * curBitmap.Width + j] * gradY[i * curBitmap.Width + j]); angle = Math.Atan2(gradY[i * curBitmap.Width + j], gradX[i * curBitmap.Width + j]); if ((angle >= -1.178097 && angle < 1.178097) || angle >= 2.748894 || angle < -2.748894) tempArray2[i * curBitmap.Width + j] = 0; else if ((angle >= 0.392699 && angle < 1.178097) || (angle >= -2.748894 && angle < -1.963495)) tempArray2[i * curBitmap.Width + j] = 1; else if ((angle >= -1.178097 && angle < -0.392699) || (angle >= 1.963495 && angle < 2.748894)) tempArray2[i * curBitmap.Width + j] = 2; else tempArray2[i * curBitmap.Width + j] = 3; } } Array.Clear(tempArray3, 0, bytes); for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { switch (Convert.ToInt16(tempArray2[i * curBitmap.Width + j])) { case 3://水平方向 if (tempArray1[i * curBitmap.Width + j] > tempArray1[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + j] && tempArray1[i * curBitmap.Width + j] > tempArray1[((i + 1) % curBitmap.Height) * curBitmap.Width + j]) tempArray3[i * curBitmap.Width + j] = tempArray1[i * curBitmap.Width + j]; break; case 1://正45度方向 if (tempArray1[i * curBitmap.Width + j] > tempArray1[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] && tempArray1[i * curBitmap.Width + j] > tempArray1[((i + 1) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)]) tempArray3[i * curBitmap.Width + j] = tempArray1[i * curBitmap.Width + j]; break; case 2://负45度方向 if (tempArray1[i * curBitmap.Width + j] > tempArray1[((Math.Abs(i - 1)) % curBitmap.Height) * curBitmap.Width + ((j + 1) % curBitmap.Width)] && tempArray1[i * curBitmap.Width + j] > tempArray1[((i + 1) % curBitmap.Height) * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)]) tempArray3[i * curBitmap.Width + j] = tempArray1[i * curBitmap.Width + j]; break; case 0://垂直方向 if (tempArray1[i * curBitmap.Width + j] > tempArray1[i * curBitmap.Width + (Math.Abs(j - 1) % curBitmap.Width)] && tempArray1[i * curBitmap.Width + j] > tempArray1[i * curBitmap.Width + ((j + 1) % curBitmap.Width)]) tempArray3[i * curBitmap.Width + j] = tempArray1[i * curBitmap.Width + j]; break; default: return; } } } Array.Clear(grayValues, 0, bytes); for (int i = 0; i < curBitmap.Height; i++) { for (int j = 0; j < curBitmap.Width; j++) { if (tempArray3[i * curBitmap.Width + j] > thresholding[0]) { grayValues[i * curBitmap.Width + j] = 255; traceEdge(i, j, tempArray3, ref grayValues, thresholding[1]); } } } System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); curBitmap.UnlockBits(bmpData); } Invalidate(); } } private void pyramid_Click(object sender, EventArgs e) { if (curBitmap != null) { int series = Convert.ToInt16(Math.Log(curBitmap.Width, 2)); glp pyramid = new glp(series); if (pyramid.ShowDialog() == DialogResult.OK) { Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height); System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat); IntPtr ptr = bmpData.Scan0; int bytes = curBitmap.Width * curBitmap.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); double thresh = pyramid.GetThresh; byte level = pyramid.GetLevel; double sigma = pyramid.GetSigma; double[][] pyramidImage = new double[level + 1][]; double[][] passImage = new double[level + 1][]; int levelBytes = bytes; for (int k = 0; k < level + 1; k++) { passImage[k] = new double[levelBytes]; pyramidImage[k] = new double[levelBytes]; levelBytes = levelBytes / 4; } for (int i = 0; i < bytes; i++) pyramidImage[0][i] = Convert.ToDouble(grayValues[i]); for (int k = 0; k < level; k++) { double[] tempImage = null; gaussSmooth(pyramidImage[k], out tempImage, sigma); int coff = pyramidImage[k].Length; for (int i = 0; i < coff; i++) { passImage[k][i] = pyramidImage[k][i] - tempImage[i]; int div = i / Convert.ToInt16(Math.Sqrt(coff)); int rem = i % Convert.ToInt16(Math.Sqrt(coff)); if (div % 2 == 0 && rem % 2 == 0) { int j = (int)((div / 2) * Math.Sqrt(pyramidImage[k + 1].Length) + rem / 2); pyramidImage[k + 1][j] = tempImage[i]; } } } for (int k = level - 1; k >= 0; k--) { int coff = pyramidImage[k].Length; for (int i = 0; i < coff; i++) { int div = i / Convert.ToInt16(Math.Sqrt(coff)); int rem = i % Convert.ToInt16(Math.Sqrt(coff)); int j = (int)((div / 2) * Math.Sqrt(pyramidImage[k + 1].Length) + rem / 2); if (div % 2 == 0 && rem % 2 == 0) pyramidImage[k][i] = pyramidImage[k + 1][j]; else pyramidImage[k][i] = 0; } double[] tempImage = null; gaussSmooth(pyramidImage[k], out tempImage, 1); for (int i = 0; i < coff; i++) pyramidImage[k][i] = tempImage[i] + passImage[k][i]; } zerocross(ref pyramidImage[0], out grayValues,thresh); System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); curBitmap.UnlockBits(bmpData); } Invalidate(); } } } }