二值化处理与边缘检测

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二值化处理与边缘检测相关的知识,希望对你有一定的参考价值。

参考技术A

问题: 我在提取图像边缘的时候,首先对图像进行灰度变换,之后进行二值处理,最后进行边缘检测得到边缘图像。
但是在查阅资料的过程中我经常发现很多人忽略二值化的步骤,直接进行边缘检测;还有很多人在实现某些功能的时候先进行边缘检测之后再阈值分割,让我感到非常迷惑,这篇文章旨在探求二者的关系。

首先要知道图像二值化和边缘检测的目的。

图像的阈值处理一般使得图像的像素值更单一、图像更简单。阈值可以分为全局阈值和局部阈值,可以是单阈值也可以是多阈值。
图像二值化是设置单阈值,为了将图像中感兴趣的像素分离出来作为前景像素,不感兴趣的部分作为背景像素。

最简单的二值化操作是使用以下函数:(这是全局化的阈值)

上述的二值化处理是设置一个全局阈值,让所有像素值与该阈值比较,下面还可以通过自适应阈值实现图像的二值化处理。
自适应阈值不需要确定一个固定的阈值,根据其对应的自适应方法,通过图像的局部特征自适应的设定阈值,做出二值化处理。
自适应阈值是一种局部阈值,要在图像中确定一个区域,求出该区域内的像素平均值,再与阈值比较

adaptiveMethod - 指定计算阈值的方法。
  cv2.ADPTIVE_THRESH_MEAN_C:阈值取相邻区域的平均值
  cv2.ADPTIVE_THRESH_GAUSSIAN_C:阈值取相邻区域的加权和,权重为一个高斯窗口。

thresholdType - 和上面一样
blockSize - 邻域大小(用来计算阈值的区域大小),计算图像的像素区域一般取3×3、5×5、7×7.....
C - 常数,阈值等于平均值或者加权平均值减去这个常数。该参数用于微调阈值,可以为负数

还有一种非常多人提及的方法——Otsu’s 二值化,这种方法下次再记录。

要对图像进行边缘检测,首先对图像进行灰度变换,使图像只包含一个通道的信息,然后比较各相邻像素间的亮度差别,亮度产生突变的地方就是边缘像素,将这些边缘像素点连接到一起就形成了边缘图像。
那么首先要知道如何检测出边缘:
边缘有方向和幅值两个要素,通常对图像相邻域像素求取梯度来描述和检测边缘。
为何要求梯度?
图像梯度是对多个方向分别求偏导得到的导数组。比如下图是亮度在x方向上变化,在y方向上没有变化,所以此时只需对x求偏导,该处关于y的偏导为0。

同样图像的亮度在y轴变化时,x方向的偏导为0。

我们知道,当一个函数在某处变化大的时候,它的导数在该处得到极值。

可以看到,图像由亮变暗时函数陡然下降,导数得到极小值,由暗变亮时函数又陡然上升,导数得到极大值,接下来只要找到导数的峰值就行。

这里主要了解Canny边缘检测算法。
Canny算子首先对图像进行平滑滤波,滤除图像的噪声以减少噪声对图像边缘检测的干扰。
下面这两篇文章对Canny算子的介绍非常清晰,在此附上链接以供学习。
https://www.cnblogs.com/techyan1990/p/7291771.html
https://www.cnblogs.com/wjy-lulu/p/6672871.html?utm_source=itdadao&utm_medium=referral
在进行边缘检测之前至少要将图像灰度化,因为梯度运算并不能反映色彩的变化差异,所以转换成只有一种颜色通道的灰度图像能够更好地进行边缘检测。

深入了解过图像二值化和边缘检测之后,我认为既可以直接使用灰度图像进行边缘检测,也可以二值化之后再进行边缘检测,二值化的目的是进一步简化灰度图像,使图像中的信息更加纯粹,边缘亮度变化更加明显。如果阈值选的较好还可以滤除不需要的弱边缘,使边缘处理后的图像轮廓更加清晰。

还有一种方法是先进行边缘检测,再二值化,这种情况一般适用于:
想得到二值化图像,但由于原图出现光照不均、前景和背景灰度差别很小等情况,我们不能直接得到完整的目标,这时就可以利用边缘检测对光线变化的不敏感性,先对图像作边缘检测,检测出我们想要进一步研究的目标轮廓,然后再根据只有边缘的图像,求出原图像所有边缘点的像素平均值,将该值作为阈值对原图像进行二值处理,就能很好得获得目标区域,并且目标区域的连通性也很好。

笔者刚刚开始学习图像处理与计算机视觉,可能会出现许多错误,欢迎各位提出改进意见!

OpenCV-Python系列—— 图像处理(灰度图二值化边缘检测高斯模糊轮廓检测)

一、【灰度图、二值化】

import cv2
img = cv2.imread("lz2.png")
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)   # 灰度图
# 二值化,(127,255)为阈值
retval,bit_img = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY)
cv2.imshow('photo1',img)
cv2.imshow('photo2',gray_img)
cv2.imshow('photo3',bit_img)
cv2.waitKey(0)

二、【边缘检测】

import cv2
img = cv2.imread("l2.png")
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)   # 灰度图
img_b = cv2.Canny(img, 38,180,apertureSize=3)    # (38,180)为阈值
img_c = cv2.Canny(img, 38,180,apertureSize=5)
cv2.imshow('photo1',img)
cv2.imshow('photo2',img_b)
cv2.imshow('photo3',img_c)
cv2.waitKey(0)

三、高斯滤波

import cv2
img = cv2.imread("lz2.png")
# 高斯滤波
blurred = cv2.GaussianBlur(img, (21, 21), 0)  #(21,21)越高越模糊,只能设置为奇数
cv2.imshow('photo1',img)
cv2.imshow('photo2',blurred)
cv2.waitKey(0)

四、【轮廓检测】

【方法一:步骤】
第一步:载入图片
第二步:使用cv2.cvtcolor() 将图片转换为灰度图
第三步: 使用cv2.threshold将图片做二值化转换
第四步:使用cv2.findContours 找出图片的轮廓值
第五步:使用cv2.drawContours在图片上画上轮廓
第六步: 使用cv2.imshow 显示

import cv2
# 第一步,读入照片
img = cv2.imread("lz2.png")
contours_img = img.copy()
# 第二步,转灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)		# 转换为灰度图
# 第三步,二值化处理
retval,bit_img = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY)		# 高斯滤波-去除噪音
# 第四步,寻找轮廓
cnts, hierarchy = cv2.findContours(bit_img.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 第五步,绘画轮廓
ret_img = cv2.drawContours(contours_img, cnts, -1, (0, 0, 255), 3)
# 显示图片
cv2.imshow('photo',ret_img)
cv2.waitKey(0)

【方法二:步骤】
第一步,读入照片 cv2.imread()
第二步,转灰度图 cv2.cvtColor()
第三步,高斯去噪 cv2.GaussianBlur()
第四步,边缘检测 cv2.Canny()
第五步,寻找轮廓 cv2.findContours()
第六步,绘画轮廓 cv2.drawContours()

import cv2
# 第一步,读入照片
img = cv2.imread("lz2.png")
contours_img = img.copy()
# 第二步,转灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)		# 转换为灰度图
# 第三步,高斯去噪
blurred_img = cv2.GaussianBlur(gray_img, (5, 5), 0)			# 高斯滤波-去除噪音
# 第四步,边缘检测
edged_img = cv2.Canny(blurred_img, 75, 200)					# Canny算子边缘检测
# 第五步,寻找轮廓
cnts, hierarchy = cv2.findContours(edged_img.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 第六步,绘画轮廓
ret_img = cv2.drawContours(contours_img, cnts, -1, (0, 0, 255), 3)
# 显示图片
cv2.imshow('photo5',ret_img)
cv2.waitKey(0)

以上是关于二值化处理与边缘检测的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV入门指南第四篇 图像的二值化

OpenCV-Python系列—— 图像处理(灰度图二值化边缘检测高斯模糊轮廓检测)

使用openCV进行边缘检测二值化轮廓轮廓检测BGR灰度图二值化,专栏:各种openCV实践的案例

MATLAB进行边缘检测

基于opencv的边缘检测方法

opencv 检测图像边缘 Canny算法应用