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中的Django框架中prefetch_related()函数对数据库查询的优化
Apr 01 Python
Django 生成登陆验证码代码分享
Dec 12 Python
python调用API实现智能回复机器人
Apr 10 Python
对pandas中iloc,loc取数据差别及按条件取值的方法详解
Nov 06 Python
详解用Python练习画个美队盾牌
Mar 23 Python
Python实现的爬取百度贴吧图片功能完整示例
May 10 Python
Django如何开发简单的查询接口详解
May 17 Python
ZABBIX3.2使用python脚本实现监控报表的方法
Jul 02 Python
django之静态文件 django 2.0 在网页中显示图片的例子
Jul 28 Python
通过实例解析python描述符原理作用
Jan 22 Python
python 爬虫 实现增量去重和定时爬取实例
Feb 28 Python
Python中全局变量和局部变量的理解与区别
Feb 07 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
redis 队列操作的例子(php)
2012/04/12 PHP
PHP实现UTF8二进制及明文字符串的转化功能示例
2017/11/20 PHP
IE与firefox之jquery用法区别
2008/10/03 Javascript
extjs fckeditor集成代码
2009/05/10 Javascript
jquery datepicker参数介绍和示例
2014/04/15 Javascript
深入理解JavaScript系列(31):设计模式之代理模式详解
2015/03/03 Javascript
JS for循环中i++ 和 ++i的区别介绍
2016/07/20 Javascript
video.js使用改变ui过程
2017/03/05 Javascript
jQuery滚动监听实现商城楼梯式导航效果
2017/03/06 Javascript
Angularjs渲染的 using 指令的星级评分系统示例
2017/11/09 Javascript
vue 添加vux的代码讲解
2017/11/30 Javascript
解析Angular 2+ 样式绑定方式
2018/01/15 Javascript
vue项目如何刷新当前页面的方法
2018/05/18 Javascript
微信小程序实现的点击按钮 弹出底部上拉菜单功能示例
2018/12/20 Javascript
一个手写的vue放大镜效果
2019/08/09 Javascript
three.js利用射线Raycaster进行碰撞检测
2020/03/12 Javascript
Python爬虫DNS解析缓存方法实例分析
2017/06/02 Python
Python实现霍夫圆和椭圆变换代码详解
2018/01/12 Python
Python爬虫实战:分析《战狼2》豆瓣影评
2018/03/26 Python
python实现读Excel写入.txt的方法
2018/04/29 Python
CSS3实例分享--超炫checkbox复选框和radio单选框
2014/09/01 HTML / CSS
HTML5+lufylegend实现游戏中的卷轴
2016/02/29 HTML / CSS
北京泡泡网网络有限公司.net面试题
2012/07/17 面试题
飞利信loadrunner和软件测试笔试题
2012/09/22 面试题
计算机专业毕业生推荐信
2013/11/25 职场文书
读书心得体会
2013/12/28 职场文书
餐厅执行经理岗位职责范本
2014/02/26 职场文书
商业计算机应用专业自荐书
2014/06/09 职场文书
处级干部反四风个人对照检查材料思想汇报
2014/09/27 职场文书
爱晚亭导游词
2015/02/09 职场文书
推荐信范文大全
2015/03/27 职场文书
2015年学生会部门工作总结
2015/04/21 职场文书
清明扫墓感想
2015/08/11 职场文书
如何将JavaScript将数组转为树形结构
2021/06/02 Javascript
从np.random.normal()到正态分布的拟合操作
2021/06/02 Python
css弧边选项卡的项目实践
2023/05/07 HTML / CSS