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中os和shutil模块实用方法集锦
May 13 Python
Python查看多台服务器进程的脚本分享
Jun 11 Python
Python中关于使用模块的基础知识
May 24 Python
Python开发中爬虫使用代理proxy抓取网页的方法示例
Sep 26 Python
在python3.5中使用OpenCV的实例讲解
Apr 02 Python
用Python写一段用户登录的程序代码
Apr 22 Python
flask中的wtforms使用方法
Jul 21 Python
实例讲解Python脚本成为Windows中运行的exe文件
Jan 24 Python
Python字符串的一些操作方法总结
Jun 10 Python
Mac安装python3的方法步骤
Aug 09 Python
Python使用itchat模块实现群聊转发,自动回复功能示例
Aug 26 Python
python 发送get请求接口详解
Nov 17 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
phpstorm编辑器乱码问题解决
2014/12/01 PHP
PHP中使用正则表达式提取中文实现笔记
2015/01/20 PHP
php实现有趣的人品测试程序实例
2015/06/08 PHP
PHP进程通信基础之信号
2017/02/19 PHP
workerman结合laravel开发在线聊天应用的示例代码
2018/10/30 PHP
动态加载图片路径 保持JavaScript控件的相对独立性
2010/09/03 Javascript
屏蔽网页右键复制和ctrl+c复制的js代码
2013/01/04 Javascript
JavaScript调用堆栈及setTimeout使用方法深入剖析
2013/02/16 Javascript
Extjs4.0设置Ext.data.Store传参的请求方式(默认为GET)
2013/04/02 Javascript
jquery得到font-size属性值实现代码
2013/09/30 Javascript
jQuery实现点击文本框弹出热门标签的提示效果
2013/11/17 Javascript
浅析JavaScript中两种类型的全局对象/函数
2013/12/05 Javascript
无闪烁更新网页内容JS实现
2013/12/19 Javascript
Flexigrid在IE下不显示数据的有效处理方法
2014/09/04 Javascript
使用console进行性能测试
2015/04/27 Javascript
Javascript Event(事件)的传播与冒泡
2017/01/23 Javascript
Vue.js展示AJAX数据简单示例讲解
2017/03/29 Javascript
深入浅析JSONAPI在PHP中的应用
2017/12/24 Javascript
vue-cli3脚手架的配置及使用教程
2018/08/28 Javascript
JavaScript实现学生在线做题计时器功能
2018/12/05 Javascript
jquery中为什么能用$操作
2019/06/18 jQuery
javascript将扁平的数据转为树形结构的高效率算法
2020/02/27 Javascript
Vue使用v-viewer实现图片预览
2020/10/21 Javascript
基于vue+echarts数据可视化大屏展示的实现
2020/12/25 Vue.js
[03:59]5分钟带你了解什么是DOTA2(第二期)
2017/02/07 DOTA
Python实现在线暴力破解邮箱账号密码功能示例【测试可用】
2017/09/06 Python
Python 中Django验证码功能的实现代码
2019/06/20 Python
python覆盖写入,追加写入的实例
2019/06/26 Python
Python如何对齐字符串
2020/07/30 Python
Java的类可以定义为Protected或者Private得吗
2015/09/25 面试题
往来会计岗位职责
2013/12/19 职场文书
办公室文员工作职责
2014/01/31 职场文书
2015年综治宣传月活动总结
2015/03/25 职场文书
安全第一课观后感
2015/06/18 职场文书
游戏开发中如何使用CocosCreator进行音效处理
2021/04/14 Javascript
使用@Value值注入及配置文件组件扫描
2021/07/09 Java/Android