图像开运算与闭运算定义

二值图像开运算的数学表达式为:

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#数字图像处理(十三)图像开运算与闭运算的更多相关文章

  1. 学习 opencv---(10)形态学图像处理(2):开运算,闭运算,形态学梯度,顶帽,黒帽合辑

    上篇文章中,我们重点了解了腐蚀和膨胀这两种最基本的形态学操作,而运用这两个基本操作,我们可以实现更高级的形态学变换. 所以,本文的主角是OpenCV中的morphologyEx函数,它利用基本的膨胀和 ...

  2. 【OpenCV新手教程之十一】 形态学图像处理(二):开运算、闭运算、形态学梯度、顶帽、黑帽合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/23184547 作者:毛星云(浅墨) ...

  3. Python 图像处理 OpenCV (9):图像处理形态学开运算、闭运算以及梯度运算

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  4. Win8 Metro(C#) 数字图像处理--1 图像打开,保存

    原文:Win8 Metro(C#) 数字图像处理--1 图像打开,保存 作为本专栏的第一篇,必不可少的需要介绍一下图像的打开与保存,一便大家后面DEMO的制作.   Win8Metro编程中,图像相关 ...

  5. opencv 4 图像处理(2 形态学滤波:腐蚀与膨胀,开运算、闭运算、形态学梯度、顶帽、黑帽)

    腐蚀与膨胀 膨胀(求局部最大值)(dilate函数) #include <opencv2/core/core.hpp> #include <opencv2/highgui/highg ...

  6. opencv-图像形态学之开运算、闭运算、形态学梯度、顶帽、黑帽合辑

    转自:https://blog.csdn.net/poem_qianmo/article/details/24599073 1.1 开运算(Opening Operation) 开运算(Opening ...

  7. Win8 Metro(C#)数字图像处理--4图像颜色空间描述

    原文:Win8 Metro(C#)数字图像处理--4图像颜色空间描述  图像颜色空间是图像颜色集合的数学表示,本小节将针对几种常见颜色空间做个简单介绍. /// <summary> / ...

  8. 机器学习进阶-图像形态学操作-开运算与闭运算 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 ...

  9. OpenCV:图像的开运算与闭运算

    导包: import numpy as np import cv2 import matplotlib.pyplot as plt def show(image): plt.imshow(image) ...

随机推荐

  1. vue 数据监听原理

    Vue.prototype.listenDatas = function(){ for(var attr in this.$data){ this.listenData(this,attr,this. ...

  2. Python12_关于文件概念的讨论与序列化

    文件是什么? 存储在一些设备上的信息的集合.一堆字节: ====================================================到底什么是二进制文件.和文本文件,它们有 ...

  3. Google老师亲授 TensorFlow2.0实战: 入门到进阶

    Google老师亲授 TensorFlow2.0 入门到进阶 课程以Tensorflow2.0框架为主体,以图像分类.房价预测.文本分类等项目为依托,讲解Tensorflow框架的使用方法,同时学习到 ...

  4. 开发板免费领!腾讯云IoT应用创新大赛正式启动!

    大赛简介 腾讯云IoT应用创新大赛是腾讯云面向物联网领域举办的大型竞赛,通过腾讯云IoT全链路产品能力,开放平台和服务,与广大开发者共同创新,孵化优秀的IoT产品和解决方案,共同构建IoT应用生态. ...

  5. $Poj3208$ 启示录 数位统计$DP$

    Poj  AcWing Description Sol  这题长得就比较像数位$DP$叭. 所以先用$DP$进行预处理,再基于拼凑思想,通过"试填法"求出最终的答案. 设$F[i] ...

  6. InterpreterPattern(解释器模式)-----Java/.Net

    解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式.这种模式实现了一个表达式接口,该接口解释一个特定的上下文.这种模式被用在 SQL 解析.符号处 ...

  7. leetcode.310最小高度树

    对于一个具有树特征的无向图,我们可选择任何一个节点作为根.图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树.给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点. ...

  8. MySQL中文乱码 - window环境

    MySQL中文乱码 window环境 Linux环境请参考这篇文章:[https://www.cnblogs.com/hankleo/p/9695842.html]: 查看及修改字符集sql --查看 ...

  9. (推荐)linux用一键安装包

    linux一键安装包内置了XXD.apache, php, mysql这些应用程序,不需要再单独安装部署. 从7.3版本开始,linux一键安装包分为32位和64位两个包,请大家根据操作系统的情况下载 ...

  10. docker-tmpfs挂载

    使用tmpfs挂载 卷和绑定装置允许在主机和容器之间共享文件,以便即使在容器停止后也可以保留数据. 如果你在Linux上运行Docker,你有第三个选择:tmpfs mounts.使用tmpfs装载创 ...