目录
一.概述
二.灰度阈值分割
三.基于边界的图像分割
学习视频
图像分割的困难
基本原理
上面的f(x,y)是某点的像素,即灰度值
如上图就人工根据直方图对阈值进行了确定(125)
*函数说明:
cv.threshold(src, thresh, maxval, type, dst=None)
thresh:Double类型的,具体的阈值。
maxval:Double类型的,阈值的最大值
THRESH_BINARY 二进制阈值化 -> 大于阈值为1 小于阈值为0
THRESH_BINARY_INV 反二进制阈值化 -> 大于阈值为0 小于阈值为1
THRESH_TRUNC 截断阈值化 -> 大于阈值为阈值,小于阈值不变
THRESH_TOZERO 阈值化为0 -> 大于阈值的不变,小于阈值的全为0
THRESH_TOZERO_INV 反阈值化为0 -> 大于阈值为0,小于阈值不变
threshold和adaptiveThreshold的区别戳这里
# -*- coding:utf-8
import cv2 as cv
from matplotlib import pyplot as plt
from PIL import Image,ImageFont,ImageDraw
image = cv.imread('/home/image/Pictures/rst.jpg', 0)
if image is None:
im=Image.open('/home/image/Pictures/lena300.jpg',mode="r")
draw=ImageDraw.Draw(im)
f=ImageFont.truetype(font='/usr/share/fonts/gnu-free/LiberationMono-Italic.ttf',size=35)
txt='''please check
the path
of image !!!
modify it!!!!
'''
draw.text((30,20),txt,font=f,fill=(255,0,0))
im.show()
blurred = cv.GaussianBlur(image, (5, 5), 0)
(retval, thresh) = cv.threshold(blurred, 155, 255, cv.THRESH_BINARY)
(retval1, threshInv) = cv.threshold(blurred, 155, 255, cv.THRESH_BINARY_INV)
thresh1 = cv.adaptiveThreshold(blurred, 255,cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY_INV, 11, 4)
thresh2 = cv.adaptiveThreshold(blurred, 255,cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 15, 3)
filenames=[thresh,threshInv,thresh1,thresh2]
names=['binaryzation','binaryReverse','adaptiveMean','adaptiveGaussian']
for i in range(4):
plt.subplot(2,2,i+1),plt.imshow(filenames[i],cmap='gray'),plt.title(names[i])
plt.xticks([]),plt.yticks([])
plt.show()
效果还可
原图:
基于双峰形直方图的阈值选取
1. 利用极大值和极小值寻找谷底及其阈值
首先求图像f(x,y)的直方图P(f ),在该直方图具有双峰特征的情况下,接着在直方图P( f )上找出两个局部极大值(或最大值),并设这两个局部极大值的位置分别为ri 和rj ;然后找出位于ri 和rj 之间的具有最小值P(rT)的点rT ,也即对于直方图上所有满足ri≤rT≤rj 的位置点,有P(ri)≤P(rT)≤P(rj)。
接下来可以进一步测定直方图双极性的强弱,也即计算:
当KT的值较小,说明谷低峰高,就认为在该直方图的两个峰值之间存在一个有用的阈值Kt,并可以将其作为进行基于阈值的图像分割方法的一个可用的阈值;
当Kt的值较大,特别是接近1时,说明谷和峰的高度比较接近,说明该直方图的双极性较弱,这时若利用阈值KT进行基于阈值的图像分割,显然很难得到满意的分割效果。
2. 双峰形直方图谷底阈值的获取
通常情况下由于直方图呈锯齿形状,这时,需要利用某些解析函数对双峰之间的直方图进行拟合(curve fitting),并通过对拟合函数求微分获得最小值。
最小二乘方曲线拟合
2. 双峰形直方图谷底阈值的获取(续)
(a)用1个二次曲线拟合谷底 (b)用2个二次曲线拟合谷底
图9.13 用二次曲线拟合双峰形直方图的谷底示例
1、图像边缘的概念
图像边缘意味着图像中一个区域的终结和另一个区域的开始。
图像中相邻区域之间的像素集合构成了图像的边缘。是指图像灰度发生空间突变的像素的集合。更具体地来说,图像中以灰度值表征的两平滑区域之间的振幅断续称为边缘。
图9.1 图像的边缘特征示意图
2、图像边缘的特点
图像边缘的特点是两侧的灰度在通过边缘时将发生某种显著的变化。
(a)边缘的理想阶跃截面 (b)实际中的边缘阶跃截面
图9.2 图像中的边缘的截面示意图
3、基于边缘检测的图像分割方法的基本思路
基本思路是先确定图像中的边缘像素,然后把它们连接在一起构成所需的边界。
常用技术:Hough变换
*函数说明:
标准霍夫线变换:HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0 )
image:边缘检测的输出图像. 它应该是个灰度图 (但事实上是个二值化图)
lines:储存着检测到的直线的参数对( )的容器
rho:参数极径 以像素值为单位的分辨率. 我们使用 1 像素.
theta:参数极角 以弧度为单位的分辨率. 我们使用 1度 (即CV_PI/180)
theta:要”检测” 一条直线所需最少的的曲线交点
srn and stn: 参数默认为0.
统计霍夫线变换:HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold,double minLineLength=0, double maxLineGap=0 )
image: 边缘检测的输出图像. 它应该是个灰度图 (但事实上是个二值化图) *
lines: 储存着检测到的直线的参数对(Xstart,Ystart,Xend,Yend)的容器,也就是线段两个端点的坐标
rho : 参数极径 以像素值为单位的分辨率. 我们使用 1 像素.
theta: 参数极角 以弧度为单位的分辨率. 我们使用 1度 (即CV_PI/180)
threshold: 要”检测” 一条直线所需最少的的曲线交点
minLinLength: 能组成一条直线的最少点的数量. 点数量不足的直线将被抛弃.线段的最小长度
maxLineGap:线段上最近两点之间的阈值
HoughCircles(image, method, dp, minDist, circles=None, param1=None, param2=None, minRadius=None, maxRadius=None)
其中:
image:8位,单通道图像。如果使用彩色图像,需要先转换为灰度图像。
method:定义检测图像中圆的方法。目前唯一实现的方法是cv2.HOUGH_GRADIENT。
dp:累加器分辨率与图像分辨率的反比。dp获取越大,累加器数组越小。
minDist:检测到的圆的中心,(x,y)坐标之间的最小距离。如果minDist太小,则可能导致检测到多个相邻的圆。如果minDist太大,则可能导致很多圆检测不到。
param1:用于处理边缘检测的梯度值方法。
param2:cv2.HOUGH_GRADIENT方法的累加器阈值。阈值越小,检测到的圈子越多。
minRadius:半径的最小大小(以像素为单位)
maxRadius:半径的最大大小(以像素为单位)
函数原型: void GaussianBlur( InputArray src, OutputArray dst, Size ksize,double sigmaX, double sigmaY = 0,int borderType = BORDER_DEFAULT );
参数详解:
InputArray src-----源图像
OutputArray dst-----目标图像
Size ksize----高斯内核大小,其中ksize.width和ksize.height可以不同,但是必须为正数和奇数,也可为零,均有sigma计算而来。
double sigmaX----表示高斯函数在X方向的标准偏差
double sigmaY---- 表示高斯函数在Y方向的标准偏差
若sigma为零,就将它设为sigmaX,如果两者均为零,就由ksize.width
和ksize.height计算出来。
int borderType -----用于推断图像外部像素的某种边界模式。
默认值 BORDER_DEFAULT */