2019-07-04 14:18:18 weixin_39504171 阅读数 22

图像处理7:一些形态学处理

(1)开运算、闭运算:

       ①开运算:

            先腐蚀后膨胀的过程称为开运算,用来消除小物体、在纤细处分离物体、平滑较大物体的边界的同时并不明显改变其面积。开操作一般使对象的轮廓变得圆滑,断开狭窄的间断和消除细小的突出物。

       ②闭操作:

            先膨胀后腐蚀的过程称为闭运算,用来填充物体内的细小空间、连接相邻物体、平滑其边界的同时并不明显改变其面积。闭操作也用来使轮廓圆滑,它通常消除狭窄的间断和长细的鸿沟,消除小的空洞,并填充轮廓线中的断裂。

 

 (2)顶帽变换和底帽变换:

        ①顶帽变换、底帽变换简介:

             顶帽变换和底帽变换是数学形态学中重要的运算形式。

        ②顶帽变换、底帽变换原理:

             顶帽变换是通过利用原始图像与原始图像开操作的结果图像进行图像减操作实现的;

             底帽变换是通过原始图像闭操作的结果图像与原始图像进行图像减操作实现的。

         ③顶帽变换、底帽变换处理效果:

               1)顶帽变换:

                    顶帽变换具有高通滤波的特性,适用于处理具有暗背景、亮物体特征的图像。

                    顶帽变化的一个重要用途是用来消除不均匀光照的,比如一副图像里面有多个物体,用比这些物体都大的结构元,做一次顶帽变换,那么光照就变得相对均匀,首先比这些物体都大,那么这些物体就会被开操作删除掉,然后就剩下了不均匀的背景,然后用原图像减去这些不均匀的背景后这些物体就可以比较合适的处理。

               2)底帽变换:

                    底帽变换能够检测图像中的谷值,适用于处理具有亮背景、暗物体特征的图像。

          ④顶帽变换、底帽变换的halcon实现:

                    read disc se:加载结构化元素 ;

                    gen disc seo:生成一个椭圆结构;

                    gray_bothato 底帽变化;

                    gray tophato顶帽变化。

 

2017-11-27 14:15:16 rosefun96 阅读数 154

1、形态学运算

1.1腐蚀:
matlab指令,

I=imerode(I,se);%se为结构元素。

MATLAB构造结构元素:
se=strel(shape,parameters)

1.2膨胀
I=imdilate(I,se)

1.3开运算
相当于,先腐蚀后膨胀处理;
使图像变得光滑,断开狭窄处连接和消除毛刺。

I=imopen(I,se);

1.4闭运算
相当于,先膨胀后腐蚀。
使图像光滑,弥合狭窄的间断。
I=imclose(I,se)

2、区域填充

在区域内,放一个种子(一个像素),通过十字架进行扩充,同时限制在区域内(和区域的补空间求交);不断重复这一步骤。

2019-02-14 16:55:37 freehawkzk 阅读数 690

【图像处理】-021 开运算和闭运算

  上一篇中说到了图像的形态学操作,介绍了腐蚀和膨胀。由于腐蚀和膨胀都会对目标的面积产生较大的影响(依据操作元素的大小),影响图像中正常目标的判断。在形态学操作中,还有开运算和闭运算操作,操作结果对目标的尺寸只有较小的影响。开运算一般会平滑物体的轮廓、断开较窄的狭颈并消除细的突出物。闭运算也会平滑轮廓的一部分,通常会弥合较窄的间断和细长的沟壑,消除小的孔洞,填补轮廓线中的断裂。

1 开运算

  结构元BB对集合AA的开操作,表示为ABA\circ B,其定义如下:
(1)AB=(AB)B A \circ B =(A\circleddash B)\bigoplus B \tag{1}
BBAA的开操作就是BBAA的腐蚀,紧接着用B对结果进行膨胀,也就是用结构元素B,先对A进行腐蚀操作,在对腐蚀结果进行膨胀操作。

2 闭运算

  用结构元B对集合A的闭运算,表示为ABA\cdot B,其定义如下:
(2)AB=(AB)B A\cdot B=(A\bigoplus B)\circleddash B \tag{2}
B对集合A的闭运算,就是先用B对A进行膨胀,然后对结果用B进行腐蚀,先膨胀后腐蚀。

3 实现

#include "../Include/baseOps.h"
int main()
{
	//OutputDebugString(L"AB");
	SetCurrentDirectoryToExePath();
	cv::Mat src = cv::imread("../images/72.png");
	cv::imshow("原图", src);

	cv::Mat bw;
	cv::threshold(src, bw, 125, 255, cv::THRESH_BINARY);
	cv::imshow("125阈值二值化", bw);

	cv::Mat m = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));
	cv::Mat dst;
	cv::morphologyEx(bw, dst, cv::MORPH_ERODE, m);
	cv::imshow("腐蚀", dst);

	cv::morphologyEx(bw, dst, cv::MORPH_DILATE, m);
	cv::imshow("膨胀", dst);

	cv::morphologyEx(bw, dst, cv::MORPH_OPEN, m);
	cv::imshow("开运算", dst);

	cv::morphologyEx(bw, dst, cv::MORPH_CLOSE, m);
	cv::imshow("闭运算", dst);
	cv::waitKey(0);

	return 0;
}

在这里插入图片描述

2019-05-04 08:59:07 zaishuiyifangxym 阅读数 939

目录

1 图像顶帽运算(原始图像 — 开运算)

1.1 基本原理

1.2 代码示例

2 图像黑帽运算(闭运算 — 原始图像)

2.1 基本原理

2.2 代码示例

参考资料


前面介绍了 形态学处理——图像开运算与图像闭运算,其中:

图像开运算先腐蚀,后膨胀。一般会平滑物体的轮廓、断开较窄的狭颈并消除细的突出物。

图像闭运算先膨胀,后腐蚀。同样也会平滑轮廓的一部分。但与开操作相反,它通常会弥合较窄的间断和细长的沟壑,消除小的孔洞,填补轮廓线中的断裂。

 

1 图像顶帽运算(原始图像 — 开运算)

1.1 基本原理

图像顶帽(或图像礼帽)运算是原始图像减去图像开运算的结果,得到图像的噪声。如下图所示:

顶帽运算:原始图像 — 图像开运算

 

 

1.2 代码示例

图像顶帽运算使用函数 morphologyEx() ,其参数 cv2.MORPH_TOPHAT 对应顶帽运算。

morphologyEx() 函数形式如下:

dst = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel)

其中,参数:

dst 表示处理的结果;

src 表示原图像;

cv2.MORPH_TOPHAT 表示顶帽运算;

kernel 表示卷积核。

例如,下图表示 5\times5 的卷积核,可以采用函数 np.ones((5,5), np.uint8) 构建。

 

(1)卷积核大小为 5\times

代码如下所示:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread('test5.bmp', cv2.IMREAD_UNCHANGED)

#设置卷积核
kernel = np.ones((5,5), np.uint8)

#图像闭运算
result = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", result)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:

 

(2)卷积核大小为 15\times15 

代码如下所示:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread('test5.bmp', cv2.IMREAD_UNCHANGED)

#设置卷积核
kernel = np.ones((15,15), np.uint8)

#图像闭运算
result = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", result)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:


 

2 图像黑帽运算(闭运算 — 原始图像)

2.1 基本原理

图像黑帽运算是图像闭运算操作减去原始图像的结果,得到图像内部的小孔,或者前景色中的小黑点。如下图所示:

黑帽运算:闭运算 — 原始图像

 

2.2 代码示例

图像黑帽运算使用函数 morphologyEx() ,其参数 cv2.MORPH_BLACKHAT 对应黑帽运算。

morphologyEx() 函数形式如下:

dst = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel)

其中,参数:

dst 表示处理的结果;

src 表示原图像;

cv2.MORPH_BLACKHAT 表示黑帽运算;

kernel 表示卷积核。

例如,下图表示 5\times5 的卷积核,可以采用函数 np.ones((5,5), np.uint8) 构建。

 

(1)卷积核大小为 5\times5

代码如下所示:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread('test6.bmp', cv2.IMREAD_UNCHANGED)

#设置卷积核
kernel = np.ones((5,5), np.uint8)

#图像闭运算
result = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", result)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:

 

 

(2)卷积核大小为 15\times15

代码如下所示:

#encoding:utf-8
import cv2
import numpy as np

#读取图片
src = cv2.imread('test6.bmp', cv2.IMREAD_UNCHANGED)

#设置卷积核
kernel = np.ones((15,15), np.uint8)

#图像闭运算
result = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel)

#显示图像
cv2.imshow("src", src)
cv2.imshow("result", result)

#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

 

运行结果如下图所示:

 


 

参考资料

[1] https://blog.csdn.net/Eastmount/article/details/83692456

[2] Python+OpenCV图像处理

2019-03-25 13:05:24 weixin_41715077 阅读数 1765

1、概述:

WebSocket是一种在单个TCP连接上进行全双工通信的协议。在我们应用的过程仲,客户端会出现无故断开的情况。这里提供一种连接断开的异常检测机制。

2、异常信息:

系统中出现的异常
2019-03-12 18:56:24,044 ERROR [com.lenovo.SocketServer.ping(172)] -
2019-03-12 18:56:24,045 ERROR [com.lenovo.SocketServer.ping(173)] - <java.net.SocketException: Software caused connection abort: recv failed>

2.1、之前有人给出的方案:

总结产生原因,在服务端/客户端单方面关闭连接的情况下,另一方依然以为tcp连接仍然建立,试图读取对方的响应数据,导致出现Software caused connection abort: recv failed的异常。 通过inputstream的available()方法来判断,是否有响应结果。但是对SocketInputStream没有效果,因为SocketInputStream 在断开连接和数据正常传输状态的下 available 返回值都是0。

3、代码分析

其中InputStream 类型为 SocketInputStream,但是SocketInputStream 在 jdk 的rt.jar 中,是JDK的核心专用类型,不是public类型,只能通过反射获取其中的参数。 有一行代码:boolean eof = (Boolean) getValueByKey(inputStream, “eof”);获取eof 字段的值就是通过Java 的反射机制做的。下面会重点说这个字段。

开启WebSocket服务端:

    
	private static void generateTCPServer() throws IOException
	{
		ServerSocket serverSocket = new ServerSocket(12345);

		while (true)
		{
			Socket socket = serverSocket.accept();
			Thread thread = new Thread()
			{
				@Override
				public void run(){
					System.out.println("开启新的线程");					
					while (true){
						try {
							if (socket == null){
								System.out.println("socket为null");
								Thread.interrupted();
							}
							else{
								boolean flag = handler(socket);
								if(!flag)
								{
									System.out.println("Client Down");
									Thread.interrupted();
									break;
								}
							Thread.sleep(50);
							}
						}
						catch (Exception e)
						{
							logger.error("System error");
							logger.error(e.getMessage());
							e.printStackTrace();
						}
						
					}
				}
			};
			thread.start();
		}
	}

连接数据处理逻辑:


	public static boolean handler(Socket socket) {
		try {
			OutputStream outputStream = socket.getOutputStream();
			InputStream inputStream = socket.getInputStream();
			// 接受客户端的响应
			byte[] b = new byte[51200];
			inputStream.read(b);

			// 第一种方式:通过获取eof 参数获取当前连接是否断开的参数
			boolean eof = (Boolean) getValueByKey(inputStream, "eof");
			if (true == eof) {
				// 已经断开
				logger.error("");
				return false;
			}
			
			// 第二种方式:获取传输的内容
			String msg = CommonUtil.toHexString(b);
			String head = msg.substring(0, 2);
			// client断开
			if (head.equals("00")) {
				logger.error("");
				return false;
			}
			
		} catch (IOException e) {
			logger.error("IOException by TCP");
			logger.error(e);
		}
		return true;
	}

4、场景分析

4.1.建立Socket连接,底层就是TCP连接:

连接过程代码走到 inputStream.read(b);就I/O中断了 并等待请求数据过来,继续执行下面的代码。new byte[51200] 为下一次请求建立了一缓存区,用于接收下一次请求的数据。
在这里插入图片描述
这里Thread的状态仍然是RUNNABLE。
在这里插入图片描述
发起连接请求:响应 为空

在这里插入图片描述
流程处理过程中部分核心参数:

    OutputStream
		   append:false
		   channel:null
		   closed:false
		   closing:false
		   socket:
			  bound:true
			  created:true
			  connected:true
			  closed:false
		InputStream
			channel:null
			closed:false 
			closing:false
			eof:false  =========== 不一样的地方
			socket:
			  bound:true
			  created:true
			  connected:true
			  closed:false

4.2.发送数据

代码从连接检测的代码处继续执行,一直到返回响应结束。
// 第一种方式:通过获取eof 参数获取当前连接是否断开的参数
boolean eof = (Boolean) getValueByKey(inputStream, “eof”);
在这里插入图片描述
在这里插入图片描述

流程处理过程中部分核心参数:如果连接没有断开,就是上一次请求结束后的参数。

      OutputStream
		   append:false
		   channel:null
		   closed:false
		   closing:false
		   socket:
			  bound:true
			  created:true
			  connected:true
			  closed:false
		InputStream
			channel:null
			closed:false 
			closing:false
			eof:false  =========== 不一样的地方
			socket:
			  bound:true
			  created:true
			  connected:true
			  closed:false

4.3.断开连接

代码从连接检测的代码处继续执行,但是在连接断开检测的时候就结束了 并返回false。
// 第一种方式:通过获取eof 参数获取当前连接是否断开的参数
boolean eof = (Boolean) getValueByKey(inputStream, “eof”);
以下两种方式中的任意一种都可以作为连接断开检测代码,推荐第一种:
在这里插入图片描述
在这里插入图片描述

流程处理过程中部分核心参数:连接断开后eof为true.

       OutputStream
		   append:false
		   channel:null
		   closed:false
		   closing:false
		   socket:
			  bound:true
			  created:true
			  connected:true
			  closed:false
		InputStream
			channel:null
			closed:false 
			closing:false
			eof:true  ============不一样的地方
			socket:
			  bound:true
			  created:true
			  connected:true
			  closed:false

5、总结:

优先通过连接状态来判断客户端是否断开。需要建立一种异常检测机制和连接重连的机制。

tcp断开异常处理

阅读数 893

crt连接自动断开

阅读数 68

没有更多推荐了,返回首页