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

目录

一、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 window1cv::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 linedouble 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;// Thresholdscv::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.mzph.cn/news/85545.shtml

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

相关文章

Python与数据分析--Matplotlib-1

目录 1.Matplotlib库函数导入 2.简单尝试绘图 3.绘制多条折线图 4.绘制多种颜色风格曲线 5.图片内容文本操作实例 6.图例设置实例 7.坐标轴设置实例 1.Matplotlib库函数导入 #导入matplotlib库 import matplotlib as mpl import matplotlib.pyplot as plt #平常一般用第…

Java实现Modbus Tcp协议读写模拟工具数据

标题 前言一、读写模拟工具中数据(1) 定义Controller层(2) 定义Service层实现 二、调试(1) 读数据(2) 向寄存器写单个数据(3) 向寄存器写多个数据 前言 参考文章&#xff1a;https://www.cnblogs.com/ioufev/p/10831289.html 该文中谈及常见的几种读取设备数据实现&#xff0…

【数据结构】二叉树之堆的实现

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;数据结构 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、二叉树的顺序结构 &#x1f4d2;1.1顺序存储 &#x1f4d2;1.2堆的性质…

Linux下的基本指令

目录 01. ls 指令 02. pwd命令 03. cd 指令 04. touch指令 05.mkdir指令&#xff08;重要&#xff09;&#xff1a; 06.rmdir指令 && rm 指令&#xff08;重要&#xff09;&#xff1a; 07.man指令&#xff08;重要&#xff09;&#xff1a; 08mv指令&#xff…

Eureka服务器注册

一。Eureka服务器注册 1.pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://mav…

安卓系统--翻译手机rom语言 添加多国语言 编译apk 反编译ODEX 工具步骤解析

很多小品牌机型不具备多语言设置。国内大都是中文。要想换为其他语言除非固件支持。例如国际版固件等等。大厂基本都有中文或者英文或者其他语言配置。而小品牌机型只能通过修改rom来达到多语言调用. 工具步骤演示 今天给友友介绍一款工具&#xff0c;可以用来翻译手机rom语言…

手摸手图解 CodeWhisperer 的安装使用

CodeWhisperer 是亚⻢逊出品的一款基于机器学习的通用代码生成器&#xff0c;可实时提供代码建议。 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术&#xff0c;观点…

20230919后台面经整理

1.你认为什么是操作系统&#xff0c;操作系统有哪些功能 os是&#xff1a;管理资源、向用户提供服务、硬件机器的扩展 1.进程线程管理&#xff1a;状态、控制、通信等 2.存储管理&#xff1a;分配回收、地址转换 3.文件管理&#xff1a;目录、操作、磁盘、存取 4.设备管理&…

24. 图论 - 图的表示种类

Hi&#xff0c;你好。我是茶桁。 之前的一节课中&#xff0c;我们了解了图的来由和构成&#xff0c;简单的理解了一下图的一些相关概念。那么这节课&#xff0c;我们要了解一下图的表示&#xff0c;种类。相应的&#xff0c;我们中间需要穿插一些新的知识点用于更好的去理解图…

C#,数值计算——Multinormaldev的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public class Multinormaldev : Ran { public Cholesky chol { get; set; } null; private int mm { get; set; } private double[] mean { get; set; } private double[,] xvar {…

shardingjdbc分库分表数据均衡性讨论

问题引入 最近一个业务系统中&#xff0c;因为数据量很大&#xff0c;经过技术选型&#xff0c;综合权衡选择了sharding-Jdbc&#xff0c;本文主要讨论的是分库分表的表达式 我们有一个批次总表A&#xff0c;还有一个明细表B&#xff0c;我们需要对明细表B进行水平拆分&#…

InputAction的使用

感觉Unity中InputAction的使用&#xff0c;步步都是坑。 需求点介绍 当用户长按0.5s 键盘X或者VR left controller primaryButton (即X键)时&#xff0c;显示下一个图片。 步骤总览 创建InputAction资产将该InputAction资产绑定到某个GameObject上在对应的script中&#xf…

计算机视觉与深度学习-经典网络解析-VGG-[北邮鲁鹏]

目录标题 VGG参考VGG网络贡献使用尺寸更小的$3 \times 3$卷积串联来获得更大的感受野放弃使用$11 \times 11$和$5 \times 5$这样的大尺寸卷积核深度更深、非线性更强&#xff0c;网络的参数也更少&#xff1b;去掉了AlexNet中的局部响应归一化层(LRN)层。 网络结构主要改进输入…

21 mysql ref 查询

前言 这里主要是 探究一下 explain $sql 中各个 type 诸如 const, ref, range, index, all 的查询的影响, 以及一个初步的效率的判断 这里会调试源码来看一下 各个类型的查询 需要 lookUp 的记录 以及 相关的差异 此系列文章建议从 mysql const 查询 开始看 测试表结构…

基于abaqus的非等速生长Voronoi晶体模型生成插件

1. 非等速生长晶体模型简介 对于标准Voronoi而言&#xff0c;每个晶粒的生长速率是相同的&#xff0c;任意两个晶粒的交界线为其形核点连线的垂直平分线&#xff0c;交界线为一条直线&#xff0c;如图1.1所示。 图1.1 标准Voronoi晶粒交界线 而对于非等速生长Voronoi晶体而言…

肖sir__项目环境之全流程__005

一、测试流程&#xff08;h模型&#xff09; 1、需求文档&#xff08;产品&#xff09; 需求文档&#xff08;软件需求规格说明书srs&#xff09; &#xff08;1&#xff09;如何分析需求 a、显示需求&#xff08;主流程、功能&#xff0c;业务&#xff09; b、隐性需求&#x…

js惰性函数

看下面这份ts代码 实现的效果也很简单,就是将一份文本,复制到剪切板上,未了兼容更多的浏览器(没错说的就是你>ie !),做了一个兼容性判断, 当浏览器支持navigator.clipboard这个api时,就直接调用这个api将文本复制到剪切板中, 如果不支持这个api的话,就执行else里面的代码,这…

解决qml编译时出现错误ninja: build stopped: subcommand failed.

qml编译时出现错误ninja: build stopped: subcommand failed. 如下图&#xff1a; 解决这个编译错误其实很简单&#xff0c;我把Window写错了&#xff0c;写成了window, 如果有类似的报错&#xff0c;可以检查一下qml代码是否有问题。当然在Qt Creator里也没有错误提示&#x…

MySQL 远程连接1130问题

通过后台进入mysql 1,切换到mysql库 2.查询user表信息 3.更新你想远程登录的用户的host信息,我这里想用root进行远程登录,所以修改如下 4.刷新权限 5.大功告成 快来和博主打成一片吧^_^

【Vue】修饰符、表单提交方式、自定义组件的关键步骤

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Vue快速入门》。&#x1f3af;&#x1f3af; &…