草庐IT

基于梵·高《向日葵》的 图像阈值处理专题(二值处理、反二值处理、截断处理、自适应处理及Otsu方法)【Python-Open_CV系列(六)】

侯小啾 2023-04-11 原文

基于梵·高《向日葵》的图像阈值处理专题(二值处理、反二值处理、截断处理、自适应处理及Otsu方法)【Python-Open_CV系列(六)】

文章目录


ʚʕ̯•͡˔•̯᷅ʔɞ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ

🍹欢迎各路大佬来到小啾主页指点
☀️本期文章将学习基于梵·高《向日葵》的图像阈值处理专题(二值处理、反二值处理、截断处理、自适应处理及Otsu方法) - Open_CV系列博文第六篇,我是博主侯小啾。✨
我的博客主页:云雀编程小窝 🌹꧔ꦿ
🌹꧔ꦿ博文内容如对您有所帮助,还请给个点赞 + 关注 + 收藏

            


如有疑问欢迎随时在评论区交流。🍹


🍹1. 什么是阈值处理?

在图像处理中,阈值处理是一种很重要的处理方式。阈值处理即给像素值设定一个阈值,然后所有的像素值都与目标阈值进行比较,根据像素值与阈值的关系,对像素值做出相应的调整,以达到影响图片的效果的预期。在计算机视觉技术中心,阈值处理十分重要,像素在经过阈值处理后,对肉眼观感可能不会太好,但是对程序而言图片上的人或物则通常更容易被搜寻到特征,以被识别出。从而实现识别的目的。

阈值处理常用的方法:threshold()方法。
✨其语法如下:

threshold(src, thresh, maxval, type, dst=None)

  • src: 原图
  • thresh: 阈值
  • maxval: 阈值处理采用的最大值,通常选择255作为最大值,即白色。
  • type: 阈值处理类型。

                       常用的阈值处理类型

类型含义
cv2.THRESH_BINARY 二值化阈值处理
cv2.THRESH_BINARY_INY反二值化阈值处理
cv2.THRESH_TOZERO低于阈值零处理
cv2.THRESH_TOZERO_INV超出阈值零处理
cv2.THRESH_TRUNC截断阈值处理

🍹2.二值化处理 与 反二值化处理

二值化处理,也称二值化阈值处理,该处理使每个像素值与指定的阈值相比较,大于阈值的像素变为最大值,小于阈值的像素值变为零。最终可以使像素只保留两种像素值,得到“非黑即白”的图像(不同与灰度处理)。


反二值化处理的处理结果与二值化处理相反,得到的也是只有黑白两种颜色的图像,不同之处在于大于阈值的像素值变为0,小于阈值的变为阈值处理采用的最大值。

下面,对二值化处理的方式进行示例,

选择图片素材:
                 梵高 《向日葵》

           

以127作为阈值,255为阈值处理最大值为例,读取图像时,需要先将图像转化为灰度图像。

import cv2
# 将图像读成灰度图像
img = cv2.imread("sunflowers.jpg", 0)  
# 做二值化处理
t, dst = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# 其中返回的t即我们选择的阈值127。
cv2.imshow('dst', dst) 
cv2.waitKey() 
cv2.destroyAllWindows() 

处理效果:

           

👇同理,再对《向日葵》做反二值化处理

import cv2
img = cv2.imread("sunflowers.jpg", 0)
# 反二值化阈值处理
t, dst = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()

           


🍹3. 零处理

零处理包括 低于阈值零处理 超出阈值零处理(也称低阈值零处理和高阈值零处理)。低于阈值零处理将低于阈值的像素值变为0,超出阈值零处理则将高于阈值的像素值变为0。

import cv2
img = cv2.imread("sunflowers.jpg", 0)
# 低于阈值零处理
t, dst = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()

           

import cv2
img = cv2.imread("sunflowers.jpg", 0)
# 超出阈值零处理
t, dst = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()

👇超阈值零处理效果呈现:
           


🍹4. 截断处理

截断处理也称截断阈值处理,将大于阈值的像素值变成跟阈值一样,小于阈值的像素值则保持不变。

截断处理后图像的整体颜色会变暗,亮度降低,原本浅色区域的颜色会变更浅。

代码示例如下:

import cv2
# 将图像读成灰度图像
img = cv2.imread("sunflowers.jpg", 0)
# 截断处理
t, dst = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()

           


🍹5.五种处理方式汇总

👇将以上五种阈值处理方式汇总对比其效果:

import cv2

image = cv2.imread(""sunflowers.jpg".jpg")
# 因为原图尺寸过大,不方便展示,所以先缩放一倍。
image = cv2.resize(image, None, fx=0.5, fy=0.5)
# 转化为灰度图像
image_Gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print(image_Gray.shape)
# 二值化阈值处理
t1, dst1 = cv2.threshold(image_Gray, 127, 255, cv2.THRESH_BINARY)
# 反二值化阈值处理
t2, dst2 = cv2.threshold(image_Gray, 127, 255, cv2.THRESH_BINARY_INV)
# 低于阈值零处理
t3, dst3 = cv2.threshold(image_Gray, 127, 255, cv2.THRESH_TOZERO)
# 超出阈值零处理
t4, dst4 = cv2.threshold(image_Gray, 127, 255, cv2.THRESH_TOZERO_INV)
# 截断处理
t5, dst5 = cv2.threshold(image_Gray, 127, 255, cv2.THRESH_TRUNC)
# 分别显示经过5种阈值类型处理后的图像
cv2.imshow("BINARY", dst1)
cv2.imshow("BINARY_INV", dst2)
cv2.imshow("TOZERO", dst3)
cv2.imshow("TOZERO_INV", dst4)
cv2.imshow("TRUNC", dst5)
cv2.waitKey()
cv2.destroyAllWindows()

这五种阈值处理的方法,的处理出的图像轮廓多少还是会有些模糊不清,不利于程序做进一步的处理。使用自适应处理可以有效改善该问题。


🍹6. 自适应处理

  自适应处理是一种改进过的阈值处理技术,其阈值是对图像区域中的某一正方形区域内的所有色素值使用指定的算法而得到的,从而而对像素进行相应的处理。自适应处理本身不属于阈值处理方法,算是对阈值处理的改进,其使用过程中可以选择使用二值化处理或反二值化处理的处理方式。

OpenCV中,做自适应处理使用的是cv2.adaptiveThreshold方法,
该方法语法如下

adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)

其中,
adaptiveMethod 是自适应阈值的计算方法,该方法有两种,

  • cv2.ADAPTIVE_THRESH_MEAN_C : 对一个正方形区域内的所有像素进行平均加权。
  • cv2.ADAPTIVE_THRESH_GAUSSIAN_C : 根据高斯函数按照像素与中心店的距离对一个正方形区域内的所有像素进行加权计算。

thresholdType 即阈值处理类型。可以是二值化处理(cv2.THRESH_BINARY)或反二值化处理(cv2.THRESH_BINARY_INY)。

blockSize 计算阈值算法中的正方形区域的边长大小。

C 常量 最终的阈值等于均值减去这个常量 或 加权值减去这个常量

dst 经过阈值处理后的图像。

下边分别使用两种阈值计算方法对图片进行自适应处理,两种方法得到的结果有一定的细微差异。


平均法 cv2.ADAPTIVE_THRESH_MEAN_C

import cv2
image = cv2.imread("sunflowers.jpg")
image_Gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
athdMEAM = cv2.adaptiveThreshold(image_Gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 3)
cv2.imshow("MEAN_C", athdMEAM)
cv2.waitKey()
cv2.destroyAllWindows()

              

高斯法 cv2.ADAPTIVE_THRESH_GAUSSIAN_C

import cv2
image = cv2.imread("sunflowers.jpg")
image_Gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
athdGAUS = cv2.adaptiveThreshold(image_Gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 5, 3)
cv2.imshow("GAUSSIAN_C", athdGAUS)
cv2.waitKey()
cv2.destroyAllWindows()

            


🍹7. Otsu方法

除了自适应处理外,Opencv还提供了Otsu方法来遍历所有可能的阈值,从而得出最合适的阈值。

Ostu方法不是独立的函数方法,其实现基于上边实现五种阈值处理的threshold() 方法,只是需要在其阈值处理类型参数type后方 续写上 + cv2.THRESH_OTSU 字样(非字符串)。

👇示例如下,依然操作向日葵:

import cv2
image = cv2.imread("sunflowers.jpg")
# 灰度处理
image_Gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# t=127的二值化处理
t1, dst1 = cv2.threshold(image_Gray, 127, 255, cv2.THRESH_BINARY)
# OTSU的二值化处理
t2, dst2 = cv2.threshold(image_Gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 打印最佳阈值
print(t2)
cv2.imshow("BINARY", dst1)
cv2.imshow("OTSU", dst2)  
cv2.waitKey() 
cv2.destroyAllWindows()  

程序执行结果如下:
         

👇程序执行效果如下,左图为阈值为127时的二值化处理结果,右图为阈值最佳时的二值化处理结果,此时阈值为147.0。可以看出,右图中的向日葵的轮廓明显要比左图相对更为清晰。



本次分享就到这里,如果您有更棒的理解或者技术方案,或是疑问,欢迎随时在评论区分享或交流!我们下期blog见。
🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ


🌹꧔ꦿ本系列blog传送门:

OpenCV图像处理基本操作 【Python-Open_CV系列(一)】

OpenCV像素处理基本操作 【Python-Open_CV系列(二)】

OpenCV之 BGR、GRAY、HSV色彩空间&色彩通道专题 【Python-Open_CV系列(三)】

OpenCV绘制图像与文字(可作为脚手架代码)(python) 【Python-Open_CV系列(四)】

OpenCV图像几何变换专题(缩放、翻转、仿射变换及透视)【python-Open_CV系列(五)】

基于梵·高《向日葵》的 图像阈值处理专题(二值处理、反二值处理、截断处理、自适应处理及Otsu方法)【Python-Open_CV系列(六)】

OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】

《三英战吕布》 - 图像模板匹配 【Python-Open_CV系列(八)】

OpenCV滤波器 龙门石窟篇【Python-Open_CV系列(九)】(均值滤波器、中值滤波器、高斯滤波器、双边滤波器)

Open_CV形态学运算专题 (腐蚀&膨胀、开&闭运算、梯度运算、顶帽运算黑帽运算 )【Python-Open_CV系列(十)】

霍夫变换看不懂?小啾带你串一遍:OpenCV图形检测专题 这样学最简单【Python-Open_CV系列(十一)】

小啾带你开天眼 之 开启py-OpenCV摄像头及视频处理【Python-Open_CV系列(十二)】

小啾带你开天眼 之 人脸检测与识别(以及华强、皇叔、高祖配墨镜特效)【Python-Open_CV系列(十三)】

有关基于梵·高《向日葵》的 图像阈值处理专题(二值处理、反二值处理、截断处理、自适应处理及Otsu方法)【Python-Open_CV系列(六)】的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  6. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  7. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  8. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  9. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  10. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

随机推荐