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 相关文章推荐
rhythmbox中文名乱码问题解决方法
Sep 06 Python
忘记ftp密码使用python ftplib库暴力破解密码的方法示例
Jan 22 Python
Python的函数嵌套的使用方法
Jan 24 Python
Python对象的深拷贝和浅拷贝详解
Aug 25 Python
Python双精度浮点数运算并分行显示操作示例
Jul 21 Python
浅析使用Python操作文件
Jul 31 Python
Sanic框架请求与响应实例分析
Jul 16 Python
使用python爬取微博数据打造一颗“心”
Jun 28 Python
Django之提交表单与前后端交互的方法
Jul 19 Python
Python笔记之代理模式
Nov 20 Python
关于Numpy中的行向量和列向量详解
Nov 30 Python
Python面向对象之多态原理与用法案例分析
Dec 30 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中使用sleep造成mysql读取失败的案例和解决方法
2014/08/21 PHP
thinkPHP实现瀑布流的方法
2014/11/29 PHP
Thinkphp模板标签if和eq的区别和比较实例分析
2015/07/01 PHP
php函数mkdir实现递归创建层级目录
2016/10/27 PHP
PHP设计模式之模板方法模式实例浅析
2018/12/20 PHP
Thinkphp5.0框架的Db操作实例分析【连接、增删改查、链式操作等】
2019/10/11 PHP
PHP高并发和大流量解决方案整理
2019/12/24 PHP
获取DOM对象的几种扩展及简写
2006/10/09 Javascript
网上应用的一个不错common.js脚本
2007/08/08 Javascript
Javascript模拟加速运动与减速运动代码分享
2014/12/11 Javascript
jQuery实现瀑布流布局
2014/12/12 Javascript
nodejs中操作mysql数据库示例
2014/12/20 NodeJs
JavaScript将字符串转换成字符编码列表的方法
2015/03/19 Javascript
jQuery调用WebMethod(PageMethod) NET2.0的方法
2016/04/15 Javascript
基于JS代码实现实时显示系统时间
2016/06/16 Javascript
DOM中事件处理概览与原理的全面解析
2016/08/16 Javascript
百度地图JavascriptApi Marker平滑移动及车头指向行径方向
2017/03/13 Javascript
underscore之Chaining_动力节点Java学院整理
2017/07/10 Javascript
详解基于vue-cli3.0如何构建功能完善的前端架子
2018/10/09 Javascript
vue.js中使用echarts实现数据动态刷新功能
2019/04/16 Javascript
微信小程序按顺序同步执行的两种方式
2019/12/20 Javascript
python实现简单的TCP代理服务器
2014/10/08 Python
Python中执行存储过程及获取存储过程返回值的方法
2017/10/07 Python
浅谈Python中带_的变量或函数命名
2017/12/04 Python
Python JSON格式数据的提取和保存的实现
2019/03/22 Python
Python Flask框架模板操作实例分析
2019/05/03 Python
用Python从0开始实现一个中文拼音输入法的思路详解
2019/07/20 Python
德国街头和运动文化高品质商店:BSTN Store
2017/08/26 全球购物
香港最新科技与优质家居产品购物网站:J SELECT
2018/08/21 全球购物
python re模块和正则表达式
2021/03/24 Python
工地安全标语
2014/06/07 职场文书
2014年学生会主席工作总结
2014/11/07 职场文书
公司捐书倡议书
2015/04/27 职场文书
2015迎新晚会开场白
2015/07/17 职场文书
留学文书中的个人陈述,应该注意哪些问题?
2019/08/23 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书