一、实验目的与要求

1.了解图像分割的意义和常用方法

2.掌握常用的图像分割方法

二、实验相关知识

图像分割就是把图像分成互不重叠的区域并提取出感兴趣目标的技术,是由图像处理到图像分析的关键步骤。

和本实验有关的常用Matlab函数:

edge:检测灰度或二值图像的边缘,返回一个二值图像,1像素是检测到的边缘,0像素是非边缘

用法:BW=edge(I,'sobel',thresh,direction); %I为检测对象;

边缘检测算子可用sobel、roberts、prewitt、zerocross、log、canny;

thresh指定阈值,检测时忽略所有小于阈值的边缘,默认自动选择阈值;

direction指定方向,可选项有horizontal、vertical或both,在指定的方向上用算子进行边缘检测

三、实验内容

1、分别用RobertsPrewittSobel三种边缘检测算子,对图像wire.bmp进行水平、垂直及各个方向的边界检测,并将检测结果转化为白底黑线条的方式显示出来;

2、使用手动阈值分割法对bottle图像进行分割,显示分割结果,并分析其优缺点。

3、对下图A进行处理,得到类似图B的样子;

四、实验图像

五、实验代码

 1、分别用RobertsPrewittSobel三种边缘检测算子,对图像wire.bmp进行水平、垂直及各个方向的边界检测,并将检测结果转化为白底黑线条的方式显示出来;

import numpy as np
import matplotlib.pyplot as plt
import cv2 as cv

src = cv.imread("wire.bmp", 0)
img = src.copy()
title = ["原图", "水平", "垂直", "各个方向"]
suptitle = ["Sobel算子", "Prewitt算子", "Roberts算子"]


def showImg(pic, flag):
    for i in range(4):
        plt.subplot(2, 2, i + 1)
        plt.title(title[i])
        plt.imshow(pic[i], cmap=plt.cm.gray)
        plt.axis("off")
    plt.suptitle(suptitle[flag])
    plt.show()


# %% ——————————Sobel算子
# 计算Sobel卷积结果
x = cv.Sobel(img, cv.CV_16S, 1, 0)  # 水平方向
y = cv.Sobel(img, cv.CV_16S, 0, 1)  # 垂直方向
# 转换数据并合成
Scale_absX = cv.convertScaleAbs(x)  # 格式转换函数
Scale_absY = cv.convertScaleAbs(y)
Scale_absXY = cv.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)  # 图像混合
# 阈值化
ret, Scale_absX = cv.threshold(Scale_absX, 0, 255, cv.THRESH_BINARY_INV)
ret, Scale_absY = cv.threshold(Scale_absY, 0, 255, cv.THRESH_BINARY_INV)
ret, Scale_absXY = cv.threshold(Scale_absXY, 0, 255, cv.THRESH_BINARY_INV)
# 显示图像
pic = [img, Scale_absX, Scale_absY, Scale_absXY]
showImg(pic, 0)

# %%——————————prewitt算子
kernel_X = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])
kernel_Y = np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]])
x = cv.filter2D(img, cv.CV_16S, kernel_X)
x = cv.convertScaleAbs(x)
y = cv.filter2D(img, cv.CV_16S, kernel_Y)
y = cv.convertScaleAbs(y)
xy = cv.addWeighted(x, 0.5, y, 0.5, 0)
xy = cv.convertScaleAbs(xy)
ret, x = cv.threshold(x, 0, 255, cv.THRESH_BINARY_INV)
ret, y = cv.threshold(y, 0, 255, cv.THRESH_BINARY_INV)
ret, xy = cv.threshold(xy, 0, 255, cv.THRESH_BINARY_INV)

pic = [img, x, y, xy]
showImg(pic, 1)

# %% ——————————Roberts算子
kernel_X = np.array([[-1, 0], [0, 1]])
kernel_Y = np.array([[0, -1], [1, 0]])
x = cv.filter2D(img, cv.CV_16S, kernel_X)
x = cv.convertScaleAbs(x)
y = cv.filter2D(img, cv.CV_16S, kernel_Y)
y = cv.convertScaleAbs(y)
xy = cv.addWeighted(x, 0.5, y, 0.5, 0)
xy = cv.convertScaleAbs(xy)
ret, x = cv.threshold(x, 0, 255, cv.THRESH_BINARY_INV)
ret, y = cv.threshold(y, 0, 255, cv.THRESH_BINARY_INV)
ret, xy = cv.threshold(xy, 0, 255, cv.THRESH_BINARY_INV)

pic = [img, x, y, xy]
showImg(pic, 2)

 

 

 2、使用手动阈值分割法对bottle图像进行分割,显示分割结果,并分析其优缺点。

import matplotlib.pyplot as plt
import cv2 as cv

src = cv.imread("bottle.png", 0)
img = src.copy()
# 计算直方图
greyScale_map = cv.calcHist([img], [0], None, [256], [0, 256])
# 阈值分割
ret, result = cv.threshold(img, 150, 255, cv.THRESH_BINARY)
# 显示图像
plt.subplot(211)
plt.plot(greyScale_map)
plt.subplot(223)
plt.axis("off")
plt.title("原图")
plt.imshow(img, cmap=plt.cm.gray)
plt.subplot(224)
plt.axis("off")
plt.title("阈值分割后的图像")
plt.imshow(result, cmap=plt.cm.gray)
plt.tight_layout()
plt.show()

 3、对下图A进行处理,得到类似图B的样子;

import matplotlib.pyplot as plt
import cv2 as cv

img = cv.imread("img.png", 0)
img_Canny = cv.Canny(img, 220, 250)
ret, result = cv.threshold(img_Canny, 0, 255, cv.THRESH_BINARY_INV)

# 显示图像
plt.subplot(121)
plt.axis("off")
plt.imshow(img, cmap=plt.cm.gray)
plt.subplot(122)
plt.axis("off")
plt.imshow(result, cmap=plt.cm.gray)
plt.show()

      

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐