【深度好文】Python图像处理之目标物体轮廓提取

1 引言

目标物体的边缘对图像识别和计算机分析十分有用。边缘可以勾画出目标物体,使观察者一目了然;边缘蕴含了丰富的内在信息(如方向、形状等),是图像识别中抽取图像特征的重要属性。轮廓提取是边界分割中非常重要的一种处理,同时也是图像处理的经典难题,轮廓提取和轮廓跟踪的目的都是获得图像的外部轮廓特征。

2 原理

二值图像的轮廓提取的原理非常简单,就是掏空内部点:如果原图中有一点为黑,且它的8个相邻点皆为黑色,则将该点删除。对于非二值图像,需要先进行二值化处理。轮廓提取的方法有很多,在这里我们介绍一种最基本、最简单容易实现的算法。算法原理如下:

  • 在进行轮廓提取时,使用一个一维数组,用来记录处理的像素点的周围8邻域的信息
  • 若8个邻域的像素点的灰度值和中心点的灰度值相同,则认为该点在物体的内部,可以删除;
  • 否则,认为该点在图像的边缘,需要保留。
  • 依次处理图像中每一个像素,则最后留下来的就是图像的轮廓。

3 Python实现

  1. 读入彩色图像
img_name = "./20210808/sample3.png"
img = cv2.imread(img_name)

结果如下:
请添加图片描述
2) 彩色图像灰度化

gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

结果如下:

请添加图片描述
3)二值化

def get_binary_img(img):
    # gray img to bin image
    bin_img = np.zeros(shape=(img.shape), dtype=np.uint8)
    h = img.shape[0]
    w = img.shape[1]
    for i in range(h):
        for j in range(w):
            bin_img[i][j] = 255 if img[i][j] > 127 else 0
    return bin_img
# 调用
bin_img = get_binary_img(gray_img)

结果如下:
请添加图片描述

4)提取轮廓
参考上述原理,进行实现,代码如下:

def get_contour(bin_img):
    # get contour
    contour_img = np.zeros(shape=(bin_img.shape),dtype=np.uint8)
    contour_img += 255
    h = bin_img.shape[0]
    w = bin_img.shape[1]
    for i in range(1,h-1):
        for j in range(1,w-1):
            if(bin_img[i][j]==0):
                contour_img[i][j] = 0
                sum = 0
                sum += bin_img[i - 1][j + 1]
                sum += bin_img[i][j + 1]
                sum += bin_img[i + 1][j + 1]
                sum += bin_img[i - 1][j]
                sum += bin_img[i + 1][j]
                sum += bin_img[i - 1][j - 1]
                sum += bin_img[i][j - 1]
                sum += bin_img[i + 1][j - 1]
                if sum ==  0:
                    contour_img[i][j] = 255

    return contour_img
# 调用    
contour_img = get_contour(bin_img)

结果如下:
请添加图片描述

4 总结

通过上述简单步骤,我们实现了物体轮廓提取,相应的处理效果如下:
请添加图片描述
上图中 左侧为原图,右侧为我们提取的物体轮廓图。

### 使用Python深度学习技术实现图像轮廓提取 #### 方法概述 为了利用深度学习进行图像轮廓提取,可以采用预训练的卷积神经网络(CNN),这些模型能够自动捕捉到复杂的模式并有效地表示图像中的边缘和其他重要特征。具体来说,在处理人脸这样的特定对象时,Dlib库提供了基于HOG特征和支持向量机(SVM)的人脸检测功能;而对于更加通用的情况,则可借助于U-Net架构或其他专门设计用来分割物体边界的深层网络。 #### 实现方案 对于想要尝试此过程的人来说,下面是一个简单的例子来展示怎样运用Keras框架下的Unet模型来进行二值化掩码预测——即得到目标区域与其周围环境之间的清晰界限: ```python from keras.models import Model, load_model from keras.layers import Input from keras.layers.core import Dropout, Lambda from keras.layers.convolutional import Conv2D, Conv2DTranspose from keras.layers.pooling import MaxPooling2D from keras.layers.merge import concatenate import numpy as np import cv2 def unet(pretrained_weights=None, input_size=(256, 256, 1)): inputs = Input(input_size) c1 = Conv2D(16, (3, 3), activation='relu', kernel_initializer='he_normal', padding='same')(inputs) p1 = MaxPooling2D((2, 2))(c1) # 中间层省略... outputs = Conv2D(1, (1, 1), activation='sigmoid')(u9) model = Model(inputs=[inputs], outputs=[outputs]) if pretrained_weights is not None: model.load_weights(pretrained_weights) return model img = cv2.imread('path_to_image.jpg',0)/255. img_input = img.reshape((1,) + img.shape+(1,)) model = unet() result = model.predict(img_input)[0,:,:,0]*255. cv2.imwrite("output_contour.png", result.astype(np.uint8)) ``` 上述代码片段定义了一个基础版本的UNet结构,并加载了一张灰度图片作为输入,经过前向传播计算后输出对应的轮廓图[^1]。 此外,还可以考虑使用其他流行的开源工具包如OpenCV配合TensorFlow或PyTorch等平台提供的API接口完成相似的任务。例如,通过调用`cv2.Canny()`函数先获取初步的边界信息再送入后续精炼模块做进一步优化处理。 值得注意的是,当涉及到复杂场景下的人物面部识别任务时,除了依赖传统的机器学习算法外,现在越来越多的研究倾向于探索端到端的学习方式,比如FaceNet、DeepID系列等工作都取得了很好的成果。这类方法通常会构建大规模的数据集用于监督式训练,从而让系统学会区分不同个体间的细微差别同时保持对各种干扰因素的良好适应能力[^3]。 最后提到的一个有趣的应用案例就是结合IPyPlot这种可视化辅助类库可以在Jupyter notebook环境中直观地观察多幅样本及其对应标签的变化趋势,这对于调试参数设置以及评估性能指标有着不可忽视的帮助价值[^2]。
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵卓不凡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值