9.2自适应阈值分割

news2024/11/20 9:20:59

基本概念

在图像处理中,阈值分割是一种简单而有效的图像分割方法,它根据像素值将图像分割成前景和背景。自适应阈值分割是阈值分割的一种高级形式,它考虑了图像局部区域的亮度变化,从而能够更准确地分割图像。OpenCV是一个强大的计算机视觉库,它提供了多种图像处理和计算机视觉功能,包括自适应阈值分割。自适应阈值分割是图像处理中的一个重要概念,它可以根据局部区域的亮度来调整阈值,从而在光照不均匀或背景复杂的图像中获得更好的分割效果。这种方法特别适用于光照条件变化较大的场景,或者是背景与前景对比度不均匀的情况。

自适应阈值分割在 OpenCV 中可以通过 adaptiveThreshold 函数实现。这个函数允许你为图像的不同部分应用不同的阈值,这对于处理光照不均或者背景复杂变化的场景特别有用。

OpenCV中的自适应阈值分割

在OpenCV中,自适应阈值分割可以通过cv::adaptiveThreshold函数实现。这个函数允许我们指定一个局部区域的大小,以及一个用于计算阈值的算法(通常是平均值或加权平均值)。

void cv::adaptiveThreshold(InputArray src, OutputArray dst,   
                           double maxValue, int adaptiveMethod,   
                           int thresholdType, int blockSize, double C)

src: 输入的8位单通道图像。
dst: 输出图像,与输入图像有相同的尺寸和类型。
maxValue: 当像素值超过(或根据阈值类型小于)计算得到的阈值时赋予的像素值。
adaptiveMethod: 使用的自适应阈值算法。cv::ADAPTIVE_THRESH_MEAN_C表示使用局部区域的平均值减去C来计算阈值;cv::ADAPTIVE_THRESH_GAUSSIAN_C表示使用局部区域的高斯加权和减去C来计算阈值。
thresholdType: 阈值类型,必须是cv::THRESH_BINARY或cv::THRESH_BINARY_INV。
blockSize: 局部区域的大小,必须是正奇数。
C: 从均值或加权均值中减去的常数。

参数说明
src: 输入图像,通常是灰度图。
dst: 输出图像,必须与输入图像有相同的尺寸。
maxValue: 当像素值超过了阈值或低于阈值(取决于类型),将被赋予的最大值。
adaptiveMethod: 指定如何计算阈值。可以是:
    ADAPTIVE_THRESH_MEAN_C: 阈值是邻域均值减去常数C。
    ADAPTIVE_THRESH_GAUSSIAN_C: 阈值是邻域的加权和,权重为一个高斯窗口。
thresholdType: 指定应用阈值的方式。可以是:
    THRESH_BINARY: 如果像素值大于阈值,则设为最大值,否则设为0。
    THRESH_BINARY_INV: 如果像素值大于阈值,则设为0,否则设为最大值。
blockSize: 决定用于计算阈值的邻域大小,即一个正方形的边长。
C: 从邻域均值或加权和中减去的常数值。

C++ 实现自适应阈值分割的基本步骤:

1. 导入必要的头文件: 首先需要包含 OpenCV 的核心模块头文件。

#include <opencv2/opencv.hpp>
using namespace cv;

2. 读取图像: 使用 imread 函数从磁盘读取图像,并将其转换为灰度图,因为自适应阈值通常应用于灰度图像。

Mat src = imread("path/to/image.jpg", IMREAD_GRAYSCALE);
if (src.empty()) {
    std::cout << "Error: Image not found or unable to read the image." << std::endl;
    return -1;
}

3. 设置自适应阈值参数: 在调用 adaptiveThreshold 之前,你需要决定一些参数:
 •方法(ADAPTIVE_THRESH_MEAN_C 或 ADAPTIVE_THRESH_GAUSSIAN_C):前者使用邻域内的平均值作为阈值的基础,后者则使用加权平均值。
 •阈值类型(如 THRESH_BINARY 或 THRESH_BINARY_INV)。
 •邻域大小(blockSize):用于计算阈值的像素邻域的大小。
 •常数 C:从平均值(或加权平均值)中减去的常数值。

int blockSize = 11; // 邻域大小
int C = 2;          // 常数

4. 应用自适应阈值: 使用 adaptiveThreshold 函数来执行自适应阈值操作。

Mat dst;
adaptiveThreshold(src, dst, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, blockSize, C);

5. 显示结果: 可以通过 imshow 显示原始图像和处理后的图像,并等待用户按键退出。

namedWindow("Original Image", WINDOW_NORMAL);
imshow("Original Image", src);

namedWindow("Adaptive Threshold Result", WINDOW_NORMAL);
imshow("Adaptive Threshold Result", dst);

waitKey(0); // Wait for a keystroke in the window

6. 保存结果(可选): 如果需要,可以将结果保存到磁盘。
imwrite("path/to/output_image.jpg", dst);



以上就是使用 OpenCV 和 C++ 进行自适应阈值分割的基本流程。
需要注意的是,在实际应用中可能需要根据具体的图像内容调整参数以达到最佳效果。
此外,为了更好地理解如何选择合适的参数。

示例代码1

#include "pch.h"


#include<iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;


int main()
{
	Mat src = imread("809.jpeg", IMREAD_GRAYSCALE);
	if (src.empty())
	{
		std::cout << "Error: Image not found or unable to read the image." << std::endl;
		return -1;
	}



	int blockSize = 11; // 邻域大小
	int C = 2;          // 常数

	Mat dst;
	adaptiveThreshold(src, dst, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, blockSize, C);


	namedWindow("Original Image", WINDOW_NORMAL);
	imshow("Original Image", src);

	namedWindow("Adaptive Threshold Result", WINDOW_NORMAL);
	imshow("Adaptive Threshold Result", dst);

	waitKey(0); // Wait for a keystroke in the window


	imwrite("00.jpg", dst);

	return 0;
}

运行结果1

示例代码2

以下是一个简单的示例,展示如何使用OpenCV进行自适应阈值分割:

#include "pch.h"
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
	// 加载图像
	cv::Mat img = cv::imread("789.jpeg", cv::IMREAD_GRAYSCALE);
	if (img.empty())
	{
		std::cout << "Error: Image cannot be loaded!" << std::endl;
		return -1;
	}

	// 定义输出图像
	cv::Mat thresh;

	// 应用自适应阈值
	int blockSize = 11;  // 可以调整这个参数来改变邻域大小
	int C = 2;           // 常数C
	cv::adaptiveThreshold(img, thresh, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, blockSize, C);

	// 显示结果
	namedWindow("Original Image", WINDOW_NORMAL);
	cv::imshow("Original Image", img);

	namedWindow("Adaptive Threshold", WINDOW_NORMAL);
	cv::imshow("Adaptive Threshold", thresh);

	// 等待按键后关闭窗口
	cv::waitKey(0);

	return 0;
}

注意事项
blockSize的选择很重要,如果太大可能会导致细节丢失,太小则可能导致噪声增加。
常数C用于调整阈值,通常需要通过实验来找到合适的值。
对于非常复杂的场景或者需要高度精确的阈值分割,可能需要进一步的预处理或者结合其他图像处理技术。

运行结果2

示例代码3

下面是一个使用OpenCV C++ API进行自适应阈值分割的示例代码:

#include "pch.h"
#include <opencv2/opencv.hpp>  
#include <iostream>  

using namespace cv;
using namespace std;

int main() {
	// 加载图像  
	Mat src = imread("896.png", IMREAD_GRAYSCALE);
	if (src.empty()) 
	{
		cout << "Could not open or find the image!\n";
		return -1;
	}

	// 创建输出图像  
	Mat dst;

	// 应用自适应阈值分割  
	adaptiveThreshold(src, dst, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 11, 2);

	// 显示结果  
	namedWindow("Original Image", WINDOW_NORMAL);
	imshow("Original Image", src);
	namedWindow("Adaptive Thresholding", WINDOW_NORMAL);
	imshow("Adaptive Thresholding", dst);
	waitKey(0);

	return 0;
}

在这个示例中,我们使用ADAPTIVE_THRESH_MEAN_C作为自适应方法,THRESH_BINARY作为阈值类型,
11作为局部区域的大小(blockSize),
2作为从均值中减去的常数(C)。
这些参数可能需要根据你的具体图像进行调整以达到最佳效
果。

注意事项
局部区域的大小(blockSize)对结果有很大影响。较小的blockSize可能会导致图像过度分割,而较大的blockSize可能会导致图像中的细节丢失。
减去的常数(C)用于调整阈值的敏感度。调整这个值可以帮助改善分割效果。
自适应阈值分割特别适用于光照不均匀的图像,因为它可以根据图像的不同区域自动调整阈值。

运行结果3

实验代码4

#include "pch.h"
#include <opencv2/core/core.hpp>              
#include <opencv2/highgui/highgui.hpp>              
#include <opencv2/imgproc/imgproc.hpp>                
#include <opencv2\imgproc\types_c.h>
//#pragma comment(lib, "opencv_world450d.lib")  

using namespace cv;

int main()
{
	//------------【1】读取源图像并检查图像是否读取成功------------    
	Mat srcImage = imread("08.jpeg");
	if (!srcImage.data)
	{
		puts("读取图片错误,请重新输入正确路径!");
		system("pause");
		return -1;
	}
	namedWindow("【源图像】", WINDOW_NORMAL);
	imshow("【源图像】", srcImage);
	//------------【2】灰度转换------------    
	Mat srcGray;
	cvtColor(srcImage, srcGray, CV_RGB2GRAY);
	namedWindow("【灰度图】", WINDOW_NORMAL);
	imshow("【灰度图】", srcGray);
	//------------【3】初始化相关变量---------------  
	Mat dstImage;        //初始化自适应阈值参数
	const int maxVal = 255;
	int blockSize = 3;    //取值3、5、7....等
	int constValue = 10;
	int adaptiveMethod = 0;
	int thresholdType = 1;
	//---------------【4】图像自适应阈值操作-------------------------
	adaptiveThreshold(srcGray, dstImage, maxVal, adaptiveMethod, thresholdType, blockSize, constValue);

	namedWindow("【自适应阈值】", WINDOW_NORMAL);
	imshow("【自适应阈值】", dstImage);
	waitKey(0);
	return 0;
}

运行结果4

失败

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

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

相关文章

完全二叉树和堆排序

完全二叉树 完全二叉树满足以下两个条件&#xff1a; 所有层的节点都完全填满&#xff1a;除了最后一层外&#xff0c;每一层的节点数都是最大节点数&#xff0c;即除了最后一层&#xff0c;其他层的节点数都是满的。 最后一层的节点尽可能地向左排列&#xff1a;在满足第一…

调试技巧 conso.trace()

console 的 trace() 方法向 Web 控制台输出一个堆栈跟踪。 trace是一个很好的调试错误的办法&#xff0c; console.trace() 方法用于显示当前执行的代码在堆栈中的调用路径。 可以查看函数在哪一些地方做了调用 这个在找不出变量在何处被修改的时候&#xff0c;很有用 同时…

TCP网络编程概述、相关函数、及实现超详解

文章目录 TCP网络编程概述1. TCP协议的特点2. TCP与UDP的差异3. TCP编程流程 TCP网络编程相关函数详解1. socket()&#xff1a;创建套接字参数说明&#xff1a;返回值&#xff1a;示例&#xff1a; 2. connect()&#xff1a;客户端连接服务器参数说明&#xff1a;返回值&#x…

力扣每日一题 公司命名 集合 找规律

Problem: 2306. 公司命名 &#x1f468;‍&#x1f3eb; 灵神题解 class Solution {public long distinctNames(String[] ideas) {// 创建一个大小为26的HashSet数组&#xff0c;用于存储每个首字母对应的字符串集合Set<String>[] groups new HashSet[26];Arrays.set…

基于Python大数据的音乐推荐及数据分析可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

Cadence Allegro17.4 板框倒角

一、Cadence Allegro 板框倒角有倒斜角和倒圆角两种形式&#xff1a; 1、 板框倒斜角 2、 板框倒圆角 二、有些时候不能倒角 如果我们绘制的板框是Shape属性的是不能正常倒角设置&#xff0c;要将Shape属性的板框更改为lines属性的板框。 1、 选择菜单栏Shape——Decompose …

Wireshark_流量分析

在当今数字化的时代&#xff0c;网络流量分析对于确保网络的稳定运行、排查故障以及保障网络安全至关重要。Wireshark 作为一款功能强大的网络数据包分析工具&#xff0c;为我们提供了多种实用的功能&#xff0c;帮助我们深入了解网络中的数据传输情况。 1、数据包筛选 数据包…

HTTP和HTTPS的区别,HTTP协议转HTTPS协议测试需要注意内容

简单快捷&#xff1a;HTTP 相对于 HTTPS 更简单和快速。在开发过程中&#xff0c;可能频繁地修改代码并测试&#xff0c;使用 HTTP 可以减少一些开发中的额外步骤和复杂性。 不涉及敏感信息&#xff1a;在本地开发环境中&#xff0c;通常不涉及真实用户数据或敏感信息的传输&a…

单链表实现和数组模拟单链表

现在有一个排好序的若干个元素(升序),现在要插入一个元素啊&#xff0c;请你输入插入该元素后的序列(升序) 请分别用单链表实现&#xff0c;和数组模拟单链表实现 为什么要用数组模拟单链表 1.内存局部性&#xff1a;数组在内存中是连续存储的&#xff0c;因此在访问元素时可…

了解针对基座大语言模型(类似 ChatGPT 的架构,Decoder-only)的重头预训练和微调训练

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 随着自然语言处理&#xff08;NLP&#xff09;技术的飞速进步&#xff0c;基于 Transformer 架构的大语言模型在众多任务中取得了显著成就。特别是 Decoder-only 架构&#xff0c;如 GPT 系列模型&…

“警警”有条:zCloud告警中心的告警与处置实践

ENMOTECH 随着金融行业数字化转型步伐的加快&#xff0c;海量数据处理成为常态&#xff0c;而作为数据存储和管理的核心——数据库的稳定性与效率直接影响着企业的运营成效。某金融科技企业使用了近10个品类、300余套数据库来承载业务&#xff0c;在专业运维、集中管理等方面都…

【操作系统】速成3

Linux内核和windows内核 原来鸿蒙是微内核 windows混合内核 参考&#xff1a;xiaolincoding.com

5种强大的方式:AI在临终关怀中提升护理质量,改善生活

目录 什么是临终关怀中的AI&#xff1f;AI如何个性化临终关怀&#xff1f;AI如何改善临终关怀患者的生活质量&#xff1f; 疼痛管理症状管理的预测分析情感和心理支持高效的资源分配减轻家庭压力 临终关怀中AI的未来 近年来&#xff0c;医疗保健行业在人工智能&#xff08;AI…

MySQL --事务(上)

文章目录 1.什么是事务1.1为什么会出现事务1.2 事务的版本支持1.3 事务提交方式1.4事务常见操作方式1.4.1正常演示 - 证明事务的开始与回滚1.4.2非正常演示1 - 证明未commit&#xff0c;客户端崩溃&#xff0c;MySQL自动会回滚&#xff08;隔离级别设置为读未提交&#xff09;1…

Ubuntu环境切换到服务器某个用户后source等命令和Tab快捷补全都用不了了,提示没找到,但root用户可以

以escs用户为例&#xff1a; 输入以下命令 grep root /etc/passwd grep escs /etc/passwd 对比发现&#xff0c;root用户配的是bash&#xff0c;而escs却是sh&#xff0c; 所以把escs的sh改成和root一样的bash&#xff0c;命令为 usermod -s /bin/bash escs 改好后就可以了。 …

Win11 安装 PostgreSQL 数据库,两种方式详细步骤

文章目录 一、exe文件安装 &#xff08;推荐&#xff09;下载安装包1. 选择操作系统2. 跳转到EDB&#xff08;PostgreSQL 的安装包托管在 EDB上&#xff09;3. 选择版本点击下载按钮 安装1. 管理员打开安装包2. 选择安装目录3. 勾选安装项4. 设置数据存储目录5. 设置管理员密码…

C语言线程编程深度解析

文章目录 前言一、线程基础概念1. 什么是线程&#xff1f;2. 线程与进程的区别 二、POSIX线程库&#xff08;pthread&#xff09;1. pthread简介2. 编译与链接3. 创建线程示例代码&#xff1a; 4. 线程同步互斥锁&#xff08;Mutex&#xff09;示例代码&#xff1a; 条件变量&a…

SpringBoot代码实战(MyBatis-Plus+Thymeleaf)

构建项目 修改pom.xml文件&#xff0c;添加其他依赖以及设置 <!--MyBatis-Plus依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.6</version><…

智源研究院与百度达成战略合作 共建AI产研协同生态

2024年9月24日&#xff0c;北京智源人工智能研究院&#xff08;简称“智源研究院”&#xff09;与北京百度网讯科技有限公司&#xff08;简称“百度”&#xff09;正式签署战略合作协议&#xff0c;双方将充分发挥互补优势&#xff0c;在大模型等领域展开深度合作&#xff0c;共…

共享打印机无法创建打印作业原因分析及解决方法

在日常办公和生活中&#xff0c;打印机是不可或缺的重要设备。然而&#xff0c;有时在添加打印机的过程中&#xff0c;经常会遇各种问题。今天有个小伙伴问我在访问共享打印机时提示“无法创建打印作业”怎么回事&#xff1f;今天小编就教大家共享打印机无法创建打印作业原因分…