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的装饰器用法学习笔记
Jun 24 Python
python爬虫入门教程--优雅的HTTP库requests(二)
May 25 Python
基于ID3决策树算法的实现(Python版)
May 31 Python
python模拟表单提交登录图书馆
Apr 27 Python
django+echart数据动态显示的例子
Aug 12 Python
对python中UDP,socket的使用详解
Aug 22 Python
详解从Django Allauth中进行登录改造小结
Dec 18 Python
Python实现ElGamal加密算法的示例代码
Jun 19 Python
Pandas的数据过滤实现
Jan 15 Python
基于Pytorch版yolov5的滑块验证码破解思路详解
Feb 25 Python
Python打包exe时各种异常处理方案总结
May 18 Python
golang特有程序结构入门教程
Jun 02 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 上传文件大小限制
2009/07/05 PHP
PHP的array_diff()函数在处理大数组时的效率问题
2011/11/27 PHP
php 替换文章中的图片路径,下载图片到本地服务器的方法
2018/02/06 PHP
php和C#的yield迭代器实现方法对比分析
2019/07/17 PHP
laravel 创建命令行命令的图文教程
2019/10/23 PHP
Thinkphp5框架中引入Markdown编辑器操作示例
2020/06/03 PHP
javascript 短路法代码精简
2009/08/20 Javascript
基于NodeJS的前后端分离的思考与实践(一)全栈式开发
2014/09/26 NodeJs
jQuery匹配文档链接并添加class的方法
2015/06/26 Javascript
基于Node.js的JavaScript项目构建工具gulp的使用教程
2016/05/20 Javascript
详解Nodejs的timers模块
2016/12/22 NodeJs
jQuery实现Select下拉列表进行状态选择功能
2017/03/30 jQuery
利用prop-types第三方库对组件的props中的变量进行类型检测
2017/05/02 Javascript
vue2利用Bus.js如何实现非父子组件通信详解
2017/08/25 Javascript
vue展示dicom文件医疗系统的实现代码
2018/08/27 Javascript
Nuxt升级2.0.0时出现的问题(小结)
2018/10/08 Javascript
解决vue props传Array/Object类型值,子组件报错的情况
2020/11/07 Javascript
粗略分析Python中的内存泄漏
2015/04/23 Python
python实现画五角星和螺旋线的示例
2019/01/20 Python
python 实现selenium断言和验证的方法
2019/02/13 Python
使用selenium和pyquery爬取京东商品列表过程解析
2019/08/15 Python
Tensorflow读取并输出已保存模型的权重数值方式
2020/01/04 Python
python3检查字典传入函数键是否齐全的实例
2020/06/05 Python
Python爬虫实例——scrapy框架爬取拉勾网招聘信息
2020/07/14 Python
python抢购软件/插件/脚本附完整源码
2021/03/04 Python
HTML5基于flash实现播放RTMP协议视频的示例代码
2020/12/04 HTML / CSS
英国皇家造币厂:The Royal Mint
2018/10/05 全球购物
德国高端单身人士交友网站:ElitePartner
2018/12/02 全球购物
TCP协议通讯的过程和步骤是什么
2015/10/18 面试题
大学生四个方面的自我评价
2013/09/19 职场文书
英语专业毕业生自荐信
2013/10/28 职场文书
计算机求职自荐信范文
2014/04/19 职场文书
导师鉴定意见
2015/06/05 职场文书
2015年秋季学校开学标语
2015/07/16 职场文书
小学数学教师研修感悟
2015/11/18 职场文书
DE1107机评
2022/04/05 无线电