边缘检测图像分割算法代码
时间: 2024-06-20 20:04:03 浏览: 100
图像分割边缘检测源代码
5星 · 资源好评率100%
边缘检测和图像分割是图像处理中非常重要的基础任务。常见的边缘检测算法有Canny算法、Sobel算法等,而图像分割算法包括阈值分割、区域生长、基于边缘的分割等。下面简单介绍一下Canny算法和基于边缘的分割算法的代码实现。
1. Canny算法
Canny算法是一种经典的边缘检测算法,它能够对图像进行高效准确的边缘检测。Canny算法主要包括以下几个步骤:
1. 对图像进行灰度化处理。
2. 对图像进行高斯滤波,消除噪声。
3. 计算图像中每个像素的梯度和方向。
4. 对梯度幅值进行非极大值抑制,保留局部极大值点。
5. 双阈值处理,将梯度幅值大于高阈值的点标记为强边缘点,将梯度幅值小于低阈值的点标记为弱边缘点。
6. 通过连接强边缘点和其周围的弱边缘点来得到最终的边缘。
下面是Canny算法的Python实现代码示例:
```python
import cv2
import numpy as np
def canny_edge_detection(image, sigma=0.33):
# 灰度化
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 高斯滤波
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
# 计算梯度
gradX = cv2.Sobel(blurred, ddepth=cv2.CV_32F, dx=1, dy=0)
gradY = cv2.Sobel(blurred, ddepth=cv2.CV_32F, dx=0, dy=1)
# 计算梯度幅值和方向
gradient = np.sqrt(gradX**2 + gradY**2)
angle = np.arctan2(gradY, gradX) * 180 / np.pi
# 非极大值抑制
angle[angle < 0] += 180
angle_mask = np.zeros_like(angle)
angle_mask[(angle >= 0) & (angle < 22.5) | (angle >= 157.5) & (angle <= 180)] = 0
angle_mask[(angle >= 22.5) & (angle < 67.5)] = 45
angle_mask[(angle >= 67.5) & (angle < 112.5)] = 90
angle_mask[(angle >= 112.5) & (angle < 157.5)] = 135
M, N = image.shape[:2]
for i in range(1, M-1):
for j in range(1, N-1):
if angle_mask[i,j] == 0:
if gradient[i,j] < gradient[i,j+1] or gradient[i,j] < gradient[i,j-1]:
gradient[i,j] = 0
elif angle_mask[i,j] == 45:
if gradient[i,j] < gradient[i-1,j+1] or gradient[i,j] < gradient[i+1,j-1]:
gradient[i,j] = 0
elif angle_mask[i,j] == 90:
if gradient[i,j] < gradient[i-1,j] or gradient[i,j] < gradient[i+1,j]:
gradient[i,j] = 0
elif angle_mask[i,j] == 135:
if gradient[i,j] < gradient[i-1,j-1] or gradient[i,j] < gradient[i+1,j+1]:
gradient[i,j] = 0
# 双阈值处理
low_thresh = np.max([np.min(gradient)*sigma, 10])
high_thresh = np.min([np.max(gradient)*sigma, 255])
strong_edges = (gradient > high_thresh)
strong_i, strong_j = np.where(strong_edges)
weak_edges = (gradient >= low_thresh) & (gradient <= high_thresh)
weak_i, weak_j = np.where(weak_edges)
connected_edges = np.zeros_like(gradient)
for i, j in zip(strong_i, strong_j):
connected_edges[i,j] = 255
for ii, jj in zip(*np.where(weak_edges[i-1:i+2,j-1:j+2])):
connected_edges[ii,jj] = 255
return connected_edges
```
2. 基于边缘的分割算法
基于边缘的分割算法是一种利用图像中的边缘信息来进行分割的方法。该方法主要包括以下几个步骤:
1. 对图像进行边缘检测,得到边缘图像。
2. 对边缘图像进行膨胀操作,将边缘扩大一定程度。
3. 对扩大后的边缘图像进行连通区域分析,得到每个连通区域。
4. 根据连通区域的面积、周长等特征进行分类,得到目标区域。
5. 在原图像中标记出目标区域。
下面是基于边缘的分割算法的Python实现代码示例:
```python
import cv2
import numpy as np
def edge_based_segmentation(image):
# 边缘检测
edges = cv2.Canny(image, 100, 200)
# 膨胀操作
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
dilated = cv2.dilate(edges, kernel)
# 连通区域分析
contours, hierarchy = cv2.findContours(dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
areas = [cv2.contourArea(cnt) for cnt in contours]
perimeters = [cv2.arcLength(cnt,True) for cnt in contours]
aspect_ratios = [float(w)/h for cnt in contours for _,_,w,h in [cv2.boundingRect(cnt)]]
# 分类得到目标区域
target_contours = []
for i in range(len(contours)):
if areas[i] > 100 and perimeters[i] > 50 and aspect_ratios[i] > 0.5 and aspect_ratios[i] < 2:
target_contours.append(contours[i])
# 在原图像中标记出目标区域
mask = np.zeros_like(edges)
cv2.drawContours(mask, target_contours, -1, (255), -1)
result = cv2.bitwise_and(image,image,mask=mask)
return result
```
阅读全文