【OpenCV实现图像阈值处理】

news2024/9/25 11:11:48

文章目录

    • 概要
    • 简单阈值调整
    • 自适应阈值调整
    • 大津(Otsu's)阈值法
    • Otsu's 二值化是如何工作的

概要

OpenCV库中的图像处理技术,主要分为几何变换、图像阈值调整和平滑处理三个部分。

在几何变换方面,OpenCV提供了cv.warpAffine和cv.warpPerspective函数,用于实现仿射变换和透视变换。这些技术包括缩放、平移、旋转等,通过变换矩阵的运用,可以实现图像的各种变换操作。

图像阈值调整是将图像的像素值按照一定规则进行二值化处理,OpenCV提供了cv.threshold函数,支持多种阈值处理类型,如二值化、反二值化、截断、阈值以下置零等。还有自适应阈值调整,它可以根据图像的局部特性动态调整阈值,适用于光照不均匀的情况。

另外,介绍了大津(Otsu’s)阈值法,该方法是一种自动确定全局阈值的技术。通过计算图像的直方图,找到最佳阈值,实现图像的二值化处理。

简单阈值调整

简单的阈值调整,自适应阈值和大津阈值法。
函数 cv.threshold 和 cv.adaptiveThreshold

在图像处理中,阈值调整是一种基本技术。其核心思想是对图像的每个像素应用相同的阈值规则,如果像素值低于阈值,就将其设置为0,反之则设置为最大值。OpenCV提供了用于阈值调整的函数cv.threshold。该函数的第一个参数是源图像,必须是灰度图像;第二个参数是阈值,用于区分像素值;第三个参数是最大值,当像素值超过阈值时,会被设置为这个值。OpenCV还提供了不同的阈值调整类型,通过第四个参数来选择。常用的阈值调整类型包括:

cv.THRESH_BINARY:超过阈值的像素值设为最大值,其他设为0。
cv.THRESH_BINARY_INV:超过阈值的像素值设为0,其他设为最大值。
cv.THRESH_TRUNC:超过阈值的像素值设为阈值,其他像素值不变。
cv.THRESH_TOZERO:超过阈值的像素值不变,其他设为0。
cv.THRESH_TOZERO_INV:超过阈值的像素值设为0,其他不变。

这些类型的具体应用可以根据需求选择。cv.threshold函数返回两个输出:第一个是使用的阈值,第二个是阈值化后的图像。选择合适的阈值调整类型和阈值参数可以有效地处理图像,提取出感兴趣的信息。详细了解每种类型的使用场景,可以参考OpenCV的相关文档以获取更多信息。

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

# 读取灰度图像
img = cv.imread('img.png', 0)

# 使用cv.threshold进行阈值调整,得到不同类型的阈值化图像
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循环显示图像和标题
for i in range(6):
    plt.subplot(2, 3, i + 1)  # 2行3列的子图中的第i+1个
    plt.imshow(images[i], 'gray', vmin=0, vmax=255)  # 显示灰度图像,灰度范围0-255
    plt.title(titles[i])  # 设置子图标题
    plt.xticks([]), plt.yticks([])  # 隐藏坐标轴

# 显示图像
plt.show()

我们使用 plt.subplot() 函数来排列图像。
这段代码输出这个结果。
在这里插入图片描述

自适应阈值调整

在图像处理中,使用全局阈值可能不适用于所有情况。例如,当图像在不同区域具有不同的光照条件时,使用固定阈值可能导致不准确的结果。为了解决这个问题,我们可以采用自适应阈值调整的方法。这种方法根据像素周围的小区域确定每个像素的阈值,因此,同一张图像的不同区域可以获得不同的阈值,从而更好地适应图像中的光照变化。

在OpenCV中,cv.adaptiveThreshold函数用于实现自适应阈值调整。该函数接受三个主要参数:

adaptiveMethod: 它决定了阈值如何被计算。
    cv.ADAPTIVE_THRESH_MEAN_C:阈值是邻域像素的平均值减去常数C。
    cv.ADAPTIVE_THRESH_GAUSSIAN_C:阈值是邻域像素的高斯加权平均值减去常数C。

blockSize: 它指定了邻域的大小。该值定义了算法在图像中寻找阈值时所考虑的像素邻域范围。

C: 它是一个常数,用于从计算得到的阈值中减去,可以调整阈值的灵敏度。

通过调整这些参数,我们可以更精确地适应不同区域的光照变化,从而得到更准确的图像处理结果。


import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

img = cv.imread('img.png', 0)
img = cv.medianBlur(img, 5)

ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)
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 Thresholding (v = 127)',
          'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']

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()

在这里插入图片描述

大津(Otsu’s)阈值法

在全局阈值调整中,我们必须手动选择一个适当的阈值来将图像分为目标和背景。然而,在某些情况下,我们无法确定最佳的阈值,尤其是当图像具有复杂的光照变化或噪声时。在这种情况下,使用大津(Otsu)阈值法是一个更好的选择。

大津阈值法适用于具有双峰直方图(即具有两个明显峰值)的图像。在这种情况下,图像的直方图将具有两个主要的峰值,分别代表目标和背景像素的灰度级别。大津方法的目标是找到一个最佳的阈值,将这两个峰值之间的灰度级别作为分割点。

在OpenCV中,我们使用cv.threshold()函数,并将cv.THRESH_OTSU作为阈值类型的额外参数传递。大津算法会自动确定最佳阈值,并将其作为函数的返回值。这样,我们就不需要手动选择阈值,而是依赖算法找到最适合的分割点,使图像的分割更准确。


import cv2 as cv

import numpy as np

from matplotlib import pyplot as plt

img = cv.imread('img.png',0)

# 全局阈值

ret1,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)

# Otsu's

ret2,th2 = cv.threshold(img,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)

# 高斯后Otsu's

blur = cv.GaussianBlur(img,(5,5),0)

ret3,th3 = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)

# 展示所有图片

images = [img, 0, th1,
          img, 0, th2,
          blur, 0, th3]

titles = ['Original Noisy Image','Histogram','Global Thresholding(v=127)',
          'Original Noisy Image','Histogram',"Otsu's Thresholding",
          'Gaussian filtered Image','Histogram',"Otsu's Thresholding"]

for i in range(3):

    plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray')

    plt.title(titles[i*3]), plt.xticks([]), plt.yticks([])

    plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)

    plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([])

    plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')

    plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])

plt.show()

在这里插入图片描述

Otsu’s 二值化是如何工作的

Otsu’s二值化算法是一种自动确定图像阈值的方法。该算法的目标是找到一个阈值 tt,使得将图像的灰度级别分为两个类别(背景和前景),并且这两个类别的内部方差最小。

在具体实现中,我们首先计算图像的直方图,该直方图显示了不同灰度级别的像素数量。接着,算法尝试在直方图中找到两个主要的峰值,这两个峰值分别代表了背景和前景像素的灰度级别。然后,Otsu’s算法尝试选择一个阈值 tt,将这两个峰值之间的灰度级别作为分割点。

为了选择最佳的阈值 tt,算法将尝试所有可能的阈值,并计算对应的两个类别的内部方差。内部方差越小,说明两个类别之间的差异越小,图像分割得越好。最终,选择使内部方差最小的阈值 tt 作为最佳阈值,将图像二值化。
在这里插入图片描述

这种方法的核心思想是通过寻找使得两个类别差异最小的阈值,实现图像的自动分割。对于了解过线性规划或神经网络的人来说,这个思想可能更容易理解。

import cv2 as cv
import numpy as np
img = cv.imread('img.png',0)
blur = cv.GaussianBlur(img,(5,5),0)

# 求归一化直方图及其累积分布函数

hist = cv.calcHist([blur],[0],None,[256],[0,256])
hist_norm = hist.ravel()/hist.sum()
Q = hist_norm.cumsum()

bins = np.arange(256)

fn_min = np.inf
thresh = -1

for i in range(1,256):

    p1,p2 = np.hsplit(hist_norm,[i]) # 概率

    q1,q2 = Q[i],Q[255]-Q[i] # 类型总和

    if q1 < 1.e-6 or q2 < 1.e-6:

        continue

    b1,b2 = np.hsplit(bins,[i]) # weights

    # 寻找均值和方差

    m1,m2 = np.sum(p1*b1)/q1, np.sum(p2*b2)/q2

    v1,v2 = np.sum(((b1-m1)**2)*p1)/q1,np.sum(((b2-m2)**2)*p2)/q2

    # 计算最小化函数

    fn = v1*q1 + v2*q2

    if fn < fn_min:

        fn_min = fn

        thresh = i

# 使用 OpenCV 函数找到 otsu 的阈值

ret, otsu = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)

print( "{} {}".format(thresh,ret) )
# 显示原始图像和Otsu's 二值化结果
cv.imshow('Original Image', img)
cv.imshow('Otsu Thresholding', otsu)
cv.waitKey(0)
cv.destroyAllWindows()

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1133858.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4、让电机转起来【51单片机控制步进电机-TB6600系列】

摘要&#xff1a;本节介绍用简单的方式&#xff0c;让步进电机转起来。其目的之一是对电机转动有直观的感受&#xff0c;二是熟悉整个开发流程。 本系列教程必要的51单片机基础包括IO口操作、中断、定时器三个部分&#xff0c;相关基础教程网上很多&#xff0c;可以自行学习 一…

VMware Ubuntu 关闭自动更新

##1. VMware 17Pro&#xff0c;ubuntu16.04 关闭自动更新 1.1 编辑–》 首选项–》更新–》启动时检查产品更新 2. 这里关了还不够&#xff0c;第二天打开的时候还是提醒系统更新&#xff0c;需要关闭另外的地方 3. 关闭更新检查&#xff0c;默认的是隔天检查一次&#xff0c;…

怎么修复vcomp140.dll丢失问题?5个详细的修复方法分享

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“vcomp140.dll丢失”。那么&#xff0c;vcomp140.dll是什么&#xff1f;它丢失会造成哪些问题呢&#xff1f;小编将从以下几个方面进行详细阐述。 一、vcomp140.dll是什么&#xff1f; vco…

如何使用透明贴图实现火焰效果

1、透明贴图的原理 透明贴图是一种纹理贴图&#xff0c;用于模拟物体部分或全部的透明效果。其原理基于透明度和混合技术。 在计算机图形中&#xff0c;如何显示透明的物体是一个具有挑战性的问题。这是因为透明物体不会像不透明物体那样完全遮挡后面的物体&#xff0c;而是允…

【REDIS】redis-命令大全

【REDIS】redis-命令大全 redis-命令的官方文档 键命令 序号命令及描述1DEL key 该命令用于在 key 存在时删除 key。2DUMP key 序列化给定 key &#xff0c;并返回被序列化的值。3EXISTS key 检查给定 key 是否存在。4EXPIRE key seconds 为给定 key 设置过期时间&#xf…

Python爬虫核心模块urllib的学习

​ 因为在玩Python challenge的时候&#xff0c;有用过这个模块&#xff0c;而且学习这个模块之后也对系统学习网络爬虫有用。 ​ 当时查了各种资料学习&#xff0c;没有碰官网文档&#xff08;因为还是对英语有抗拒性&#xff09;&#xff0c;但是还是官方的文档最具权威和学…

使用Java做业务开发,如何做好一个定时任务的技术选型?

1. 轻量级任务调度 Quartz Scheduler 适用场景: 单机或简单的分布式任务调度特点: 提供丰富的调度选项&#xff0c;如Cron表达式、固定间隔等&#xff1b;支持持久化&#xff0c;能够在应用重启后恢复任务&#xff1b;支持任务监听和触发器监听。建议: 如果你的应用是基于Spr…

搭建docker本地仓库

1.拉取私有仓库镜像 [rootmaster1 ~]# docker pull registry [rootmaster1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx v1 546db553f62a About an hour ago …

ftp远程连接传输的常见问题有哪些?如何一站式解决传输问题?

众多传统老行业很多已经部署了FTP传输相关系统&#xff0c;随着数据量和文件量的增加&#xff0c;一些相应的问题也出现了&#xff0c;些问题可能会影响传输的效率和安全性。本文将介绍FTP的常见问题和解决方法&#xff0c;并说明为什么大文件传输平台可以帮助企业实现更快更安…

安卓主板_MTK联发科4G低功耗安卓主板开发板方案

ZM358-DP安卓主板是一款性能功能强大的4G安卓平台。它采用了联发科MTK6737、MTK8735、MTK6753、MTK6735等芯片平台&#xff0c;64位四核Cortex-A53架构&#xff0c;主频高达1.3GHz&#xff0c;搭载ARM Mail-T450 MP2 GPU。 安卓主板具备多路显示屏接口&#xff0c;包括双LVDS、…

强劲升级,太极2.x你值得拥有!

嗨&#xff0c;大家好&#xff0c;最近桃桃没顾得上给大家分享好用好玩的软件。 还记得前段时间给大家分享的太极1.0软件&#xff1f; 最近大佬对软件进行了全新升级&#xff0c;升级后的功能更强更稳定&#xff0c;轻度用户使用基本功能就已经足够了&#xff0c;壕无人性的同学…

广州华锐互动:VR技术应用到工程项目施工安全培训的好处

随着科技的飞速发展&#xff0c;虚拟现实(VR)技术已经深入到各个领域。在建筑施工领域&#xff0c;VR技术的应用为工程项目施工安全培训带来了许多好处。本文将探讨VR技术在这方面的优势和应用。 首先&#xff0c;VR技术能够提供沉浸式的安全培训体验。通过VR设备&#xff0c;学…

cuDNN安装成功

验证方法&#xff1a;winR cmd进入安装目录下&#xff0c;再进入到 extras\demo_suite下&#xff0c;执行.\bandwidthTest.exe和.\deviceQuery.exe&#xff0c;得到下图。

蓝桥算法赛(摆玩具)

问题描述 小蓝是一个热爱收集玩具的小伙子&#xff0c;他拥有 n 个不同的玩具。 这天&#xff0c;他把 n 个玩具按照高度顺序从矮到高摆放在了窗台上&#xff0c;然后&#xff0c;他希望将这些玩具分成 k 个段&#xff0c;使得所有分段的极差之和尽可能小。 具体来说&…

Vue props实现父组件给子组件传递数据

Vue中的配置项Props能让组件接收外部传递过来的数据。 一、传递数据 在要传递的组件标签中配置传递信息&#xff1a; 属性名 "属性值" 注意&#xff1a;如果传递的属性值是一个表达式&#xff0c;要使用&#xff1a;属性名"属性值" 的形式。 二、接收数…

竞赛选题 深度学习动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

FLStudio21汉化破解激活版下载,Fl Studio 2024中文破解版激活补丁

最新版本FL Studio 21官方中文汉化激破解版是比利时Image-Line公司开发的DAW。在去年DTM站的DAW调查中&#xff0c;在世界上很受欢迎&#xff0c;特别是作为EDM制作工具被广泛使用。从1997年以FruityLoops的名字发行的时候开始&#xff0c;FL Studio 21就一直作为Windows专用的…

软件工程17-18期末试卷

2.敏捷开发提倡一个迭代80%以上的时间都在编程&#xff0c;几乎没有设计阶段。敏捷方法可以说是一种无计划性和纪律性的方法。错 敏捷开发是一种软件开发方法论&#xff0c;它强调快速响应变化、持续交付有价值的软件、紧密合作和适应性。虽然敏捷方法鼓励迭代开发和灵活性&…

RK3568驱动指南|第七期-设备树-第60章 实例分析:GPIO

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

2023软件测试面试问题全在这,刷完即就业

Part1 1、你的测试职业发展是什么&#xff1f; 测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&#xff0c;按如何做好测试工程师的要点去要求自…