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) ...
随机推荐
- Visual Studio Team Services使用教程【3】:默认团队权限说明
2017.4.23之后建议朋友看下面的帖子 TFS2017 & VSTS 实战(繁体中文视频) Visual Studio Team Services(VSTS)与敏捷开发ALM实战关键报告( ...
- pytorch中DataLoader, DataSet, Sampler之间的关系
转自:https://mp.weixin.qq.com/s/RTv0cUWvc0kuXBeNoXVu_A 自上而下理解三者关系 首先我们看一下DataLoader.__next__的源代码长什么样,为 ...
- TCP三次握手、四次挥手详解
1.TCP报文格式 TCP(Transmission Control Protocol) 传输控制协议.TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接. 我们需要 ...
- 记一次ftp错误
在一个ftp上,突然登不上 报错,使用浏览器登录,报此用户不是私密连接,然后使用服务器客户端登录尝试,错误信息如下: [root@test ~]# ftp *.*.*.* Connected to * ...
- 洛谷$P1864\ [NOI2009]$二叉查找树 区间$dp$
正解:区间$dp$ 解题报告: 传送门$QwQ$ 首先根据二叉查找树的定义可知,数据确定了,这棵树的中序遍历就已经改变了,唯一能改变的就是通过改变权值从而改变结点的深度. 发现这里权值的值没有意义,所 ...
- 「每日五分钟,玩转JVM」:指针压缩
64位JVM和32位JVM 最初的时候,JVM是32位的,但是随着64位系统的兴起,JVM也迎来了从32位到64位的转换,32位的JVM对比64位的内存容量比较有限,但是我们使用64位虚拟机的同时,也 ...
- 《带你装B,带你飞》pytest修仙之路3 - setup/teardown
1. 简介 学过unittest的都知道里面用前置和后置setup和teardown非常好用,在每次用例开始前和结束后都去执行一次.当然还有更高级一点的setupClass和teardownClass ...
- surging 社区版本支持.net core 3.1
简介 surging 经过两年多的研发,微服务引擎已经略有雏形,也承蒙各位的厚爱, GitHub上收获了将近2800星,fork 811,付费用户企业也有十几家,还有咨询培训, 在2020年,我们将依 ...
- ios 页面滑动到底部无法往上滚的问题
简单说明:当h5端使用vue-infinite-scroll 插件 做滚动加载 如:页面布局 <header></header> <div ...
- Java之Object类用法总结
Object类概述: 1.Object类是所有Java类的根父类. 2.如果在类的声明中未使用extends关键字指明其父类, 则默认父类为java.lang.Object类. Object类主要结构 ...