opencv python如何实现图像二值化


Posted in Python onFebruary 03, 2020

这篇文章主要介绍了opencv python如何实现图像二值化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

代码如下

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

# 二值图像就是将灰度图转化成黑白图,没有灰,在一个值之前为黑,之后为白
# 有全局和局部两种
# 在使用全局阈值时,我们就是随便给了一个数来做阈值,那我们怎么知道我们选取的这个数的好坏呢?答案就是不停的尝试。
# 如果是一副双峰图像(简 单来说双峰图像是指图像直方图中存在两个峰)呢?
# 我们岂不是应该在两个峰之间的峰谷选一个值作为阈值?这就是 Otsu 二值化要做的。
# 简单来说就是对 一副双峰图像自动根据其直方图计算出一个阈值。
# (对于非双峰图像,这种方法 得到的结果可能会不理想)。


def threshold_demo(image):
  gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

  # 这个函数的第一个参数就是原图像,原图像应该是灰度图。
  # 第二个参数就是用来对像素值进行分类的阈值。
  # 第三个参数就是当像素值高于(有时是小于)阈值时应该被赋予的新的像素值
  # 第四个参数来决定阈值方法,见threshold_simple()
  # ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY)
  ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
  print("threshold value: %s"%ret)
  cv.imshow("threshold_demo", binary)


def threshold_simple(image):
  img = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
  ret, thresh1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
  ret, thresh2 = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)
  ret, thresh3 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC)
  ret, thresh4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO)
  ret, thresh5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV)
  titles = ['Original Image', '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') # 将图像按2x3铺开
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])

  plt.show()


# 在前面的部分我们使用是全局阈值,整幅图像采用同一个数作为阈值。
# 当时这种方法并不适应与所有情况,尤其是当同一幅图像上的不同部分的具有不同亮度时。
# 这种情况下我们需要采用自适应阈值。此时的阈值是根据图像上的 每一个小区域计算与其对应的阈值。
# 因此在同一幅图像上的不同区域采用的是不同的阈值,从而使我们能在亮度不同的情况下得到更好的结果。
# 这种方法需要我们指定三个参数,返回值只有一个
# _MEAN_C:阈值取自相邻区域的平均值,_GAUSSIAN_C:阈值取值相邻区域 的加权和,权重为一个高斯窗口。
# Block Size - 邻域大小(用来计算阈值的区域大小)。
# C - 这就是是一个常数,阈值就等于的平均值或者加权平均值减去这个常数。

def threshold_adaptive(image):
  img = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
  # 中值滤波
  img = cv.medianBlur(img,5)

  ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
  # 11 为 Block size, 2 为 C 值
  th2 = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 11, 2)
  th3 = cv.adaptiveThreshold(img,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 11, 2)

  titles = ['Original Image', 'Global Threshold (v = 127)', 'Adaptive Mean Threshold', 'Adaptive Gaussian Threshold']
  images = [img, th1, th2, th3]

  for i in range(4):
    plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])

  plt.show()


def threshold_custom(image):
  gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
  h, w = gray.shape[:2]
  m = np.reshape(gray, [1, w*h])
  mean = m.sum() / (w*h) # 求出整个灰度图像的平均值
  print("mean:", mean)
  ret, binary = cv.threshold(gray, mean, 255, cv.THRESH_BINARY)
  cv.imshow("threshold_custom", binary)


# 将大图片拆分成小图片后再用自适应局部阈值比较好
def big_image_demo(image):
  print(image.shape)
  cw = 200
  ch = 200
  h, w = image.shape[:2]
  gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
  cv.imshow("big_image_demo_gray", gray)

  # 将一张图片每隔ch * cw分成一份
  for row in range(0, h, ch):
    for col in range(0, w, cw):
      roi = gray[row:row+ch, col:col+cw]
      dst = cv.adaptiveThreshold(roi, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 127, 2)
      gray[row:row + ch, col:col + cw] = dst
      print(np.std(dst), np.mean(dst))

  cv.imwrite("../images/result_big_image.png", gray)


def main():
  img = cv.imread("../images/02.jpg")
  # threshold_demo(img)
  # threshold_simple(img)
  # threshold_adaptive(img)
  # threshold_custom(img)
  src = cv.imread("../images/big_image.jpg")
  big_image_demo(src)
  cv.waitKey(0) # 等有键输入或者1000ms后自动将窗口消除,0表示只用键输入结束窗口
  cv.destroyAllWindows() # 关闭所有窗口


if __name__ == '__main__':
  main()

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

Python 相关文章推荐
python中实现字符串翻转的方法
Jul 11 Python
Python多进程原理与用法分析
Aug 21 Python
Python实现随机创建电话号码的方法示例
Dec 07 Python
使用Python实现企业微信的自动打卡功能
Apr 30 Python
pyqt5 lineEdit设置密码隐藏,删除lineEdit已输入的内容等属性方法
Jun 24 Python
python实现递归查找某个路径下所有文件中的中文字符
Aug 31 Python
详解如何用python实现一个简单下载器的服务端和客户端
Oct 28 Python
Python urllib2运行过程原理解析
Jun 04 Python
python mongo 向数据中的数组类型新增数据操作
Dec 05 Python
python基础学习之生成器与文件系统知识总结
May 25 Python
Python合并pdf文件的工具
Jul 01 Python
Python实现批量将文件复制到新的目录中再修改名称
Apr 12 Python
python实现人机猜拳小游戏
Feb 03 #Python
如何使用selenium和requests组合实现登录页面
Feb 03 #Python
检测tensorflow是否使用gpu进行计算的方式
Feb 03 #Python
Tensorflow 实现释放内存
Feb 03 #Python
手把手教你进行Python虚拟环境配置教程
Feb 03 #Python
解决TensorFlow GPU版出现OOM错误的问题
Feb 03 #Python
python global和nonlocal用法解析
Feb 03 #Python
You might like
PHP goto语句简介和使用实例
2014/03/11 PHP
PHP设计模式之观察者模式(Observer)详细介绍和代码实例
2014/04/08 PHP
php中strstr、strrchr、substr、stristr四个函数的区别总结
2014/09/22 PHP
php对数组内元素进行随机调换的方法
2015/05/12 PHP
举例详解PHP脚本的测试方法
2015/08/05 PHP
PHP获取指定时间段之间的 年,月,天,时,分,秒
2016/06/05 PHP
laravel 5.4中实现无限级分类的方法示例
2017/07/27 PHP
php实现的PDO异常处理操作分析
2018/12/27 PHP
Laravel 修改默认日志文件名称和位置的例子
2019/10/17 PHP
JavaScript DOM 学习第九章 选取范围的介绍
2010/02/19 Javascript
网页前台通过js非法字符过滤代码(骂人的话等等)
2010/05/26 Javascript
jquery中获取id值方法小结
2013/09/22 Javascript
省市区三级联动下拉框菜单javascript版
2015/08/11 Javascript
Node.js巧妙实现Web应用代码热更新
2015/10/22 Javascript
jQuery+canvas实现简单的球体斜抛及颜色动态变换效果
2016/01/28 Javascript
jquery mobile 实现自定义confirm确认框效果的简单实例
2016/06/17 Javascript
详解js正则表达式验证时间格式xxxx-xx-xx形式
2018/02/09 Javascript
基于Vue实现拖拽效果
2018/04/27 Javascript
vue.js实现回到顶部动画效果
2019/07/31 Javascript
详解vue+axios给开发环境和生产环境配置不同的接口地址
2019/08/16 Javascript
vuex中store存储store.commit和store.dispatch的用法
2020/07/24 Javascript
JavaScript 判断浏览器是否是IE
2021/02/19 Javascript
[05:17]DOTA2誓师:今天我们在这里 明天TI4等我!
2014/03/26 DOTA
[49:43]VG vs FNATIC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
Python交换变量
2008/09/06 Python
在MAC上搭建python数据分析开发环境
2016/01/26 Python
实例讲解Python爬取网页数据
2018/07/08 Python
Python函数式编程指南:对生成器全面讲解
2019/11/19 Python
Python pygame绘制文字制作滚动文字过程解析
2019/12/12 Python
如何唤起类中的一个方法
2013/11/29 面试题
奥巴马开学演讲观后感
2015/06/12 职场文书
幼儿园小班教学反思
2016/03/03 职场文书
2016年五一国际劳动节活动总结
2016/04/06 职场文书
SpringBoot集成Redis的思路详解
2021/10/16 Redis
windows11怎么查看wifi密码? win11查看wifi密码的技巧
2021/11/21 数码科技
python绘制云雨图raincloud plot
2022/08/05 Python