【第三章:OpenCv阈值分割/二值化(单通道、多通道图片)总结】

第三章:OpenCv阈值分割/二值化(单通道、多通道图片)总结

  • 0.前言
  • 1.基础知识
    • 1.1 什么是算子
    • 1.2 图像处理中的图像分割技术
    • 1.3 单通道图片的阈值分割
    • 1.4 推荐文章链接
  • 2. 灰度图分割
    • 2.1 灰度直方图
    • 2.2 简单阈值分割与大津二值化分割
  • 3.分离常见色彩空间下的单通道图片
  • 4. HSV分割
    • 4.1 常见分割代码
    • 4.2 技巧性1,通过鼠标感应,获取某个像素的的HSV像素值
    • 4.2 最佳技巧性工具:借助滑动条,快速实现基于颜色的目标识别
    • 4.3. 扩展1:扩展滑动条数量,进行多颜色识别
    • 4.4 扩展2:BGR色彩空间下的颜色识别
  • 总结

0.前言

  • 对一些算法的基本概念以及原理,本文不做过多的阐述,本文将一些相关基础知识以超链接的形式放在文章开头,大家根据需要进行挑选阅读,有基础的朋友可以直接跳过。

1.基础知识

1.1 什么是算子

  • 什么是算子: 高等数学上册P2中有这样的描述,算子即映射。可理解为从图像中的离散像素点集合通过某种关系,映射到另一个集合即可。

    【第三章:OpenCv阈值分割/二值化(单通道、多通道图片)总结】_第1张图片
图1.1.1 算子即映射


1.2 图像处理中的图像分割技术

  • 对于图像处理中常见的分割,我这里做了个人的总结,同时,第三章主要以阈值分割为主,以及一些技巧的分享。在后面章节,会分享粘连物体的分割。

    【第三章:OpenCv阈值分割/二值化(单通道、多通道图片)总结】_第2张图片
图1.2.1 图像处理中的分割

1.3 单通道图片的阈值分割

  • 注意:只要是单通道图片,就能进行二值化。 这里的单通道图片主要以Gray灰度图为主,但是在一些检测当中,需要用到其他色彩空间某些单通道的图片进行分割(因为某通道特征可能更为明显,更好分割)。后文会贴上程序,如何分离一张图片所有色彩空间下所有单通道图片。

  • 下面展示的是常用在单通道图片阈值分割的二值化算法
    【第三章:OpenCv阈值分割/二值化(单通道、多通道图片)总结】_第3张图片

    【第三章:OpenCv阈值分割/二值化(单通道、多通道图片)总结】_第4张图片
图1.3.1 单通道图片二值化常用方法

1.4 推荐文章链接

  • 推荐文章1:多种色彩空间RGB、BGR、HSV /HSB、HSL、YUV的基本简介

  • 推荐文章2:多种边缘检测算法(Sobel算子、Isotropic Sobel算子、Roberts算子、Prewitt算子、Laplacian算子、Canny算子)介绍及比较

  • 推荐文章3:图像二值化方法汇总

  • 推荐文章4:图像二值化

  • 推荐文章5:多阈值 OTSU 处理方法

  • 推荐文章6:大津二值化



2. 灰度图分割

  • 个人比较常用的二值化算法是:简单二值化、大津二值化算法(图片亮度不均匀也能比较好分割)。其中简单二值化选取的阈值有时候可以借助灰度直方图,可以使阈值选取更为恰当,
  • 当图片有以下特点时可以考虑用灰度图分割: 检测物体对色彩特征没有要求,同时物体与背景像素值相差比较大。

2.1 灰度直方图

# 作者:OpenCv机器视觉
# 时间:2023/1/5
# 功能:灰度、BGR像素直方图
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt


# 绘制灰度直方图
def plot_demo(image):
    """
    画灰度图直方图:
    绘图都可以调用matplotlib.pyplot库来进行,其中的hist函数可以直接绘制直方图。
    plt.hist(arr, bins=50, normed=1, facecolor='green', alpha=0.75)
    hist的参数非常多,但常用的就这五个,只有第一个是必须的,后面四个可选
    arr: 需要计算直方图的一维数组
    bins: 直方图的柱数,可选项,默认为10
    normed: 是否将得到的直方图向量归一化。默认为0
    range参数表示箱子的下限和上限。即横坐标显示的范围,范围之外的将被舍弃
    """
    plt.hist(image.ravel(), 256, [0, 256],color="black")  # image.ravel()#ravel函数功能是将多维数组降为一维数组,统计各个bin的频次,256:bin的个数,[0, 256]:范围
    plt.show()  # 和OpenCV中的想要的直方图不同




def image_hist(image):
    """
    calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
    images参数表示输入图像,传入时应该用中括号[ ]括起来
    channels参数表示传入图像的通道,如果是灰度图像,那就不用说了,只有一个通道,值为0,
    如果是彩色图像(有3个通道),那么值为0,1,2,中选择一个,对应着BGR各个通道。这个值也得用[ ]传入。
    mask参数表示掩膜图像。如果统计整幅图,那么为None。
    主要是如果要统计部分图的直方图,就得构造相应的掩膜来计算。
    histSize参数表示灰度级的个数,需要中括号,比如[256]
    ranges参数表示像素值的范围,通常[0,256]。此外,假如channels为[0,1],ranges为[0,256,0,180],
    则代表0通道范围是0-256,1通道范围0-180。
    hist参数表示计算出来的直方图。
    """
    color = ('blue', 'green', 'red')  # 图像三通道
    for i, color in enumerate(color):
        hist = cv.calcHist([image], [i], None, [256], [0, 256])  # 绘制各个通道的直方图
        plt.plot(hist, color=color)  # 定义线的颜色
        plt.xlim([0, 256])  # x轴的范围
    plt.show()




src = cv.imread("img/1.png")
cv.namedWindow("input image",0)
cv.imshow("input image", src)

gray = cv.cvtColor(src,cv.COLOR_BGR2GRAY)
# 灰度直方图
plot_demo(gray)
# BGR像素直方图
image_hist(src)

cv.waitKey(0)
cv.destroyAllWindows()

  • 图片特征分析:不需要颜色特征,所以直接对其灰度图分割即可。根据灰度像素直方图可得我们得阈值设置在40-125左右即可。

    【第三章:OpenCv阈值分割/二值化(单通道、多通道图片)总结】_第5张图片

    图2.1 灰度像素直方图


2.2 简单阈值分割与大津二值化分割

  • 代码,这里包含了简单阈值分割,自适应阈值分割、大津分割算法代码(代码涉及到python面向对象的知识点)。
# 作者:OpenCv机器视觉
# 时间:2023/1/5
# 功能:简单阈值分割,自适应阈值分割、大津分割算法代码
import cv2 as cv



class GetBinary(object):
    def __init__(self,img):
        self.img = img

    def threshed_fixed(self):
        """
        :function:利用固定阈值进行二值化
        :return:
        """

        blurred = cv.blur(self.img, (5,5))  # 这里进行5x5卷积核的均值滤波处理
        gray = cv.cvtColor(blurred,cv.COLOR_BGR2GRAY)

        ret,bin = cv.threshold(gray,100,255,cv.THRESH_BINARY)
        return bin
    def adaptive_threshold(self):
        """
        :function:利用自适应局部二值化方法进行二值化
        :return:
        """
        blurred = cv.blur(self.img, (5,5))  # 这里进行5x5卷积核的均值滤波处理
        gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)
        bin = cv.adaptiveThreshold(src=gray,maxValue=255,adaptiveMethod=cv.ADAPTIVE_THRESH_MEAN_C,thresholdType=cv.THRESH_BINARY,blockSize=31,C=1)
        return bin


    def threshed_otsus(self):
        """
        :function:利用OTSU's二值化算法阈值进行二值化
        :return:
        """
        blurred = cv.blur(self.img, (5, 5))  # 这里进行5x5卷积核的均值滤波处理
        gray = cv.cvtColor(blurred,cv.COLOR_BGR2GRAY)
        ret,bin=  cv.threshold(gray,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
        return bin


img = cv.imread(".\\img\\1.png")
# 定义一个对象
get_binary = GetBinary(img)
# 调用对象中的方法
bin1 = get_binary.threshed_fixed()      # 简单阈值分割
bin2 = get_binary.adaptive_threshold()  # 自适应阈值分割
bin3 = get_binary.threshed_otsus()      # 大津算法分割




cv.namedWindow("img",0)
cv.imshow("img",img)

cv.namedWindow("threshed_fixed",0)
cv.imshow("threshed_fixed",bin1)
cv.namedWindow("adaptive_threshold",0)
cv.imshow("adaptive_threshold",bin2)
cv.namedWindow("threshed_otsus",0)
cv.imshow("threshed_otsus",bin3)


cv.waitKey(0)
cv.destroyAllWindows()

图2.2 简单阈值分割与大津二值化分割分割效果

  • 参考链接

1.灰度直方图、BGR像素直方图

2.matplotlib画图基本操作



3.分离常见色彩空间下的单通道图片

  • 背景意义:当彩色图片下的目标与背景区分度不是很高,这时候我们可以考虑分离各通道下的图片,观察在哪个通道下的特征比较明显,便于后期的阈值分割。这里举例子的是某课题细胞分割图片。

【第三章:OpenCv阈值分割/二值化(单通道、多通道图片)总结】_第6张图片

图3.1 某细胞图片


  • 代码
# 作者:OpenCv机器视觉
# 时间:2023/1/6
# 功能:获取HSV 、LAB、HIS、LUV、YUV色彩空间下各单通道图片
import cv2 as cv
import os




def split_all_chancel(img):

    # 色彩空间转换
    gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    HSV = cv.cvtColor(img, cv.COLOR_BGR2HSV)
    LAB = cv.cvtColor(img, cv.COLOR_BGR2LAB)
    HIS = cv.cvtColor(img, cv.COLOR_BGR2HLS)
    LUV = cv.cvtColor(img, cv.COLOR_BGR2LUV)
    YUV = cv.cvtColor(img, cv.COLOR_BGR2YCrCb)

    # 对各图片通道进行拆分
    bgr_b, bgr_g, bgr_r = cv.split(img)
    hsv_h, hsv_s, hsv_v = cv.split(HSV)
    lab_l, lab_a, lab_b = cv.split(LAB)
    his_h, his_i, his_s = cv.split(HIS)
    luv_l, luv_u, luv_v = cv.split(LUV)
    yuv_y, yuv_u, yuv_v = cv.split(YUV)
    return  ([hsv_h, hsv_s, hsv_v,lab_l, lab_a, lab_b,  his_h, his_i, his_s,luv_l, luv_u, luv_v,yuv_y, yuv_u, yuv_v,bgr_b, bgr_g, bgr_r,gray],
            ["hsv_h"," hsv_s", "hsv_v","lab_l", "lab_a", "lab_b",  "his_h", "his_i", "his_s","luv_l", "luv_u", "luv_v","yuv_y", "yuv_u", "yuv_v","bgr_b","bgr_g","bgr_r","gray"])


# 原图片路径
img_path = ".\\img\\2.jpg"

img = cv.imread(img_path)                       # 读取图片
name = os.path.splitext(img_path)[0]            # 图片文件名
extend_name = os.path.splitext(img_path)[-1]    # 图片扩展名
if not os.path.exists(name):                    # 判断以图片名 为命名的文件夹是否存在
    os.makedirs(name)                           # 不存在就创建文件夹,用于存放图片

# 调用分离通道函数
channels_imgs,channel_str = split_all_chancel(img)
for i, channels_img in enumerate(channels_imgs):
    out_name = os.path.join(name,channel_str[i]+".png")   # 保存路径,为图片相同路径下
    print(out_name)
    cv.imwrite(out_name, channels_img)


  • 通道分离效果如下,从分离的单通道图片中,不难看出,HSV色彩空间下的V通道特征比较明显(BGR_G,LAB_L通道也比较明显,都可以采用此通道进行阈值分割,但是常用的还是HSV色彩空间),因此下文通过HSV色彩空间转换,对细胞进行分割识别。

【第三章:OpenCv阈值分割/二值化(单通道、多通道图片)总结】_第7张图片

图2.2 简单阈值分割与大津二值化分割分割效果

  • 代码
  • 效果

4. HSV分割

4.1 常见分割代码

pass

4.2 技巧性1,通过鼠标感应,获取某个像素的的HSV像素值

pass

4.2 最佳技巧性工具:借助滑动条,快速实现基于颜色的目标识别

pass

4.3. 扩展1:扩展滑动条数量,进行多颜色识别

pass

4.4 扩展2:BGR色彩空间下的颜色识别

pass

总结

你可能感兴趣的:(图像处理,opencv,opencv,计算机视觉,图像处理)