image segmentation

目录

 一.概述

 二.灰度阈值分割

三.基于边界的图像分割


学习视频

 一.概述

image segmentation_第1张图片

image segmentation_第2张图片

image segmentation_第3张图片

图像分割的困难

image segmentation_第4张图片

image segmentation_第5张图片

image segmentation_第6张图片

 基本原理

image segmentation_第7张图片

image segmentation_第8张图片

image segmentation_第9张图片

image segmentation_第10张图片

image segmentation_第11张图片


 二.灰度阈值分割

image segmentation_第12张图片

image segmentation_第13张图片

上面的f(x,y)是某点的像素,即灰度值

image segmentation_第14张图片

image segmentation_第15张图片

image segmentation_第16张图片

如上图就人工根据直方图对阈值进行了确定(125)

image segmentation_第17张图片

*函数说明:

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()

效果还可

原图:

image segmentation_第18张图片

image segmentation_第19张图片

image segmentation_第20张图片

image segmentation_第21张图片

image segmentation_第22张图片

image segmentation_第23张图片

image segmentation_第24张图片

image segmentation_第25张图片

image segmentation_第26张图片

image segmentation_第27张图片

image segmentation_第28张图片

基于双峰形直方图的阈值选取

1. 利用极大值和极小值寻找谷底及其阈值

首先求图像f(x,y)的直方图P(f ),在该直方图具有双峰特征的情况下,接着在直方图P( f )上找出两个局部极大值(或最大值),并设这两个局部极大值的位置分别为ri 和rj ;然后找出位于ri 和rj 之间的具有最小值P(rT)的点rT ,也即对于直方图上所有满足ri≤rT≤rj 的位置点,有P(ri)≤P(rT)≤P(rj)。

接下来可以进一步测定直方图双极性的强弱,也即计算:

image segmentation_第29张图片

  当KT的值较小,说明谷低峰高,就认为在该直方图的两个峰值之间存在一个有用的阈值Kt,并可以将其作为进行基于阈值的图像分割方法的一个可用的阈值;
      当Kt的值较大,特别是接近1时,说明谷和峰的高度比较接近,说明该直方图的双极性较弱,这时若利用阈值KT进行基于阈值的图像分割,显然很难得到满意的分割效果。

image segmentation_第30张图片

2. 双峰形直方图谷底阈值的获取

通常情况下由于直方图呈锯齿形状,这时,需要利用某些解析函数对双峰之间的直方图进行拟合(curve fitting),并通过对拟合函数求微分获得最小值。

设有二次曲线方程:(9.13)

对应于直方图双峰之间的最小值谷底阈值就为:image segmentation_第31张图片

最小二乘方曲线拟合

2. 双峰形直方图谷底阈值的获取(续)

image segmentation_第32张图片

(a)用1个二次曲线拟合谷底                     (b)用2个二次曲线拟合谷底

             图9.13  用二次曲线拟合双峰形直方图的谷底示例


三.基于边界的图像分割

image segmentation_第33张图片

1、图像边缘的概念

图像边缘意味着图像中一个区域的终结和另一个区域的开始。
    图像中相邻区域之间的像素集合构成了图像的边缘。是指图像灰度发生空间突变的像素的集合。更具体地来说,图像中以灰度值表征的两平滑区域之间的振幅断续称为边缘。

image segmentation_第34张图片

图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           */

 

 

你可能感兴趣的:(CV)