C/C++开发,opencv阀值操作

news2024/11/24 5:55:41

目录

一、OpenCV-阀值操作

1.1阀值操作函数threshold

1.2threshold的操作类型

1.3Otsu算法

二、样例开发

2.1 Makefile

2.2 main.cpp

2.3 运行效果

三、OpenCV-自适应阀值操作

        3.1 自适应阀值操作函数-adaptiveThreshold

3.2 样例开发


一、OpenCV-阀值操作

1.1阀值操作函数threshold

        在OpenCV中,阀值操作是一种基本的图像处理方法,用于将灰度图像转换为二值图像。这个操作是通过使用一个设定的阈值(thresh)来比较输入图像的每个像素值,并根据比较结果将像素值设置为0或最大值(maxval)。有五种不同的阀值操作类型,包括二进制阀值化、反二进制阀值化、截断阀值化、阀值化为0、反阀值化为0。

        在OpenCV-C++源码中,其阀值操作函数定义在\opencv2\imgproc.hpp中:

@param src input array (multiple-channel, 8-bit or 32-bit floating point).
@param dst output array of the same size  and type and the same number of channels as src.
@param thresh threshold value.
@param maxval maximum value to use with the #THRESH_BINARY and #THRESH_BINARY_INV thresholding
types.
@param type thresholding type (see #ThresholdTypes).
@return the computed threshold value if Otsu's or Triangle methods used.

@sa  adaptiveThreshold, findContours, compare, min, max
 */
CV_EXPORTS_W double threshold( 
    InputArray src, 
    OutputArray dst,         
    double thresh, 
    double maxval, 
    int type );

        该函数threshold将固定级别的阈值设置应用于多通道阵列。该函数通常用于从灰度图像中获得双层(二进制)图像或用于去除噪声,即过滤掉太小或太大的像素价值观该函数支持多种类型的阈值处理。它们由类型参数。此外,特殊值#THRESH_OTSU或#THRESH-TRIANGLE可以与以上值。在这些情况下,函数使用Otsu或三角算法,并使用它来代替指定的阈值。注意:目前,Otsu和Triangle方法仅适用于8位单通道图像。

1.2threshold的操作类型

        如果对卷积核有所了解的话,也可以把阀值操作看做是一个用1*1的核进行卷积,对每个像素进行一次非线性操作。

        在OpenCV中,阀值操作有五种类型(int type),分别是:

  1. THRESH_BINARY = 0:二值化,大于阈值的为255,小于阈值的为0。
  2. THRESH_BINARY_INV = 1:反二值化,大于阈值的为0,小于阈值的为255。
  3. THRESH_TRUNC = 2:截断法,大于阈值的取阈值,小于阈值的不变。
  4. THRESH_TOZERO = 3:大于阈值的不变,小于阈值的为0。
  5. THRESH_TOZERO_INV = 4:大于阈值的为0,小于阈值的不变。

        在使用时可以根据实际需求选择相应的类型。

1.3Otsu算法

        函数cv::threshold可以自动决定最优的阀值,只需要对参数thresh传递THRESH_OTSU。Otsu算法是一种确定图像二值化最优阈值的算法,其原理是利用最大类间方差法来确定图像的阈值,从而将图像分割成前景和背景两部分。

        Otsu算法的基本思想是:假设输入图像的高为、宽为,代表其归一化所获得的图像灰度直方图,代表灰度值等于的像素点的个数在图像中占的比例。首先,计算灰度直方图的零阶累积矩(也称为累加直方图)和一阶累积矩;然后,计算图像总体的灰度平均值,其实就是时的一阶累积矩;接着,对于每个灰度级作为阈值,计算前景区域的平均灰度、背景区域的平均灰度和整幅图像的平均灰度的方差,对方差的衡量采用以下度量;最后,找到使类间方差最大时的对应的灰度级作为最优阈值。

        Otsu算法是一种自适应阈值确定的方法,计算简单,效率高,但对于光照不均的图像处理效果不是很好。

二、样例开发

2.1 Makefile

关于opencv编辑及库生成、调用等请参考本专栏的前面博文,这里不展开。    编译命令:mingw32-make -j4或make -4。

#/bin/sh
CX= g++ 

BIN 		:= ./
TARGET      := transform_img1.exe
FLAGS		:= -std=c++11 -static
SRCDIR 		:= ./
#INCLUDES
INCLUDEDIR 	:= -I"../../opencv_MinGW/include" 
#-I"$(SRCDIR)"
staticDir   := ../../opencv_MinGW/x64/mingw/staticlib/
#LIBDIR		:= $(staticDir)/libopencv_world460.a\
#			   $(staticDir)/libade.a \
#			   $(staticDir)/libIlmImf.a \
#			   $(staticDir)/libquirc.a \
#			   $(staticDir)/libzlib.a \
#			   $(wildcard $(staticDir)/liblib*.a) \
#			   -lgdi32 -lComDlg32 -lOleAut32 -lOle32 -luuid 
#opencv_world放弃前,然后是opencv依赖的第三方库,后面的库是MinGW编译工具的库

LIBDIR 	    := -L $(staticDir) -lopencv_world460 -lade -lIlmImf -lquirc -lzlib \
				-llibjpeg-turbo -llibopenjp2 -llibpng -llibprotobuf -llibtiff -llibwebp \
				-lgdi32 -lComDlg32 -lOleAut32 -lOle32 -luuid 
source		:= $(wildcard $(SRCDIR)/*.cpp) 

$(TARGET) :
	$(CX) $(FLAGS) $(INCLUDEDIR) $(source)  -o $(BIN)/$(TARGET) $(LIBDIR)

clean:
	rm  $(BIN)/$(TARGET)

2.2 main.cpp

#include "opencv2/opencv.hpp" //Include file for every supported OpenCV function 
#include <iostream>
#include <vector>
using namespace std;
//阀值化
void sum_rgb1( const cv::Mat& src, cv::Mat& dst )
{
	// Split image onto the color planes
	//
	vector< cv::Mat> planes;
	cv::split(src,planes);
	cv::Mat b = planes[0],g = planes[1],r = planes[2],s;
	// Add equally weighted rgb values
	//
	cv::addWeighted( r,1./3., g,1./3., 0.0,s );
	cv::addWeighted( s,1., b,1./3.,0.0,s );
	// Truncate values above 100
	//
	cv::threshold( s,dst,100,100,cv::THRESH_TRUNC );
}
//组合与阀值图像平面
void sum_rgb2( const cv::Mat& src,cv::Mat& dst )
{
	// Split image onto the color planes
	//
	vector<cv::Mat> planes;
	cv::split(src,planes);
	cv::Mat b = planes[0],g = planes[1],r= planes[2];
	// Accumulate separate planes, combine and threshold
	//
	cv::Mat s = cv::Mat::zeros(b.size(),CV_32F);
	cv::accumulate(b,s);
	cv::accumulate(g,s); 
	cv::accumulate(r,s);
	// Truncate values above 100 and rescale into dst.
	cv::threshold( s,s,100,100,cv::THRESH_TRUNC );
	s.convertTo(dst,b.type());
}

void help()
{
	cout <<"Call: ./1.PNG"<< endl;
	cout << "Shows use of alpha blending (addweighted) and threshold" << endl;
}

int main(int argc,char** argv){
	help();
	if(argc< 2){ cout <<"specify input image" << endl; return -1;}
	// Load the image from the given file name
	//
	cv::Mat src = cv::imread( argv[1] ),dst;
	if( src.empty() ){
		cout << "can not load " << argv[1] << endl; 
		return -1;
	}
	// sum_rgb1( src,dst);
	sum_rgb2( src,dst);
	// Create a named window with the name of the fle and
	// show the image in the window1
	cv::imshow( argv[1],dst );
	// Idle until the user hits any key
	//
	cv::waitKey(0);
	return 0;
}

2.3 运行效果

三、OpenCV-自适应阀值操作

        3.1 自适应阀值操作函数-adaptiveThreshold

        自适应阀值操作adaptiveThreshold和前面的阀值化方法不同,其阀值在整个过程中自动产生变化。同样在在\opencv2\imgproc.hpp中定义。在OpenCV中,自适应阈值操作是一种更为高级的阈值处理方法,用于处理具有非均匀亮度的图像。自适应阈值操作的基本思想是:对于每个像素,都使用其邻域的像素值来计算其阈值。这个邻域的像素值通常包括该像素周围的8个或16个像素。这种方法的优点是能够更好地适应图像的非均匀亮度。

@param src Source 8-bit single-channel image.
@param dst Destination image of the same size and the same type as src.
@param maxValue Non-zero value assigned to the pixels for which the condition is satisfied
@param adaptiveMethod Adaptive thresholding algorithm to use, see #AdaptiveThresholdTypes.
The #BORDER_REPLICATE | #BORDER_ISOLATED is used to process boundaries.
@param thresholdType Thresholding type that must be either #THRESH_BINARY or #THRESH_BINARY_INV,
see #ThresholdTypes.
@param blockSize Size of a pixel neighborhood that is used to calculate a threshold value for the
pixel: 3, 5, 7, and so on.
@param C Constant subtracted from the mean or weighted mean (see the details below). Normally, it
is positive but may be zero or negative as well.

@sa  threshold, blur, GaussianBlur
 */
CV_EXPORTS_W void adaptiveThreshold( 
    InputArray src, 
    OutputArray dst,
    double maxValue, 
    int adaptiveMethod,
    int thresholdType, 
    int blockSize, 
    double C );

参数:
    src:输入图像,应该是灰度图像。
    dst:输出图像
    maxValue:输出图像的最大值。
    adaptiveMethod:自适应阈值算法的选择,可以是ADAPTIVE_THRESHOLD_MEAN_C或ADAPTIVE_THRESHOLD_GAUSSIAN_C。
    thresholdType:阈值类型,通常是THRESH_BINARY或THRESH_BINARY_INV。
    blockSize:用于计算阈值的邻域大小。
    C:加到阈值上的常数,以调整阈值。

        cv::adaptiveThreshold()根据adaptiveMethod的设置,允许两种不同的自适应阙值方法。两种方法都是逐个像素地计算自适应阙值T(x,y),方法是通过计算每个像素位置周围的b*b区域的加权平均值然后减去常数C,其中b由blocksize给定。不同的是,如果选择的均值方法是cv::ADAPTIVE THRESH MEAN C,那么均值时取得权值是相等的,如果选择的均值方法是cv::ADAPTIVE THRESH GAUSSIAN C(x,y)周围的像素的权值则根据其到中心点的距离通过高斯方程得到。
        对于thresholdType阈值类型来说 ,adaptiveThreshold函数的类型和threshold函数的类型相同。相对于一般的闽值化操作,当图像中出现较大的明暗差异时,自适应闽值时非常有效的。这个函数仅处理单通道8位或浮点型图像,并且要求源图像和目标图像不同。

3.2 样例开发

        Makefile文件,与前面的Makefile文件几乎一致,仅将输出程序名调整一下:

#TARGET      := transform_img1.exe
TARGET      := transform_img2.exe

       编译命令:mingw32-make -j4或make -4

        main.cpp实现

#include "opencv2/opencv.hpp" //Include file for every supported OpenCV function 

#include<iostream>
using namespace std;
int main( int argc,char** argv )
{
	if(argc != 7){ 
		cout <<"Usage:"<<argv[0] <<"fixed_threshold invert(0=offl1=on)"
		"adaptive_type(0=mean]1=gaussian) block_size offset image\n"
		"Example:"<<argv[0] <<"100 1 0 15 10 1.PNG"; 
		return -1;
	}
	// Command line
	double fixed_threshold = (double)atof(argv[1]);

	int threshold_type = atoi(argv[2]) ? cv::THRESH_BINARY : cv::THRESH_BINARY_INV;
	int adaptive_method = atoi(argv[3]) ? cv::ADAPTIVE_THRESH_MEAN_C : cv::ADAPTIVE_THRESH_GAUSSIAN_C;
	int block_size = atoi(argv[4]);
	double offset =(double)atof(argv[5]);
	cv::Mat Igray = cv::imread(argv[6], cv::IMREAD_GRAYSCALE);
	// Read in gray image
	//
	if( Igray.empty() ){ 
		cout << "Can not load " << argv[6] << endl; 
		return -1; 
	}
	// Declare the output images.
	//
	cv::Mat It,Iat;
	// Thresholds
	
	cv::threshold(
	Igray,
	It,
	fixed_threshold,
	255,
	threshold_type);
	cv::adaptiveThreshold(
	Igray,
	Iat ,
	255,
	adaptive_method,
	threshold_type,
	block_size,
	offset	);
	// Show the results.
	//
	cv::imshow("Raw",Igray);
	cv::imshow("Threshold",It);
	cv::imshow("Adaptive Threshold",Iat);

	cv::waitKey(0);
	return 0;
}

        运行效果如下:

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

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

相关文章

渗透测试中的前端调试(上)

一、前言 前端调试是安全测试的重要组成部分。它能够帮助我们掌握网页的运行原理&#xff0c;包括js脚本的逻辑、加解密的方法、网络请求的参数等。利用这些信息&#xff0c;我们就可以更准确地发现网站的漏洞&#xff0c;制定出有效的攻击策略。前端知识对于安全来说&#xff…

私域运营丨用户运营SOP,批量成交私域新老客户!

私域运营的重点内容除了社群外&#xff0c;还包括1对1的沟通成交。特别是针对价格高、决策成本高、需要定制化和深度服务、具有私密性的产品&#xff0c;非常适合进行1对1的成交。 通过建立标准化的用户运营SOP&#xff0c;可以更科学地管理私域客户&#xff0c;并根据客户所处…

AO天鹰优化算法|含源码(元启发式算法)|跑23个经典函数(含源码)

-------往期目录------ 1、灰狼优化算法 文章目录 天鹰优化器一、第一种搜索方法二、第二种搜素方法三、第三种搜素方法四、第四种搜索方法 代码实现 天鹰优化器 Aquila Optimizer&#xff08;AO&#xff09;&#xff0c;灵感来自Aquila在捕捉猎物过程中的自然界行为。因此&a…

华为云云耀云服务器L实例评测|云耀云服务器L实例部署HertzBeat实时监控系统

华为云云耀云服务器L实例评测&#xff5c;云耀云服务器L实例部署HertzBeat实时监控系统 一、云耀云服务器L实例介绍1.1 云耀云服务器L实例简介1.2 云耀云服务器L实例特点 二、HertzBeat介绍2.1 HertzBeat简介2.2 HertzBeat特点 三、本次实践介绍3.1 本次实践简介3.2 本次环境规…

Activiti7工作流 二【Activiti7入门、Activiti7进阶】

文章目录 六、Activiti7入门6.1 业务流程建模6.1.1 绘制流程图6.1.2 指定任务负责人6.1.3 生成png格式流程图 6.2 部署流程定义6.3 启动流程实例6.4 任务查询6.5 任务处理6.6 添加审批意见6.6 查看历史审批 七、Activiti7进阶7.1 流程定义相关7.1.1 流程定义查询7.1.2 流程资源…

基于Spring Boot的体育馆管理系统的设计与实现

目录 前言 一、技术栈 二、系统功能介绍 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 本基于Spring Boot的海滨体育馆管理系统设计目标是实现海滨体育馆的信息化管理&#xff0c;提高管理效率&#xff0c;使得海滨体育馆管理工作规范化、高效化。 本文重…

fonts什么文件夹可以删除吗?fonts文件夹删除了怎么恢复

在电脑上&#xff0c;fonts文件夹是存放字体文件的目录之一。尽管有时可能考虑删除该文件夹以节省硬盘空间或出于其他原因&#xff0c;但删除该文件夹可能会导致系统字体问题&#xff0c;影响用户的正常使用。因此&#xff0c;在删除之前需要考虑是否可以删除fonts文件夹&#…

golang优先级坑

看如下代码&#xff0c;我本以为a1, a2是相同的 package mainimport "fmt"func main() {b, c, d : 1, 0, 1a1 : b ^ c&(^d) // 1 ^a2 : c ^ b&(^d) // 0 ^fmt.Println(a1, a2) // 1 0 }但结果却是不同的&#xff0c;在golang中&的优先级^和&#xff5c;…

Edge 浏览器『版本回退』和『关闭更新』

前言 最近 Edge 浏览器又更新了&#xff0c;给整体浏览器页面布局进行大改动&#xff0c;之前苗条的标签页和收藏夹栏瞬间变得臃肿了&#xff0c;我实在无法忍受这种布局&#xff0c;所以我索性直接进行版本回退和设置永久关闭更新&#xff0c;详细步骤请看下文 Edge 浏览器版…

【新版】系统架构设计师 - 案例分析 - 架构设计<架构风格和质量属性>

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 案例分析 - 架构设计&#xff1c;架构风格和质量属性&#xff1e;例题1例题2例题3例题4例题5例题6 架构 - 案例分析 - 架构设计&#xff1c;架构风格和质量属性&#xff1e; 例题1 某软件公司为…

大数据开发工程师面试题

一、选择题 1、哪个程序负责HDFS数据存储&#xff1f; Datanode 2、HDFS中的block默认保存几份&#xff1f; 默认3份 3、哪个程序通常与NameNode在一个节点启动&#xff1f; Jobtracker 4、HDFS默认Block Size是多少&#xff1f; 64MB 5、什么通常是集群的最主要瓶颈 …

typedef与define定义类型

#define _CRT_SECURE_NO_WARNINGS #define DataType2 int* #include<iostream> typedef int* DataType1; int main() {DataType1 a, b;DataType2 c, d;printf("%d %d %d %d", sizeof(a), sizeof(b), sizeof(c), sizeof(d));return 0; } 输出结果如何&#xf…

MySQL集群高可用架构之MMM

一、MMM概述 1.1 MMM 简介 MMM&#xff08;Master-Master replication manager for MvSQL&#xff0c;MySQL主主复制管理器&#xff09;是一套支持双主故障切换和双主日常管理的脚本程序。 MMM 使用 Perl 语言开发&#xff0c;主要用来监控和管理 MySQL Master-Master &#…

免费玩云上大数据--海汼部落实验室

玩大数据遇到的问题 大家好&#xff0c;这次分享一个免费的大数据部署工具&#xff0c;并非是给人家打广告&#xff0c;试过了真的爽。 学习大数据的人都知道&#xff0c;如果用VMware模拟Linux搭建大数据集群的话我们需要很高的内存和硬盘内存&#xff0c;随随便便跑一下mapre…

机器学习笔记:adaBoost

1 介绍 AdaBoost&#xff08;Adaptive Boosting&#xff09;是一种集成学习方法&#xff0c;它的目标是将多个弱分类器组合成一个强分类器 通过反复修改训练数据的权重&#xff0c;使得之前分类错误的样本在后续的分类器中得到更多的关注每一轮中&#xff0c;都会增加一个新的…

eCognition易康操作教程(一):如何利用eCognition易康软件进行影像分割之棋盘分割、四叉树分割、光谱差异分割

一、新建工程 使用eCognition新建工程ImageSegmentation&#xff0c;加载影像数据&#xff0c;并编辑图层名称&#xff0c;将Layer 1、Layer 2、Layer 3、Layer 4的 Layer Alias 分别改为 Blue、Green、Red、如图1-1&#xff0c;图1-2所示&#xff1a; 图 1-1 图 1-2 设置加载…

十三、直流电机驱动

十三、直流电机驱动 介绍直流电机调数 介绍 PWM PWM是脉冲宽度调制&#xff0c;在具有惯性的系统中&#xff0c;可以通过对一系列脉冲的宽度进行调制&#xff0c;等效的获取需要的模拟参量&#xff0c;常应用于电机控速、开关电源等领域。通过改变一个周期信号的占空比&#xf…

为什么做测试既要懂开发又要懂产品?这3点看完,你就懂了!

本篇讨论的是什么呢&#xff1f;何谓一个真正的测试&#xff1f; 纯粹是个人的理解&#xff0c;仅供参考。 ● 论一个真正的软件测试工程师 ● 自动化在项目中的应用 ● 性能专项在项目中的应用 半个产品、半个开发 有人觉得这个标题有点讽刺&#xff0c;真正的测试&…

关于RestTemplate postForObject方法请求 服务端Controller接受不到值的问题解决

本文适合有SSM框架基础和springboot开发基础的同学查阅 这里postForObject 方法有三个参数&#xff0c;没有使用四个参数的。 restTemplate.postForObject(String url, Object request, Class<T> responseType); 1.String url > 顾名思义 这个参数是请求的url路径。…

Spring面试题10:Spring的XMLBeanFactory怎么使用

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:Spring的XMLBeanFactory怎么使用 XmlBeanFactory是Spring框架中的一个实现类,它是BeanFactory接口的一个具体实现。XmlBeanFactory的主要作用是通…