c#数字图像处理(十三)图像开运算与闭运算
图像开运算与闭运算定义
二值图像开运算的数学表达式为:
g(x, y)=open[f(x, y ), B]=dilate{erode[f(x, y),B],B}
二值图像的开运算事实上就是先作腐蚀运算,再作膨胀运算。
二值图像闭运算的数学表达式为:
g(x, y)=close[f(x, y ), B]=erode{dilate[f(x, y),B],B}
二值图像的闭运算事实上就是先作膨胀运算,再作腐蚀运算
private void opening_Click(object sender, EventArgs e)
{
if (curBitmap != null)
{
struction struForm = new struction();
struForm.Text = "开运算结构元素";
if (struForm.ShowDialog() == DialogResult.OK)
{
Rectangle rect = new Rectangle(, , 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];
Marshal.Copy(ptr, grayValues, , bytes); byte flagStru = struForm.GetStruction; byte[] temp1Array = new byte[bytes];
byte[] tempArray = new byte[bytes];
for (int i = ; i < bytes; i++)
{
tempArray[i] = temp1Array[i] = ;
} switch (flagStru)
{
case 0x11:
//腐蚀运算
for (int i = ; i < curBitmap.Height; i++)
{
for (int j = ; j < curBitmap.Width - ; j++)
{
if (grayValues[i * curBitmap.Width + j] == &&
grayValues[i * curBitmap.Width + j + ] == &&
grayValues[i * curBitmap.Width + j - ] == )
{
temp1Array[i * curBitmap.Width + j] = ;
} }
}
//膨胀运算
for (int i = ; i < curBitmap.Height; i++)
{
for (int j = ; j < curBitmap.Width - ; j++)
{
if (temp1Array[i * curBitmap.Width + j] == ||
temp1Array[i * curBitmap.Width + j + ] == ||
temp1Array[i * curBitmap.Width + j - ] == )
{
tempArray[i * curBitmap.Width + j] = ;
} }
}
break;
case 0x21:
//腐蚀运算
for (int i = ; i < curBitmap.Height; i++)
{
for (int j = ; j < curBitmap.Width - ; j++)
{
if (grayValues[i * curBitmap.Width + j] == &&
grayValues[i * curBitmap.Width + j + ] == &&
grayValues[i * curBitmap.Width + j - ] == &&
grayValues[i * curBitmap.Width + j + ] == &&
grayValues[i * curBitmap.Width + j - ] == )
{
temp1Array[i * curBitmap.Width + j] = ;
} }
}
//膨胀运算
for (int i = ; i < curBitmap.Height; i++)
{
for (int j = ; j < curBitmap.Width - ; j++)
{
if (temp1Array[i * curBitmap.Width + j] == ||
temp1Array[i * curBitmap.Width + j + ] == ||
temp1Array[i * curBitmap.Width + j - ] == ||
temp1Array[i * curBitmap.Width + j + ] == ||
temp1Array[i * curBitmap.Width + j - ] == )
{
tempArray[i * curBitmap.Width + j] = ;
} }
}
break;
case 0x12:
//腐蚀运算
for (int i = ; i < curBitmap.Height - ; i++)
{
for (int j = ; j < curBitmap.Width; j++)
{
if (grayValues[i * curBitmap.Width + j] == &&
grayValues[(i - ) * curBitmap.Width + j] == &&
grayValues[(i + ) * curBitmap.Width + j] == )
{
temp1Array[i * curBitmap.Width + j] = ;
} }
}
//膨胀运算
for (int i = ; i < curBitmap.Height - ; i++)
{
for (int j = ; j < curBitmap.Width; j++)
{
if (temp1Array[i * curBitmap.Width + j] == ||
temp1Array[(i - ) * curBitmap.Width + j] == ||
temp1Array[(i + ) * curBitmap.Width + j] == )
{
tempArray[i * curBitmap.Width + j] = ;
} }
}
break;
case 0x22:
//腐蚀运算
for (int i = ; i < curBitmap.Height - ; i++)
{
for (int j = ; j < curBitmap.Width; j++)
{
if (grayValues[i * curBitmap.Width + j] == &&
grayValues[(i - ) * curBitmap.Width + j] == &&
grayValues[(i + ) * curBitmap.Width + j] == &&
grayValues[(i - ) * curBitmap.Width + j] == &&
grayValues[(i + ) * curBitmap.Width + j] == )
{
temp1Array[i * curBitmap.Width + j] = ;
} }
}
//膨胀运算
for (int i = ; i < curBitmap.Height - ; i++)
{
for (int j = ; j < curBitmap.Width; j++)
{
if (temp1Array[i * curBitmap.Width + j] == ||
temp1Array[(i - ) * curBitmap.Width + j] == ||
temp1Array[(i + ) * curBitmap.Width + j] == ||
temp1Array[(i - ) * curBitmap.Width + j] == ||
temp1Array[(i + ) * curBitmap.Width + j] == )
{
tempArray[i * curBitmap.Width + j] = ;
} }
}
break;
case 0x14:
//腐蚀运算
for (int i = ; i < curBitmap.Height - ; i++)
{
for (int j = ; j < curBitmap.Width - ; j++)
{
if (grayValues[i * curBitmap.Width + j] == &&
grayValues[(i - ) * curBitmap.Width + j] == &&
grayValues[(i + ) * curBitmap.Width + j] == &&
grayValues[i * curBitmap.Width + j + ] == &&
grayValues[i * curBitmap.Width + j - ] == )
{
temp1Array[i * curBitmap.Width + j] = ;
} }
}
//膨胀运算
for (int i = ; i < curBitmap.Height - ; i++)
{
for (int j = ; j < curBitmap.Width - ; j++)
{
if (temp1Array[i * curBitmap.Width + j] == ||
temp1Array[(i - ) * curBitmap.Width + j] == ||
temp1Array[(i + ) * curBitmap.Width + j] == ||
temp1Array[i * curBitmap.Width + j + ] == ||
temp1Array[i * curBitmap.Width + j - ] == )
{
tempArray[i * curBitmap.Width + j] = ;
} }
}
break;
case 0x24:
//腐蚀运算
for (int i = ; i < curBitmap.Height - ; i++)
{
for (int j = ; j < curBitmap.Width - ; j++)
{
if (grayValues[i * curBitmap.Width + j] == &&
grayValues[(i - ) * curBitmap.Width + j] == &&
grayValues[(i + ) * curBitmap.Width + j] == &&
grayValues[(i - ) * curBitmap.Width + j] == &&
grayValues[(i + ) * curBitmap.Width + j] == &&
grayValues[i * curBitmap.Width + j + ] == &&
grayValues[i * curBitmap.Width + j - ] == &&
grayValues[i * curBitmap.Width + j + ] == &&
grayValues[i * curBitmap.Width + j - ] == )
{
temp1Array[i * curBitmap.Width + j] = ;
} }
}
//膨胀运算
for (int i = ; i < curBitmap.Height - ; i++)
{
for (int j = ; j < curBitmap.Width - ; j++)
{
if (temp1Array[i * curBitmap.Width + j] == ||
temp1Array[(i - ) * curBitmap.Width + j] == ||
temp1Array[(i + ) * curBitmap.Width + j] == ||
temp1Array[(i - ) * curBitmap.Width + j] == ||
temp1Array[(i + ) * curBitmap.Width + j] == ||
temp1Array[i * curBitmap.Width + j + ] == ||
temp1Array[i * curBitmap.Width + j - ] == ||
temp1Array[i * curBitmap.Width + j + ] == ||
temp1Array[i * curBitmap.Width + j - ] == )
{
tempArray[i * curBitmap.Width + j] = ;
} }
}
break;
case 0x18:
//腐蚀运算
for (int i = ; i < curBitmap.Height - ; i++)
{
for (int j = ; j < curBitmap.Width - ; j++)
{
if (grayValues[i * curBitmap.Width + j] == &&
grayValues[(i - ) * curBitmap.Width + j] == &&
grayValues[(i + ) * curBitmap.Width + j] == &&
grayValues[i * curBitmap.Width + j + ] == &&
grayValues[i * curBitmap.Width + j - ] == &&
grayValues[(i - ) * curBitmap.Width + j - ] == &&
grayValues[(i + ) * curBitmap.Width + j - ] == &&
grayValues[(i - ) * curBitmap.Width + j + ] == &&
grayValues[(i + ) * curBitmap.Width + j + ] == )
{
temp1Array[i * curBitmap.Width + j] = ;
} }
}
//膨胀运算
for (int i = ; i < curBitmap.Height - ; i++)
{
for (int j = ; j < curBitmap.Width - ; j++)
{
if (temp1Array[i * curBitmap.Width + j] == ||
temp1Array[(i - ) * curBitmap.Width + j] == ||
temp1Array[(i + ) * curBitmap.Width + j] == ||
temp1Array[i * curBitmap.Width + j + ] == ||
temp1Array[i * curBitmap.Width + j - ] == ||
temp1Array[(i - ) * curBitmap.Width + j - ] == ||
temp1Array[(i + ) * curBitmap.Width + j - ] == ||
temp1Array[(i - ) * curBitmap.Width + j + ] == ||
temp1Array[(i + ) * curBitmap.Width + j + ] == )
{
tempArray[i * curBitmap.Width + j] = ;
} }
}
break;
case 0x28:
//腐蚀运算
for (int i = ; i < curBitmap.Height - ; i++)
{
for (int j = ; j < curBitmap.Width - ; j++)
{
if (grayValues[(i - ) * curBitmap.Width + j - ] == &&
grayValues[(i - ) * curBitmap.Width + j - ] == &&
grayValues[(i - ) * curBitmap.Width + j] == &&
grayValues[(i - ) * curBitmap.Width + j + ] == &&
grayValues[(i - ) * curBitmap.Width + j + ] == &&
grayValues[(i - ) * curBitmap.Width + j - ] == &&
grayValues[(i - ) * curBitmap.Width + j - ] == &&
grayValues[(i - ) * curBitmap.Width + j] == &&
grayValues[(i - ) * curBitmap.Width + j + ] == &&
grayValues[(i - ) * curBitmap.Width + j + ] == &&
grayValues[i * curBitmap.Width + j - ] == &&
grayValues[i * curBitmap.Width + j - ] == &&
grayValues[i * curBitmap.Width + j] == &&
grayValues[i * curBitmap.Width + j + ] == &&
grayValues[i * curBitmap.Width + j + ] == &&
grayValues[(i + ) * curBitmap.Width + j - ] == &&
grayValues[(i + ) * curBitmap.Width + j - ] == &&
grayValues[(i + ) * curBitmap.Width + j] == &&
grayValues[(i + ) * curBitmap.Width + j + ] == &&
grayValues[(i + ) * curBitmap.Width + j + ] == &&
grayValues[(i + ) * curBitmap.Width + j - ] == &&
grayValues[(i + ) * curBitmap.Width + j - ] == &&
grayValues[(i + ) * curBitmap.Width + j] == &&
grayValues[(i + ) * curBitmap.Width + j + ] == &&
grayValues[(i + ) * curBitmap.Width + j + ] == )
{
temp1Array[i * curBitmap.Width + j] = ;
} }
}
//膨胀运算
for (int i = ; i < curBitmap.Height - ; i++)
{
for (int j = ; j < curBitmap.Width - ; j++)
{
if (temp1Array[(i - ) * curBitmap.Width + j - ] == ||
temp1Array[(i - ) * curBitmap.Width + j - ] == ||
temp1Array[(i - ) * curBitmap.Width + j] == ||
temp1Array[(i - ) * curBitmap.Width + j + ] == ||
temp1Array[(i - ) * curBitmap.Width + j + ] == ||
temp1Array[(i - ) * curBitmap.Width + j - ] == ||
temp1Array[(i - ) * curBitmap.Width + j - ] == ||
temp1Array[(i - ) * curBitmap.Width + j] == ||
temp1Array[(i - ) * curBitmap.Width + j + ] == ||
temp1Array[(i - ) * curBitmap.Width + j + ] == ||
temp1Array[i * curBitmap.Width + j - ] == ||
temp1Array[i * curBitmap.Width + j - ] == ||
temp1Array[i * curBitmap.Width + j] == ||
temp1Array[i * curBitmap.Width + j + ] == ||
temp1Array[i * curBitmap.Width + j + ] == ||
temp1Array[(i + ) * curBitmap.Width + j - ] == ||
temp1Array[(i + ) * curBitmap.Width + j - ] == ||
temp1Array[(i + ) * curBitmap.Width + j] == ||
temp1Array[(i + ) * curBitmap.Width + j + ] == ||
temp1Array[(i + ) * curBitmap.Width + j + ] == ||
temp1Array[(i + ) * curBitmap.Width + j - ] == ||
temp1Array[(i + ) * curBitmap.Width + j - ] == ||
temp1Array[(i + ) * curBitmap.Width + j] == ||
temp1Array[(i + ) * curBitmap.Width + j + ] == ||
temp1Array[(i + ) * curBitmap.Width + j + ] == )
{
tempArray[i * curBitmap.Width + j] = ;
} }
}
break;
default:
MessageBox.Show("错误的结构元素!");
break;
} grayValues = (byte[])tempArray.Clone(); System.Runtime.InteropServices.Marshal.Copy(grayValues, , ptr, bytes);
curBitmap.UnlockBits(bmpData);
} Invalidate();
}
}
#region 关于图像尺寸的说明
//本代码只能处理8位深度的512*512图像。可自行修改,如修改3位水平方向结构元素代码:
//01修改成如下代码即可处理任意尺寸的8位深度的图像
//int bytes = bmpData.Stride * curBitmap.Height;
//for (int i = 0; i < curBitmap.Height; i++)
//{
// for (int j = 1; j < curBitmap.Width - 1; j++)
// {
// if (grayValues[i * bmpData.Stride + j] == 0 &&
// grayValues[i * bmpData.Stride + j + 3] == 0 &&
// grayValues[i * bmpData.Stride + j - 1] == 0)
// {
// tempArray[i * bmpData.Stride + j] = 0;
// tempArray[i * bmpData.Stride + j + 1] = 0;
// tempArray[i * bmpData.Stride + j + 2] = 0;
// }
// }
//}
//for (int i = 0; i < curBitmap.Height; i++)
//{
// for (int j = 1; j < curBitmap.Width - 1; j++)
// {
// if (grayValues[i * bmpData.Stride + j] == 0 ||
// grayValues[i * bmpData.Stride + j + 3] == 0 ||
// grayValues[i * bmpData.Stride + j - 1] == 0)
// {
// tempArray[i * bmpData.Stride + j] = 0;
// tempArray[i * bmpData.Stride + j + 1] = 0;
// tempArray[i * bmpData.Stride + j + 2] = 0;
// }
// }
//}
//02修改成如下代码即可处理任意尺寸的24位深度的图像
//int bytes = bmpData.Stride * curBitmap.Height;
//for (int i = 0; i < curBitmap.Height; i++)
//{
// for (int j = 4; j < curBitmap.Width * 3 - 3; j += 3)
// {
// if (grayValues[i * bmpData.Stride + j] == 0 &&
// grayValues[i * bmpData.Stride + j + 3] == 0 &&
// grayValues[i * bmpData.Stride + j - 1] == 0)
// {
// tempArray[i * bmpData.Stride + j] = 0;
// tempArray[i * bmpData.Stride + j + 1] = 0;
// tempArray[i * bmpData.Stride + j + 2] = 0;
// }
// }
//}
//for (int i = 0; i < curBitmap.Height; i++)
//{
// for (int j = 1; j < curBitmap.Width - 1; j++)
// {
// if (grayValues[i * bmpData.Stride + j] == 0 ||
// grayValues[i * bmpData.Stride + j + 3] == 0 ||
// grayValues[i * bmpData.Stride + j - 1] == 0)
// {
// tempArray[i * bmpData.Stride + j] = 0;
// tempArray[i * bmpData.Stride + j + 1] = 0;
// tempArray[i * bmpData.Stride + j + 2] = 0;
// }
// }
//}
#endregion
c#数字图像处理(十三)图像开运算与闭运算的更多相关文章
- 学习 opencv---(10)形态学图像处理(2):开运算,闭运算,形态学梯度,顶帽,黒帽合辑
上篇文章中,我们重点了解了腐蚀和膨胀这两种最基本的形态学操作,而运用这两个基本操作,我们可以实现更高级的形态学变换. 所以,本文的主角是OpenCV中的morphologyEx函数,它利用基本的膨胀和 ...
- 【OpenCV新手教程之十一】 形态学图像处理(二):开运算、闭运算、形态学梯度、顶帽、黑帽合辑
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/23184547 作者:毛星云(浅墨) ...
- Python 图像处理 OpenCV (9):图像处理形态学开运算、闭运算以及梯度运算
前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...
- Win8 Metro(C#) 数字图像处理--1 图像打开,保存
原文:Win8 Metro(C#) 数字图像处理--1 图像打开,保存 作为本专栏的第一篇,必不可少的需要介绍一下图像的打开与保存,一便大家后面DEMO的制作. Win8Metro编程中,图像相关 ...
- opencv 4 图像处理(2 形态学滤波:腐蚀与膨胀,开运算、闭运算、形态学梯度、顶帽、黑帽)
腐蚀与膨胀 膨胀(求局部最大值)(dilate函数) #include <opencv2/core/core.hpp> #include <opencv2/highgui/highg ...
- opencv-图像形态学之开运算、闭运算、形态学梯度、顶帽、黑帽合辑
转自:https://blog.csdn.net/poem_qianmo/article/details/24599073 1.1 开运算(Opening Operation) 开运算(Opening ...
- Win8 Metro(C#)数字图像处理--4图像颜色空间描述
原文:Win8 Metro(C#)数字图像处理--4图像颜色空间描述 图像颜色空间是图像颜色集合的数学表示,本小节将针对几种常见颜色空间做个简单介绍. /// <summary> / ...
- 机器学习进阶-图像形态学操作-开运算与闭运算 1.cv2.morphologyEx(进行各类形态学变化) 2.op=cv2.MORPH_OPEN(先腐蚀后膨胀) 3.op=cv2.MORPH_CLOSE(先膨胀后腐蚀)
1.cv2.morphologyEx(src, op, kernel) 进行各类形态学的变化 参数说明:src传入的图片,op进行变化的方式, kernel表示方框的大小 2.op = cv2.MO ...
- OpenCV:图像的开运算与闭运算
导包: import numpy as np import cv2 import matplotlib.pyplot as plt def show(image): plt.imshow(image) ...
随机推荐
- vue-learning:14 - js - new Vue(options)中option
new Vue(options)中option 2019-4-14 Vue的核心是数据驱动,在template中实现视图逻辑,在javascript中实现业务逻辑.要通过模板template将数据显示 ...
- kafka性能测试代码
bin/kafka-producer-perf-test.sh --num-records 5000000 --record-size 5000 \ --topic kafkatopic2 \ --b ...
- Oracle 11g静默安装
1.检查安装包 安装依赖包 yum -y install gcc make binutils gcc-c++ compat-libstdc++-33 elfutils-libelf-devel elf ...
- $bzoj4152\ The\ Captain$ 最短路
正解:最短路+优化连边 解题报告: 传送门$w$ 这种优化连边啥的真的好妙噢$QwQ$ 首先显然离散化下不说$QwQ$.然后对所有横坐标纵坐标分别建点,相邻两横坐标点相连,边权为离散前的坐标差.纵坐标 ...
- linux技巧---创建应用快捷方式
linux中启动或关闭应用有时候比较麻烦,你必须cd到该应用的可执行脚本的目录中再执行该脚本,不能在任意目录下开启或关闭应用..当然,设置了环境变量path可以解决在任意目录下开启应用的问题,但是每个 ...
- ELK日志分析系统搭建
之前一段时间由于版本迭代任务紧,组内代码质量不尽如人意.接二连三的被测试提醒后台错误之后, 我们决定搭建一个后台日志分析系统, 经过几个方案比较后,选择的相对更简单的ELK方案. ELK 是Elast ...
- 「洛谷P3931」 SAC E#1 - 一道难题 Tree
P3931 SAC E#1 - 一道难题 Tree 题目背景 冴月麟和魏潇承是好朋友. 题目描述 冴月麟为了守护幻想乡,而制造了幻想乡的倒影,将真实的幻想乡封印了.任何人都无法进入真实的幻想乡了,但是 ...
- AssemblyScript基本使用与项目构建
全局安装assemblyscript npm i -S AssemblyScript/assemblyscript glob 生成编译脚手架 npx asinit . 项目构建 npm run asb ...
- C#操作注册表(简单方便,兼容X32和X64)
C#操作注册表(简单方便,兼容X32和X64) 大家好,我在这里给大家介绍本人实现的操作注册表的类,简单方便,兼容32位系统和64位系统. 一般大家用C#操作注册的方法是使用命名空间Microsoft ...
- [推荐]icheck-bootstrap(漂亮的ckeckbox/radiobox)
适用于Twitter Bootstrap框架的纯CSS样式的复选框/单选框按钮的插件. GitHub:https://github.com/bantikyan/icheck-bootstrap 如果你 ...