OpenCv 中的【图像阈值化处理】

简介: 正常一个图像分为 R、G、B、三个通道,彩色照片中的每个像素值(生活中的某一中颜色)都是由不同R、G、B的值组合在一起的,比如下面这种

正常一个图像分为 R、G、B、三个通道,彩色照片中的每个像素值(生活中的某一中颜色)都是由不同R、G、B的值组合在一起的,比如下面这种:


网络异常,图片无法展示
|

而 图片去色之后变成灰度图,也就是我们所常见的黑白照片,其实生活中所谓的 "黑白照片"有一定的歧义,仔细观察会发现里面会参杂着不同程度的灰色:

网络异常,图片无法展示
|

真正意义上的 黑白照片 中只有黑色跟白色,要么是白色,要么是黑色;把一张灰度图变成这样的 黑白照片 也称之为 图像的 二值化


图像的二值化一般经过下面几个步骤:


图像灰度图转化,多通道变单通道;

设置阈值,在设置一个新值(介于黑—白之间的颜色),高于这个颜色设为新值,否则设为另外一个颜色;

选择调节方法阈值;

OpenCv 中有分为几类阈值:简单阈值、自适应阈值和 Otsu’s 二值化,其实这几种方法都是关于图像二值化处理:


简单阈值


简单阈值原理,设置一个阈值,高于这个阈值的图像赋予一个新值,低于这个阈值赋予另一种颜色,用到的函数主要是 cv2.threshhold();里面需要用到4个参数:第一个是需要处理的原图像;第二个是 设置的阈值,第三个是需要赋予的新的像素值;第四个参数是 不同的阈值方法:


cv2.THRESH_BINARY;

cv2.THRESH_BINARY_INV;

cv2.THRESH_TRUNC;

cv2.THRESH_TOZERO;

cv2.THRESH_TOZERO_INV;


五种阈值方法区别如下:

网络异常,图片无法展示
|
为了让大家更加理解,这里分别用每种阈值方法来处理原图像,代码如下:

import cv2
import numpy as np
from matplotlib import pyplot as plt
img_path = 'D:/ceshi.jpg'
img = cv2.imread(img_path)
#灰度图转化;;;
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,th1 = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY)
ret,th2 = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY_INV)
ret,th3 = cv2.threshold(img_gray,127,255,cv2.THRESH_TRUNC)
ret,th4 = cv2.threshold(img_gray,127,255,cv2.THRESH_TOZERO)
ret,th5 = cv2.threshold(img_gray,127,255,cv2.THRESH_TOZERO_INV)
titles = ['oringnal','gray_img','BINGARY','BINGARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img,img_gray,th1,th2,th3,th4,th5]
i = 0
for i in range(7):
    plt.subplot(3,3,i+1)
    plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])
plt.show()

阈值展示效果如下:

可以从图像中可以很清楚地看到 不同阈值之间的区别与联系;Threshold()函数返回的有两个值,第二个才是我们要的图像

自适应阈值


这一部分选取处理图像如下:

简单阈值又称之为全句阈值,就是整个图像发生改变,图像中的像素值分布只有两种,一种是大于初设的阈值区域,另外一种就是小于初设的阈值,对于图像阈值处理方面具有一定的局限性,OpenCv 中又引入了一种 自适应阈值 方法,使得图像中不同亮度部分最终显示不同效果,

**自适应阈值 ** 是根据图像上 每一小区域来进行计算 其对应阈值,也就是不同区域会设置不同的阈值效果,


OpenCv 中 自适应阈值函数用到的函数为: adaptiveThreshold(),里面包含有6个参数:


第一个跟简单阈值一样,是源图像 img;


第二个就是赋予的新像素值;


第三个为 Adaptive Method 指定计算阈值的方法,有两种:


cv2.ADPTIVE_THRESH_MENA_C:阈值取子相邻区域的平均值;

cv2.ADPTOVE_THRESH_GAUSSIAN_C:阈值取值相邻区域的加权和,权重为一个高斯窗口。

第四个就是需要选用的阈值方法,简单阈值中用到过的,例如:cv2.THRESH_BINARY;


第五个参数为 Block Size —邻域大小(用来计算阈值的区域大小)。


第六个参数 C 是一个常数,阈值就等于的平均值或者加权平均值减去这个常数值;


提醒一下,在做 自适应阈值 之前,需要对图片进行 一下 中值滤波处理 ;计算指定大小区域的平均像素值并把这一区域的像素值统一赋值;


下来可以看一下 自适应阈值 与 简单阈值 之间的区别,以及 自适应阈值 不同计算方法之间的差别:

import cv2
import numpy as np
from matplotlib import pyplot as plt
#图片读入灰度图
img1  =cv2.imread('E:/7.jpg',0)
#中值滤波
img = cv2.medianBlur(img1,5)
#简单阈值
ret, th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,
                            cv2.THRESH_BINARY,11,2)
th3 =cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,
                           cv2.THRESH_BINARY,11,5)
th4 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
th5 =cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,5)
titles = [
    'origianl_ images','means-image','gloabal(v = 127)','Mean(C =2)',
'Mean(C =5)','Gayssian(C = 2)',
'Gayssian(C = 5)'
]
images =[img1,img,th1,th2,th3,th4,th5]
num = 1
for i in range(2,6):
    plt.subplot(2,2,num),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])
    num += 1
plt.show()

展示效果:



这里我用到的图片比较模糊,所以展示的效果很差,下面我贴一下官网上的效果图:

网络异常,图片无法展示
|


Otsu’s 二值化


无论是 简单阈值 ,还是 自适应阈值 ,我们在处理之前都不可避免地需要考虑 阈值 设置问题,设置的好坏对于最后成像起到很大的影响,但是怎样设置一最适合的阈值呢?不断尝试?


而这个就是 Ostu 二值化要做的,通过根据图像的直方图分布计算出一个阈值 ,但是对于 非双峰图像来说,这种方法得到的结果可能不太理想,Ostu 二值化 用到的函数同样是 cv2.threshold(),


在之前的 简单阈值 部分中,cv2.threshold() 函数返回了两个值,第二个参数是我们最后要的图像,而第一个 rerval ,其实就是这里我们要计算的的最佳阈值,Ostu二值化 与 **简单阈值 **之间 一个重要的区别,就是需要多传入一个参数:cv2.THRESH_OSTU ,同时把 threshold() 函数中设定的阈值一定要设为 0;

import cv2
import numpy as np
from matplotlib import pyplot as plt
#图片读入灰度图
img1  =cv2.imread('E:/9.jpg',0)
#简单阈值处理
ret1,th1 = cv2.threshold(img1,127,255,cv2.THRESH_BINARY)
#Ostu thresholding
ret2,th2 = cv2.threshold(img1,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Ostu ‘ s thresholding after Gaussian FILTERING
#5,5为高斯核的大小,0为标准差;
blur =cv2.GaussianBlur(img1,(5,5),0)
ret3,th3 =cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
## plot all the images and their histogram
images =[img1,0,th1,
         img1,0,th2,
         blur,0,th3]
titles =[
    'Ori','Hist','Glo(v =127)',
    'Ori', 'Hist', 'Ostu',
    'Gass', 'Hist', 'Ostu',
]
#治理使用 pyplot绘制直方图,参数为一维数组,用到了numpy.ravel()函数;
for i in range(3):
    plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray')
    plt.title(titles[i*3]),plt.xticks([]),plt.yticks([])
    plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)
    plt.title(titles[i*3+1]),plt.xticks([]),plt.yticks([])
    plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')
    plt.title(titles[i*3+2]),plt.xticks([]),plt.yticks([])
plt.show()

这里选取一个带有噪点的图像,对于第一、二排是分别对图像做了 简单阈值Ostu二值化 ,而对于第三副图,先对带噪点的图像做了一个高斯核出去噪音,然后再进行 二值化

下面利用 pyplot 函数展示每一排分别代表为:处理之前的图像、未处理的直方图、处理之后的图像;

因为这里处理的元图像很模糊,所以处理之后的效果并不明显,这里贴一张官方的图片:

怎么样是不是很赞,而我处理的原图像就下面这样子。。。。。

网络异常,图片无法展示
|

相关文章
|
2月前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
545 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
|
3月前
|
算法 计算机视觉
opencv图像形态学
图像形态学是一种基于数学形态学的图像处理技术,它主要用于分析和修改图像的形状和结构。
56 4
|
3月前
|
存储 计算机视觉
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
本文介绍了使用OpenCV进行图像读取、显示和存储的基本操作,以及如何绘制直线、圆形、矩形和文本等几何图形的方法。
Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制
|
4月前
|
算法 计算机视觉 Python
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
该文章详细介绍了使用Python和OpenCV进行相机标定以获取畸变参数,并提供了修正图像畸变的全部代码,包括生成棋盘图、拍摄标定图像、标定过程和畸变矫正等步骤。
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
WK
|
4月前
|
编解码 计算机视觉 Python
如何在OpenCV中进行图像转换
在OpenCV中,图像转换涉及颜色空间变换、大小调整及类型转换等操作。常用函数如`cvtColor`可实现BGR到RGB、灰度图或HSV的转换;`resize`则用于调整图像分辨率。此外,通过`astype`或`convertScaleAbs`可改变图像数据类型。对于复杂的几何变换,如仿射或透视变换,则可利用`warpAffine`和`warpPerspective`函数实现。这些技术为图像处理提供了强大的工具。
WK
131 1
|
6月前
|
算法 计算机视觉
【Qt&OpenCV 图像的感兴趣区域ROI】
【Qt&OpenCV 图像的感兴趣区域ROI】
211 1
|
6月前
|
运维 算法 计算机视觉
【Qt&OpenCV 图像的模板匹配 matchTemplate/minMaxLoc】
【Qt&OpenCV 图像的模板匹配 matchTemplate/minMaxLoc】
88 1
|
6月前
|
存储 编解码 算法
【Qt&OpenCV 检测图像中的线/圆/轮廓 HoughLinesP/HoughCircles/findContours&drawContours】
【Qt&OpenCV 检测图像中的线/圆/轮廓 HoughLinesP/HoughCircles/findContours&drawContours】
111 0
|
5月前
|
机器学习/深度学习 XML 计算机视觉
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,它提供了大量的函数和工具,用于处理图像和视频数据。
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习库,它提供了大量的函数和工具,用于处理图像和视频数据。
|
6月前
|
算法 计算机视觉
【Qt&OpenCV 图像边缘检测 Sobel/Laplace/Canny】
【Qt&OpenCV 图像边缘检测 Sobel/Laplace/Canny】
79 0