OpenCV4(C++)—— 图像阈值化

news2024/11/26 19:32:23

文章目录

  • 前言
  • 一、固定阈值化 —— threshold
  • 二、自适应阈值化 —— adaptiveThreshold
  • 三、LUT查找表


前言

图像阈值化在许多计算机视觉和图像处理任务中都是一个重要的预处理步骤。在边缘检测过程中,通过将图像转换为二值图像,可以突出图像中的边缘信息。通过选择适当的阈值,可以使边缘更加明显,以便于进一步的分析和提取。在文字识别任务中,图像阈值化可以用于将文本与背景分离。通过将图像转换为二值图像,可以增强文字的对比度,方便后续的文字检测、定位和识别。在图像分割中,通过将图像转换为二值图像,可以将感兴趣的目标与背景区域进行分离。阈值化可以将目标对象与背景进行明显的分离,从而方便后续的目标检测、跟踪或分析。

一、固定阈值化 —— threshold

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

thresh:阈值,用于对比源图像像素值的值。
maxval:二值化过程的最大值,只在THRESH_BINARY和THRESH_BINARY_INV两种二值化方法中才使用,但是在使用其他方法是也需要输入(随便输任何值都行,反正不起作用)
type:阈值化类型,表示如何应用阈值化。常用的固定阈值类型有:
	cv::THRESH_BINARY:二值化。如果源图像像素值大于阈值,则将输出像素设置为 maxval,否则设置为 0。
	cv::THRESH_BINARY_INV:反向二值化。与 cv::THRESH_BINARY 相反,如果源图像像素值大于阈值,则将输出像素设置为 0,否则设置为 maxval。
	cv::THRESH_TRUNC:截断。如果源图像像素值大于阈值,则将输出像素设置为阈值,否则保持不变。
	cv::THRESH_TOZERO:零化。如果源图像像素值大于阈值,则保持不变,否则将输出像素设置为 0。
	cv::THRESH_TOZERO_INV:反向零化。与 cv::THRESH_TOZERO 相反,如果源图像像素值大于阈值,则将输出像素设置为 0,否则保持不变。
#include <opencv2/opencv.hpp>
#include<iostream>  
using namespace std;

int main()
{
    cv::Mat img = cv::imread("C:/Users/Opencv/temp/ocr.png");
    cv::Mat gray, grayB, grayB_V, imgB, imgB_V;
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);

    //cv::threshold(img, imgB, 125, 255, cv::THRESH_BINARY);
    //cv::threshold(img, imgB_V, 125, 255, cv::THRESH_BINARY_INV);
    //cv::imshow("Binary", imgB);
    //cv::imshow("Binary_V", imgB_V);

    cv::threshold(gray, grayB, 100, 255, cv::THRESH_BINARY);  // 设置阈值=100
    cv::threshold(gray, grayB_V, 100, 255, cv::THRESH_BINARY_INV);
    cv::imshow("Binary", grayB);
    cv::imshow("Binary_V", grayB_V);
    
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}

注:彩色图像进行阈值化时,是对每个通道单独进行处理,最后的结果依然是彩色图像。但目前来说,一般都是对灰度图像进行阈值化处理的场景比较多。

  上面第5个参数提到的5种阈值化方法都需要人为的设置一个阈值,阈值该设置为多少就需要自己判定了。OpenCV4给出了两种方法(OTSU 和 TRIANGLE)),结合图像灰度值分布特性获取二值化的阈值,并将阈值以函数返回值的形式给出。同样,虽然第三个参数thresh会自动给出,但是在调用函数的时候仍然不能缺省,需要自己随便设定一个,只是不会使用这个数值。(注:只能用在单通道的灰度图像)

使用方法就是在选择阈值化类型后,加 |
    cv:: Mat gray_BT, gray_BTT;
    cv::threshold(gray, gray_BT, 254, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);  //选择二值化类型,加THRESH_OTSU获取阈值
    cv::threshold(gray, gray_BTT, 254, 255, cv::THRESH_BINARY | cv::THRESH_TRIANGLE);

二、自适应阈值化 —— adaptiveThreshold

threshold全局都使用一个阈值,对于某些光影分布不均匀的图像,无论选择什么阈值,某些局部区域都会存在些许问题。其中一个方法就是对图像进行裁剪处理,将大图裁剪为多张小图,对这些小图再分别设置合适的阈值。此外,OpenCV中提供了一个局部自适应阈值的方法——adaptiveThreshold,该函数通过均值法和高斯法自适应的计算blockSize* blockSize邻域内的阈值,之后进行二值化

adaptiveThreshold(src, dst, maxval, adaptiveMethod, thresholdType, blockSize, C):

src:输入图像,只能是单通道灰度图像 CV_8UC1。
dst:输出图像,与输入图像具有相同的大小和类型。
maxval:当源图像的像素值超过阈值时,要给输出像素设置的值。
adaptiveMethod:自适应方法,用于确定每个像素的阈值。常用的方法有:
	cv::ADAPTIVE_THRESH_MEAN_C:使用邻域均值作为阈值。
	cv::ADAPTIVE_THRESH_GAUSSIAN_C:使用邻域加权平均作为阈值,权重是一个高斯窗口。
thresholdType:阈值化类型,只能是THRESH_BINARY和THRESH_BINARY_INV。
blockSize:邻域尺寸,用于计算每个像素的阈值。必须是奇数(一般为357的奇数),并且大于 1。
C:从平均或加权平均中减去的常数。它用于调整阈值的灵敏度。
    cv::Mat gray_ada, gray_ada2;
    cv::adaptiveThreshold(gray, gray_ada, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 7, 0);
    cv::adaptiveThreshold(gray, gray_ada2, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 7, 0);

  原图为一个阴影图片,都采用cv::THRESH_BINARY进行二值化处理。第二张是使用threshold,人为设定阈值为100;第三张和第四张是使用OTSU 和 TRIANGLE来自动获取全局阈值;第五张和第六张是使用上述的adaptiveThreshold的cv::ADAPTIVE_THRESH_MEAN_C和cv::ADAPTIVE_THRESH_GAUSSIAN_C的结果。
在这里插入图片描述

三、LUT查找表

上述无论是全局阈值还是局部阈值,每个像素都是跟一个阈值进行比较。在使用二值化处理时得到的结果总是单一的0或255像素;在使用截断或零化处理时,得到的是源像素或阈值像素。OpenCV中提供了LUT查找表的映射方法,相当于提供了多个阈值进行比较,能够自定义最终结果有几种像素。通过对图像的每个像素值进行查表操作,可以高效地实现各种图像处理任务。如图像滤波中的均值滤波和中值滤波,可以看成通过定义合适的滤波函数作为查找表,对图像进行滤波操作。

cv::LUT(src, lut, dst)

src: 输入图像矩阵,只能是CV_8U(0-255),可以是单通道或多通道
lut:256个像素灰度值的查找表,单通道或者与src通道数相同(即src为多通道时,lut可以设置为单通道或相同的多通道)
dst:输出图像矩阵,其尺寸与src相同,数据类型与lut相同
int main()
{
    cv::Mat img = cv::imread("C:/Users/Opencv/temp/lena.png");
    cv::imshow("原图", img);
    cv::Mat gray;
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
    
    // 固定二值化
    cv::threshold(gray, grayB, 185, 255, cv::THRESH_BINARY);
    cv::imshow("Binary", grayB);

    //LUT表映射
    uchar lut1[256];
    for (int i = 0; i < 256; i++)
    {
        if (i <= 75)
            lut1[i] = 0;
        if (i > 75 && i <= 185)
            lut1[i] = 125;
        if (i > 185)
            lut1[i] = 255;
    }
    cv::Mat lutTable(1, 256, CV_8UC1, lut1);

    cv::Mat out0;
    cv::LUT(gray, lutTable, out0);
    cv::imshow("lut", out0);

    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}

从结果图可以看出,固定阈值设定为185,高于185的像素转换为255白色,低于185的转换为0黑色,只有两种像素。使用的LUT表,设置了三种映射关系,所以结果图有三种像素(0,125,255).
在这里插入图片描述

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

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

相关文章

Qt:多语言支持,构建全面应用程序“

Qt&#xff1a;强大API、简化框架、多语言支持&#xff0c;构建全面应用程序" 强大的API&#xff1a;Qt提供了丰富的API&#xff0c;包括250多个C类&#xff0c;基于模板的集合、序列化、文件操作、IO设备、目录管理、日期/时间等功能。还包括正则表达式处理和支持2D/3D…

制作长图海报的详细指南,制作长图海报的5个步骤

制作长图海报是宣传活动、产品或服务的重要方式之一。乔拓云后台提供了丰富的海报模板&#xff0c;让你轻松制作出专业级的长图海报。下面将介绍如何使用乔拓云后台制作长图海报的技巧。 一、选择模板 首先&#xff0c;注册并登录乔拓云后台&#xff0c;进入云设计页面。在选择…

C语言学生成绩录入系统

一、系统概述 该系统是一个由链表创建主菜单的框架&#xff0c;旨在快速创建学生成绩录入系统的主菜单结构。其主要任务包括&#xff1a; 实现链表的创建、插入和遍历功能&#xff0c;用于存储和展示学生成绩录入系统各个模块的菜单项。 2. 提供用户友好的主菜单界面&#xf…

证件照换底色详细教程

说到证件照的底色更改&#xff0c;我想对大部分朋友来说是蛮头疼的事情&#xff0c;由于我们不论是在生活还是学习中&#xff0c;有时候总会要上传一些证件照&#xff0c;而当你手上有证件照准备上传时&#xff0c;发现底色不对&#xff0c;是不是很抓狂&#xff0c;现在&#…

SpringCloud学习笔记-Eureka的服务拉取

假设是OrderService里面拉取Eureka的服务之一User Service 1.依然需要在该服务里面引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependenc…

水波纹文字效果动画

效果展示 CSS 知识点 text-shadow 属性绘制立体文字clip-path 属性来绘制水波纹 工具网站 CSS clip-path maker 效果编辑器 页面整体结构实现 使用多个 H2 标签来实现水波纹的效果实现&#xff0c;然后使用clip-path结合动画属性一起来进行波浪的起伏动画实现。 <div …

分析性质+dp计数:1007T4

http://cplusoj.com/d/senior/p/SS231007D 分析题目性质&#xff0c;有&#xff1a; 按编号顺序最短路必然为连续段边只会在连续段内和相邻连续段之间连 i i i 段 连 i 1 i1 i1 段&#xff0c; i 1 i1 i1 段中每个点恰有1条来自 i i i 的边 然后肯定是考虑 f ( l , r )…

Edge浏览器下载文件被保存为 .crdownload 文件的问题小记

问题 近期使用Edge浏览器下载文件时&#xff0c;文件都被保存为 .crdownload 格式的文件了&#xff0c;不确定从哪个版本开始的。除非下载未完成导致文件不完整&#xff0c;否则不会被保存为 .crdownload 格式的文件&#xff1b;实际上文件已完成了下载&#xff0c;且手工修改…

Day4:Linux系统编程1-60P

我的学习方法是&#xff1a;Linux系统编程&#xff08;看pdf笔记&#xff09; Linux网络编程 WebServer 01P-17P Linux相关命令及操作 cp -a dirname1 dirname2 复制目录 cp -r dirname1 dirname2 递归复制目录 1 到目录 2 这里-a 和-r 的差别在于&#xff0c;-a 是完全复制…

深入了解 GMP

视频链接地址:Golang深入理解GPM模型_哔哩哔哩_bilibili 一、Golang“调度器”的由来? (1) 单进程时代不需要调度器 我们知道,一切的软件都是跑在操作系统上,真正用来干活(计算)的是CPU。早期的操作系统每个程序就是一个进程,直到一个程序运行完,才能进行下一个进程,就是…

大数据Doris(七):Doris安装与部署规划

文章目录 Doris安装与部署规划 一、软硬件需求 二、​​​​​​​资源规划

[Java] 服务端消息推送汇总

前言&#xff1a;当构建实时消息推送功能时&#xff0c;选择适合的方案对于开发高效的实时应用至关重要。消息的推送无非就推、拉两种数据模型。本文将介绍四种常见的消息实时推送方案&#xff1a;短轮询&#xff08;拉&#xff09;、长轮训&#xff08;拉&#xff09;、SSE&am…

详解C语言指针(二)

文章目录 1. 字符指针2. 指针数组3. 数组指针3.1 什么是数组指针&#xff1f;3.2 &数组名 VS 数组名 4. 数组参数4.1 一维数组传参4.2 二维数组传参 5. 函数指针6. 函数指针数组7. 指向函数指针数组的指针8. 回调函数 1. 字符指针 字符指针是指针类型的变量&#xff0c;其…

文本自动输入/删除的加载动画效果

效果展示 CSS 知识点 绕矩形四周跑的光柱动画实现animation 属性的 steps 属性值运用 页面基础结构实现 <div class"loader"><!-- span 标签是围绕矩形四周的光柱 --><span></span><span></span><span></span>&l…

Git 学习笔记 | 使用码云

Git 学习笔记 | 使用码云 Git 学习笔记 | 使用码云注册登录码云&#xff0c;完善个人信息设置本机绑定SSH公钥&#xff0c;实现免密码登录创建远程仓库 Git 学习笔记 | 使用码云 注册登录码云&#xff0c;完善个人信息 网址&#xff1a;https://gitee.com/ 可以使用微信&…

SpringBoot结合dev-tool 实现IDEA项目热部署

什么是热部署&#xff1f; 应用正在运行的时候升级功能, 不需要重新启动应用对于Java应用程序来说, 热部署就是在运行时更新Java类文件 通俗的来讲&#xff0c;应用在运行状态下&#xff0c;修改项目源码后&#xff0c;不用重启应用&#xff0c;会把编译的内容部署到服务器上…

【Acwing1010】拦截导弹(LIS+贪心)题解

题目描述 思路分析 本题有两问&#xff0c;第一问直接用lis的模板即可&#xff0c;下面重点看第二问 思路是贪心&#xff1a; 贪心流程&#xff1a; 从前往后扫描每一个数&#xff0c;对于每个数&#xff1a; 情况一&#xff1a;如果现有的子序列的结尾都小于当前的数&…

stm32的GPIO寄存器操作以及GPIO外部中断,串口中断

一、学习参考资料 &#xff08;1&#xff09;正点原子的寄存器源码。 &#xff08;2&#xff09;STM32F103最小系统板开发指南-寄存器版本_V1.1&#xff08;正点&#xff09; &#xff08;3&#xff09;STM32F103最小系统板开发指南-库函数版本_V1.1&#xff08;正点&a…

【重拾C语言】七、指针(一)指针与变量、指针操作、指向指针的指针

目录 前言 七、指针 7.1 指针与变量 7.1.1 指针类型和指针变量 7.1.2 指针所指变量 7.1.3 空指针、无效指针 7.2 指针操作 7.2.1 指针的算术运算 7.2.2 指针的比较 7.2.3 指针的递增和递减 7.3 指向指针的指针 前言 指针是C语言中一个重要的概念正确灵活运用指针 可…

单元测试该怎么写

单元测试对于开发人员来说很熟悉&#xff0c;各种语言都提供了单元测试的框架&#xff0c;用于自动化执行单元测试并生成测试报告。它通常提供了一组API和工具&#xff0c;使开发人员能够编写和运行测试用例&#xff0c;比较预期行为和实际行为之间的差异&#xff0c;并准确地识…