Python下opencv图像阈值处理的使用笔记

图像的阈值处理一般使得图像的像素值更单一、图像更简单。阈值可以分为全局性质的阈值,也可以分为局部性质的阈值,可以是单阈值的也可以是多阈值的。当然阈值越多是越复杂的。下面将介绍opencv下的三种阈值方法。

(一)简单阈值

简单阈值当然是最简单,选取一个全局阈值,然后就把整幅图像分成了非黑即白的二值图像了。函数为cv2.threshold()
这个函数有四个参数,第一个原图像,第二个进行分类的阈值,第三个是高于(低于)阈值时赋予的新值,第四个是一个方法选择参数,常用的有:

  • cv2.THRESH_BINARY(黑白二值)
  • cv2.THRESH_BINARY_INV(黑白二值反转)
  • cv2.THRESH_TRUNC (得到的图像为多像素值)
  • cv2.THRESH_TOZERO
  • cv2.THRESH_TOZERO_INV

该函数有两个返回值,第一个retVal(得到的阈值值(在后面一个方法中会用到)),第二个就是阈值化后的图像。
一个实例如下:

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('flower.jpg',0) #直接读为灰度图像
ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
titles = ['img','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img,thresh1,thresh2,thresh3,thresh4,thresh5]
for i in range(6):
 plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
 plt.title(titles[i])
 plt.xticks([]),plt.yticks([])
plt.show()

可以看到这里把阈值设置成了127,对于BINARY方法,当图像中的灰度值大于127的重置像素值为255.

(二)自适应阈值:

前面看到简单阈值是一种全局性的阈值,只需要规定一个阈值值,整个图像都和这个阈值比较。而自适应阈值可以看成一种局部性的阈值,通过规定一个区域大小,比较这个点与区域大小里面像素点的平均值(或者其他特征)的大小关系确定这个像素点是属于黑或者白(如果是二值情况)。使用的函数为:cv2.adaptiveThreshold()
该函数需要填6个参数:

  1. 第一个原始图像
  2. 第二个像素值上限
  3. 第三个自适应方法Adaptive Method:
    1. — cv2.ADAPTIVE_THRESH_MEAN_C :领域内均值
    2. —cv2.ADAPTIVE_THRESH_GAUSSIAN_C :领域内像素点加权和,权 重为一个高斯窗口
  4. 第四个值的赋值方法:只有cv2.THRESH_BINARY 和cv2.THRESH_BINARY_INV
  5. 第五个Block size:规定领域大小(一个正方形的领域)
  6. 第六个常数C,阈值等于均值或者加权值减去这个常数(为0相当于阈值 就是求得领域内均值或者加权值)

这种方法理论上得到的效果更好,相当于在动态自适应的调整属于自己像素点的阈值,而不是整幅图像都用一个阈值。

一个实例如下:

mport cv2
import matplotlib.pyplot as plt

img = cv2.imread('flower.jpg',0) #直接读为灰度图像
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_GAUSSIAN_C,\
cv2.THRESH_BINARY,11,2) #换行符号 \
images = [img,th1,th2,th3]
plt.figure()
for i in xrange(4):
 plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
plt.show()

可以看到上述窗口大小使用的为11,当窗口越小的时候,得到的图像越细。想想一下,如果把窗口设置足够大以后(不能超过图像大小),那么得到的结果可能就和第二幅图像的相同了。

(三)Otsu's二值化

我们前面说到,cv2.threshold函数是有两个返回值的,前面一直用的第二个返回值,也就是阈值处理后的图像,那么第一个返回值(得到图像的阈值)将会在这里用到。

前面对于阈值的处理上,我们选择的阈值都是127,那么实际情况下,怎么去选择这个127呢?有的图像可能阈值不是127得到的效果更好。那么这里我们需要算法自己去寻找到一个阈值,而Otsu's就可以自己找到一个认为最好的阈值。并且Otsu's非常适合于图像灰度直方图具有双峰的情况,他会在双峰之间找到一个值作为阈值,对于非双峰图像,可能并不是很好用。那么经过Otsu's得到的那个阈值就是函数cv2.threshold的第一个参数了。因为Otsu's方法会产生一个阈值,那么函数cv2.threshold的的第二个参数(设置阈值)就是0了,并且在cv2.threshold的方法参数中还得加上语句cv2.THRESH_OTSU。那么什么是双峰图像(只能是灰度图像才有),就是图像的灰度统计图中可以明显看出只有两个波峰,比如下面一个图的灰度直方图就可以是双峰图:

好了现在对这个图进行Otsu's阈值处理就非常的好,通过函数cv2.threshold会自动找到一个介于两波峰之间的阈值。一个实例如下:

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('finger.jpg',0) #直接读为灰度图像
#简单滤波
ret1,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
#Otsu 滤波
ret2,th2 = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
print ret2
plt.figure()
plt.subplot(221),plt.imshow(img,'gray')
plt.subplot(222),plt.hist(img.ravel(),256)#.ravel方法将矩阵转化为一维
plt.subplot(223),plt.imshow(th1,'gray')
plt.subplot(224),plt.imshow(th2,'gray')

print ret2 得到的结果为122。可以看出似乎两个结果并没有很明显差别(素材也不太好弄~_~!),主要是两个阈值(127与122)太相近了,如果这两个隔得很远那么会很明显的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 利用OpenCV实现局部动态阈值分割

    利用OpenCV实现局部动态阈值分割,参考Halcon dyn_threshold算子的思路实现. #include "dialog.h" #include <QApplication> #include "cv.h" #include "highgui.h" #include <QDebug> int main(int argc, char *argv[]) { IplImage *img = cvLoadImage(&

  • python opencv 简单阈值算法的实现

    本文先了解一个简单阈值函数,以了解一个阈值算法的具体参数. 然后比较不同阈值函数的区别. 同样的,先用一副图说明本文重要大纲: #! usr/bin/env python # coding: utf-8 import cv2 img = cv2.imread('cat.jpg') img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 先将图像矩阵进行二值化 # img = cv2.imread('cat.jpg',0) # 也可以直接将图像用灰度值读入,其中0

  • python+opencv实现阈值分割

    最近老师留了几个作业,虽然用opencv很简单一句话就出来了,但是还没用python写过.在官方文档中的tutorial中的threshold里,看到可以创建两个滑动条来选择type和value,决定用python实现一下 注意python中的全局变量,用global声明 开始出现了一些问题,因为毁掉函数每次只能传回一个值,所以每次只能更新value,后来就弄了两个毁掉函数,这个时候,又出现了滑动其中一个,另一个的值就会变为默认值的情况,这个时候猜想是全局变量的问题,根据猜想改动之后果然是. 感

  • Python下opencv图像阈值处理的使用笔记

    图像的阈值处理一般使得图像的像素值更单一.图像更简单.阈值可以分为全局性质的阈值,也可以分为局部性质的阈值,可以是单阈值的也可以是多阈值的.当然阈值越多是越复杂的.下面将介绍opencv下的三种阈值方法. (一)简单阈值 简单阈值当然是最简单,选取一个全局阈值,然后就把整幅图像分成了非黑即白的二值图像了.函数为cv2.threshold() 这个函数有四个参数,第一个原图像,第二个进行分类的阈值,第三个是高于(低于)阈值时赋予的新值,第四个是一个方法选择参数,常用的有: cv2.THRESH_B

  • Python下opencv使用hough变换检测直线与圆

    在数字图像中,往往存在着一些特殊形状的几何图形,像检测马路边一条直线,检测人眼的圆形等等,有时我们需要把这些特定图形检测出来,hough变换就是这样一种检测的工具. Hough变换的原理是将特定图形上的点变换到一组参数空间上,根据参数空间点的累计结果找到一个极大值对应的解,那么这个解就对应着要寻找的几何形状的参数(比如说直线,那么就会得到直线的斜率k与常熟b,圆就会得到圆心与半径等等). 关于hough变换,核心以及难点就是关于就是有原始空间到参数空间的变换上.以直线检测为例,假设有一条直线L,

  • python计算机视觉opencv图像金字塔轮廓及模板匹配

    目录 1.图像金字塔 ①高斯金字塔 ②拉普拉斯金字塔 2.图像轮廓 ①寻找轮廓 ②轮廓特征 ③轮廓绘制 3.模板匹配 ①模板匹配 ②匹配框线绘制 ③多对象匹配 4.直方图统计 ①直方图绘制 ②直方图统计 ③直方图的mask操作 ④直方图均衡化 5.傅里叶变换 1.图像金字塔 ①高斯金字塔 向下采样,数据会越来越少,减少的方式是:将偶数行和列删除 向上采样,数据会越来越多,将图像在每个方向上扩大为原来的两倍,新增的行和列用0来填充.使用先前同样的内核与放大后的图像卷积,获得近似值. 上采样之后,图

  • 浅谈python下tiff图像的读取和保存方法

    对比测试 scipy.misc 和 PIL.Image 和 libtiff.TIFF 三个库 输入: 1. (读取矩阵) 读入uint8.uint16.float32的lena.tif 2. (生成矩阵) 使用numpy产生随机矩阵,float64的mat import numpy as np from scipy import misc from PIL import Image from libtiff import TIFF # # 读入已有图像,数据类型和原图像一致 tif32 = mi

  • 查看python下OpenCV版本的方法

    在命令行输入以下代码: python import cv2 cv2.__version__ 以上这篇查看python下OpenCV版本的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • Python下opencv库的安装过程及问题汇总

    本文主要内容是python下opencv库的安装过程,涉及我在安装时遇到的问题,并且,将从网上搜集并试用的一些解决方案进行了简单的汇总,记录下来. 由于记录的是我第一次安装opencv库的过程,所以内容涵盖可能不全面,如果有出错的地方请务必指正.下面进入主题. 关于python的下载安装不再赘述,python的版本号是我们在opencv库的安装过程中需要用到的,cmd运行python可以进行查看. 通常,我们使用pip命令来安装扩展库. 打开cmd运行 pip install opencv-py

  • python中opencv图像叠加、图像融合、按位操作的具体实现

    目录 1图像叠加 2图像融合 3按位操作 1图像叠加 可以通过OpenCV函数cv.add()或简单地通过numpy操作添加两个图像,res = img1 + img2.两个图像应该具有相同的深度和类型,或者第二个图像可以是标量值. NOTE: OpenCV添加是饱和操作,也就是有上限值,而Numpy添加是模运算. 添加两个图像时, OpenCV功能将提供更好的结果.所以总是更好地坚持OpenCV功能. 代码: import cv2 import numpy as np x = np.uint8

  • Python中OpenCV图像特征和harris角点检测

    目录 概念 第一步:计算一个梯度 Ix,Iy 第二步:整合矩阵,计算特征值 第三步:比较特征值的大小 第四步: 非极大值抑制,把真正的角点留下来,角点周围的过滤掉 代码实现 概念 第一步:计算一个梯度 Ix,Iy 第二步:整合矩阵,计算特征值 第三步:比较特征值的大小 第四步: 非极大值抑制,把真正的角点留下来,角点周围的过滤掉 代码实现 import cv2 import numpy as np img =cv2.imread('pie.png') print('img.shape',img.

  • python用opencv 图像傅里叶变换

    傅里叶变换 dft = cv.dft(np.float32(img),flags = cv.DFT_COMPLEX_OUTPUT) 傅里叶逆变换 img_back = cv.idft(f_ishift) 实验:将图像转换到频率域,低通滤波,将频率域转回到时域,显示图像 import numpy as np import cv2 as cv from matplotlib import pyplot as plt img = cv.imread('d:/paojie_g.jpg',0) rows,

  • python OpenCV 图像通道数判断

    目录 前言 教程 1.读取/保存图片 1)imread和imwrite方法 2)imdecode和imencode方法 2.编码转换 1)BGR转RGB 2)BGR转GRAY 3.快速判断图像是否单通道灰度图 4.获取图像通道数 前言 OpenCV是图像处理常用的库,作为初学者,往往从图片的读取.保存.查询图片的信息开始,下面将分享Python下OpenCV的一些基本使用方法,掌握这些基本方法后,能够更好地与matplotlib.numpy等结合使用,完成相应的图像操作. 教程 1.读取/保存图

随机推荐