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 正则表达式 概述及常用字符
May 04 Python
Python2.x中str与unicode相关问题的解决方法
Mar 30 Python
Python进程通信之匿名管道实例讲解
Apr 11 Python
Python中几种导入模块的方式总结
Apr 27 Python
python 日志增量抓取实现方法
Apr 28 Python
Django+uni-app实现数据通信中的请求跨域的示例代码
Oct 12 Python
爬虫代理池Python3WebSpider源代码测试过程解析
Dec 20 Python
Python表达式的优先级详解
Feb 18 Python
Python面向对象多态实现原理及代码实例
Sep 16 Python
一个非常简单好用的Python图形界面库(PysimpleGUI)
Dec 28 Python
Python中常见的导入方式总结
May 06 Python
Python游戏开发实例之graphics实现AI五子棋
Nov 01 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在线生成ico文件的代码
2007/10/09 PHP
php模板之Phpbean的目录结构
2008/01/10 PHP
PHP 页面跳转到另一个页面的多种方法方法总结
2009/07/07 PHP
Php 构造函数construct的前下划线是双的_
2009/12/08 PHP
php中的boolean(布尔)类型详解
2013/10/28 PHP
PHP中遇到的时区问题解决方法
2015/07/23 PHP
PHP实现二叉树的深度优先与广度优先遍历方法
2015/09/28 PHP
Yii框架操作cookie与session的方法实例详解
2019/09/04 PHP
Laravel的Auth验证Token验证使用自定义Redis的例子
2019/09/30 PHP
PHP pthreads v3使用中的一些坑和注意点分析
2020/02/21 PHP
js中几种去掉字串左右空格的方法
2006/12/25 Javascript
运用Windows XP附带的Msicuu.exe、Msizap.exe来彻底卸载顽固程序
2007/04/21 Javascript
Javascript打印网页部分内容的脚本
2008/11/17 Javascript
javascript中的关于类型转换的性能优化
2010/12/14 Javascript
Reactjs实现通用分页组件的实例代码
2017/01/19 Javascript
web前端vue filter 过滤器
2018/01/12 Javascript
微信小程序MUI导航栏透明渐变功能示例(通过改变opacity实现)
2019/01/24 Javascript
vue组件命名和props命名代码详解
2019/09/01 Javascript
JS基础之逻辑结构与循环操作示例
2020/01/19 Javascript
解决vue+router路由跳转不起作用的一项原因
2020/07/19 Javascript
CentOS 8.2服务器上安装最新版Node.js的方法
2020/12/16 Javascript
Python设计模式中单例模式的实现及在Tornado中的应用
2016/03/02 Python
Python的Flask框架应用调用Redis队列数据的方法
2016/06/06 Python
Django 自定义分页器的实现代码
2019/11/24 Python
pycharm导入源码的具体步骤
2020/08/04 Python
Tarte Cosmetics官网:美国最受欢迎的化妆品公司之一
2017/08/24 全球购物
iHerb台湾:维生素、保健品和健康产品
2018/01/31 全球购物
万宝龙英国官网:Montblanc手表、书写工具、皮革和珠宝
2018/10/16 全球购物
JD Sports澳洲官网:英国领先的运动鞋和运动时尚零售商
2020/02/15 全球购物
美国优质宠物用品购买网站:Muttropolis
2020/02/17 全球购物
天鹅的故事教学反思
2014/02/04 职场文书
学校食品安全责任书
2015/01/29 职场文书
大国崛起观后感
2015/06/02 职场文书
汉语拼音教学反思
2016/02/22 职场文书
教你快速构建一个基于nginx的web集群项目
2021/11/27 Servers
IIS服务器中设置HTTP重定向访问HTTPS
2022/04/29 Servers