图像开运算与闭运算定义

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

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. Android多媒体框架

    Android系统的多媒体架构图 OpenMax做编解码作用(codec),从上到下依次是AL(应用层,在多媒体中间件和应用程序之间提供一个标准化接口).IL(集成层,解码编码器).DL(开发层,供应 ...

  2. 22.XML

    转载:https://www.cnblogs.com/yuanchenqi/article/5732581.html xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用 ...

  3. 支撑百万级并发,Netty如何实现高性能内存管理

    Netty作为一款高性能网络应用程序框架,实现了一套高性能内存管理机制 通过学习其中的实现原理.算法.并发设计,有利于我们写出更优雅.更高性能的代码:当使用Netty时碰到内存方面的问题时,也可以更高 ...

  4. java_学生成绩管理系统

    //信1805-2 20183670 王云鹏 package student; import java.util.Scanner; public class ScoreManagement { sta ...

  5. Java线程的生命周期与状态流转

    上图是一个线程的生命周期状态流转图,很清楚的描绘了一个线程从创建到终止的过程. 这些状态的枚举值都定义在java.lang.Thread.State下 NEW:毫无疑问表示的是刚创建的线程,还没有开始 ...

  6. 开启 Django 博客的 RSS 功能

    作者:HelloGitHub-追梦人物 文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 博客提供 RSS 订阅应该是标配,这样读者就可以通过一些聚合阅读工具订阅你的博客,时 ...

  7. GNE: 4行代码实现新闻类网站通用爬虫

    GNE(GeneralNewsExtractor)是一个通用新闻网站正文抽取模块,输入一篇新闻网页的 HTML, 输出正文内容.标题.作者.发布时间.正文中的图片地址和正文所在的标签源代码.GNE在提 ...

  8. $Noip2013/Luogu1966$ 火柴排队 贪心+离散化+逆序对

    $Luogu$ $Description$ 给定等长的$a,b$两个序列.每次可以交换一个序列中相邻两个数.求最小的交换次数使得$\sum(a_i-b_i)^2$最小. $Sol$ 交换后的序列一定满 ...

  9. C / C++ 保留小数函数(setprecision(n)的一些用法总结)

    从C语言开始正式学习C++,但是一上来输出位数就懵了,查资料才知道C++需要使用 “ setprecision  ”函数.自己总结一下. 首先说C++代码 #include <iomanip&g ...

  10. 「CodeForces 546B」Soldier and Badges 解题报告

    CF546B Soldier and Badges 题意翻译 给 n 个数,每次操作可以将一个数 +1,要使这 n 个数都不相同, 求最少要加多少? \(1 \le n \le 3000\) 感谢@凉 ...