图像开运算与闭运算定义

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

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. Visual Studio Team Services使用教程【3】:默认团队权限说明

    2017.4.23之后建议朋友看下面的帖子 TFS2017 & VSTS 实战(繁体中文视频) Visual Studio Team Services(VSTS)与敏捷开发ALM实战关键报告( ...

  2. pytorch中DataLoader, DataSet, Sampler之间的关系

    转自:https://mp.weixin.qq.com/s/RTv0cUWvc0kuXBeNoXVu_A 自上而下理解三者关系 首先我们看一下DataLoader.__next__的源代码长什么样,为 ...

  3. TCP三次握手、四次挥手详解

    1.TCP报文格式 TCP(Transmission Control Protocol) 传输控制协议.TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接. 我们需要 ...

  4. 记一次ftp错误

    在一个ftp上,突然登不上 报错,使用浏览器登录,报此用户不是私密连接,然后使用服务器客户端登录尝试,错误信息如下: [root@test ~]# ftp *.*.*.* Connected to * ...

  5. 洛谷$P1864\ [NOI2009]$二叉查找树 区间$dp$

    正解:区间$dp$ 解题报告: 传送门$QwQ$ 首先根据二叉查找树的定义可知,数据确定了,这棵树的中序遍历就已经改变了,唯一能改变的就是通过改变权值从而改变结点的深度. 发现这里权值的值没有意义,所 ...

  6. 「每日五分钟,玩转JVM」:指针压缩

    64位JVM和32位JVM 最初的时候,JVM是32位的,但是随着64位系统的兴起,JVM也迎来了从32位到64位的转换,32位的JVM对比64位的内存容量比较有限,但是我们使用64位虚拟机的同时,也 ...

  7. 《带你装B,带你飞》pytest修仙之路3 - setup/teardown

    1. 简介 学过unittest的都知道里面用前置和后置setup和teardown非常好用,在每次用例开始前和结束后都去执行一次.当然还有更高级一点的setupClass和teardownClass ...

  8. surging 社区版本支持.net core 3.1

    简介 surging 经过两年多的研发,微服务引擎已经略有雏形,也承蒙各位的厚爱, GitHub上收获了将近2800星,fork 811,付费用户企业也有十几家,还有咨询培训, 在2020年,我们将依 ...

  9. ios 页面滑动到底部无法往上滚的问题

    简单说明:当h5端使用vue-infinite-scroll 插件 做滚动加载                如:页面布局  <header></header> <div ...

  10. Java之Object类用法总结

    Object类概述: 1.Object类是所有Java类的根父类. 2.如果在类的声明中未使用extends关键字指明其父类, 则默认父类为java.lang.Object类. Object类主要结构 ...