OpenCv入门(三)——阈值化处理

2023-05-16

目录

0x01 OTSU

0X02 固定阈值化

0x03 自适应阈值化

0x04 双阈值化

0x05 半阈值化

在图像处理中,处理灰度图像的计算量要小于处理彩色图像,而二值化图像(只含灰度值0或1)的计算复杂度更优于以上两者,因此二值化操作在数字图像处理中有着不可或缺的实用价值。一幅图像包括目标、背景以及噪声,想要直接提取出目标物体,通常是采用灰度变换阈值化操作。

图像的阈值化操作就是利用图像像素点分布的规律,设定阈值进行像素点分割,进而得到图像的二值化图像。

图像阈值化操作:

  • OTSU

  • 固定阈值

  • 自适应阈值

  • 双阈值

  • 半阈值化

0x01 OTSU

算法步骤:

  • 统计灰度级中每个像素在整幅图像中的个数。

  • 计算每个像素在整幅图像的概率分布。

  • 对灰度级进行遍历搜索,计算当前灰度值下前景背景类间概率。

  • 通过目标函数计算出类内与类间方差下对应的阈值。

int OTSU(const cv::Mat& image)
{
	int nCols = image.cols;
	int nRows = image.rows;
	int threshold = 0;

	//初始化统计参数
	int nSumPix[256];
	float nProDis[256];
	for (int i = 0; i < 256; i++)
	{
		nSumPix[i] = 0;
		nProDis[i] = 0;
	}

	//统计灰度级中每个像素在整幅图像中的个数
	for (int i = 0; i < nCols; i++)
	{
		for (int j = 0; j < nRows; j++)
		{
			nSumPix[(int)image.at<uchar>(i, j)]++;
		}
	}

	//计算每个灰度级占图像中的概率分布
	for (int i = 0; i < 256; i++)
	{
		nProDis[i] = (float)nSumPix[i] / (nCols * nRows);
	}

	//遍历灰度级[0,255],计算出最大类间方差下的阈值
	float w0, w1, u0_temp, u1_temp, u0, u1, delta_temp;
	double delta_max = 0.0;
	for (int i = 0; i < 256; i++)
	{
		//初始化相关系数
		w0 = w1 = u0_temp = u1_temp = u0 = u1 = delta_temp = 0;
		for (int j = 0; j < 256; j++)
		{
			//背景部分
			if (j <= i)
			{
				//当前i为分割阈值,第一类总的概率
				w0 += nProDis[j];
				u0_temp += j * nProDis[j];
			}
			//前景部分
			else
			{
				w1 += nProDis[j];
				u1_temp += j * nProDis[j];
			}
		}

		//分别计算各类的平均速度
		u0 = u0_temp / w0;
		u1 = u1_temp / w1;
		delta_temp = (float)(w0 * w1 * pow((u0 - u1), 2));
		//依次找到最大类间方差下的阈值
		if (delta_temp > delta_max)
		{
			delta_max = delta_temp;
			threshold = i;
		}
	}

	return threshold;
}

调用:

int ostuThreshold = OTSU(image_reduced);

cv::Mat otsuResultImage(304,304,CV_8UC1);
	
cv::threshold(image_reduced, otsuResultImage, ostuThreshold, 255, cv::THRESH_BINARY);

cv::imshow("OTSU", otsuResultImage);

效果:

0X02 固定阈值化

Opencv提供了阈值化函数threshold,对应5种阈值化类型参数:

cv::threshold(src,			 		//源图像数组
			  dst,					//输出图像数组
			  thresh,				//阈值
			  maxval, 				//阈值设置
			 type);					//阈值化处理的类型设置

Threshold函数应用在单通道图像中固定阈值化处理,通常是为了得到二值化灰度图像(只包含0或1灰度值)或为了去除噪声。参数类型:

(1)THRESH_BINARY 二进制阈值化

对8位灰度图应用该阈值进行操作时,预先设定好特定的阈值量thresh。阈值化操作只需要将大于thresh的灰度值设定为255,将低于thresh的灰度值设定为0:

 

(2)THRESH_BINARY_INV 反二进制阈值化

对8位灰度图应用该阈值进行操作时,预先设定好特定的阈值量thresh,阈值化操作只需要将大于thresh的灰度值设定位0,将不大于thresh的灰度值设定位255:

 

 (3)THRESH_TRUNC截断阈值化

对8位灰度图应用该阈值进行操作时,预先设定好特定的阈值量thresh,阈值化操作只需要将大于thresh的灰度值设定为threshold,将低于thresh的灰度值设定为不变。

(4)THRESH_TOZERO阈值化为0

对8位灰度图应用该阈值进行操作时,预先设定好特定的阈值量thresh,阈值化操作只需要将大于thresh的灰度值设定为不变,将低于thresh的灰度值设定为0。

(5)THRESH_TOZERO_INV反阈值化为0

对8位灰度图应用该阈值进行操作时,预先设定后特定的阈值量是thresh,阈值化操作只需要将大于thresh的灰度值设定为0,将低于thresh的灰度值设定为不变。

0x03 自适应阈值化

在图像阈值化操作中,我们更官辛的是从二值化图像中分离目标区域和背景区域,仅仅提供给定一个固定的阈值是难以达到理想的分割效果的。

在实际应用中,目标及背景区域通常相互依存在图像块中,我们可以通过图像像素领域块的分特征来自适应来确定区域的二值化阈值。对于图像块中亮度变化明显的区域,自适应阈值通常会设置为较大或较小,进而保证图像中各个像素的阈值都会随着周围领域块的变化而变化。

void adaptiveThreshold(InputArray src,		//源图像数组
                       OutputArray dst,		//输出图像数组
                       double maxValue,		//预设满足条件的最大值
                       int adaptiveMethod,	//算法选择
                       int thresholdType,	//阈值类型
                       int blockSize,		//领域块的大小
                       double C)		 	//从均值或加权均值提取的常数,可以是负数

使用可以如下:

//初始化自适应阈值参数
int blockSize = 5;
int constValue = 20;
const int maxVal = 255;
cv::Mat image_adaptive(304, 304, CV_8UC1);
cv::adaptiveThreshold(image_reduced, image_adaptive, maxVal,cv::ADAPTIVE_THRESH_GAUSSIAN_C,cv::THRESH_BINARY,blockSize,constValue);

0x04 双阈值化

对于图像中国有明显的双分界线特征,需要考虑使用双阈值法来进行二值化操作。

对8位灰度图应用该阈值化方法进行操作时,预先设定好特定的阈值量thresh1、thresh2,且thresh1<thresh2,阈值化操作只需要将大于thresh1且小于thresh2的灰度值设定位maxval,将其余情况设定为0。

双阈值化中的两个阈值可以根据实际场景需求进行设置。其中maxval可以为一个固定值,通常情况下8位无符号图像设置为最大灰度值255,双阈值化操作:

 其实说白了就是给定一个阈值范围,在这个范围内确定黑白:

cv::Mat DualThreshold(const cv::Mat& image,int maxval,int low_threshold,int high_threshold)
{
	cv::Mat dstTempImage1, dstTempImage2, dstImage;
	
	//小阈值对源灰度图像进行阈值化操作
	cv::threshold(image,dstTempImage1,low_threshold,maxval,cv::THRESH_BINARY);

	//大阈值对源灰度图像进行阈值化操作
	cv::threshold(image,dstTempImage2,high_threshold,maxval,cv::THRESH_BINARY_INV);

	//矩阵与运算可得二值化结果
	cv::bitwise_and(dstTempImage1,dstTempImage2,dstImage);

	return dstImage;
}

0x05 半阈值化

对于图像中有明显得目标与背景差异特征,如手写体字符分割与识别,我们可以考虑用半阈值法进行阈值化操作。

原理:预先设定好阈值量thresh,版阈值化操作只需要将大于thresh的灰度值设定为不变,将其余情况设定为0。

为什么要使用半阈值化?

图像半阈值化操作应用于字符分割领域,对字符区域进行分割,一般阈值化方法会倒是字符间存在粘连或漏空,给字符特征提取带来诸多难题,而图像半阈值化操作有利于保存字符间的边界信息,可有效实现粘连字符的分割。

实现:

cv::Mat HalfThresh(const cv::Mat& image,int maxval,int thresholdval)
{
	cv::Mat dstTempImage, dstImage;
	//阈值对源灰度图像进行阈值化操作
	cv::threshold(image,dstTempImage,thresholdval,255,cv::THRESH_BINARY);
	//矩阵与运算
	cv::bitwise_and(image,dstTempImage,dstImage);
	
	return dstImage;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCv入门(三)——阈值化处理 的相关文章

  • 如何将输出视频保存到 OpenCV 中的文件中

    我想将输出视频保存到文件中而不是显示它并尝试使用 cvcaptureimage 但仍然无法获得结果 include
  • OpenCV 2.3 与 VS 2008 - 鼠标事件

    强制性 我是新手 有一份涉及编程的工作 并且我一边工作一边自学 不用说 作为一名老师 我经常犯彻底的错误 我现在所处的位置 我创建了 Graph 类 它 令人惊讶的是 制作了图表 但现在我想通过单击鼠标来修改图形 但我似乎无法让鼠标处理程序
  • OpenCV 2.4.3 中的阴影去除

    我正在使用 OpenCV 2 4 3 最新版本 使用内置的视频流检测前景GMG http docs opencv org modules gpu doc video html highlight gmg gpu 3a 3aGMG GPU算法
  • 如何使用 Python 裁剪图像中的矩形

    谁能给我关于如何裁剪两个矩形框并保存它的建议 我已经尝试过这段代码 但效果不佳 import cv2 import numpy as np Run the code with the image name keep pressing spa
  • 2d 图像点和 3d 网格之间的交点

    Given 网格 源相机 我有内在和外在参数 图像坐标 2d Output 3D 点 是从相机中心发出的光线穿过图像平面上的 2d 点与网格的交点 我试图找到网格上的 3d 点 This is the process From Multip
  • 如何使用 opencv python 计算乐高积木上的孔数?

    我正在开发我的 python 项目 我需要计算每个乐高积木组件中有多少个孔 我将从输入 json 文件中获取有关需要计算哪个程序集的信息 如下所示 img 001 red 0 blue 2 white 1 grey 1 yellow 1 r
  • cv2.drawContours() - 取消填充字符内的圆圈(Python,OpenCV)

    根据 Silencer的建议 我使用了他发布的代码here https stackoverflow com questions 48244328 copy shape to blank canvas opencv python 482465
  • 如何将 Mat (opencv) 转换为 INDArray (DL4J)?

    我希望任何人都可以帮助我解决这个任务 我正在处理一些图像分类并尝试将 OpenCv 3 2 0 和 DL4J 结合起来 我知道DL4J也包含Opencv 但我认为它没什么用 谁能帮我 如何转换成 INDArray 我尝试阅读一些问题here
  • OpenCV 2.2 和多 CPU - opencv_haartraining.exe 是多线程的吗?

    我在 VS 2010 上构建了 OpenCV 2 2 启用了 TBB 3 支持 我确保所有项目都有正确的 tbb lib 目录 并将 tbb lib 列为依赖项 通过隐藏 tbb dll 进行验证 果然 haartraining exe 抱
  • 图像梯度角计算

    我实际上是按照论文的说明进行操作的 输入应该是二进制 边缘 图像 输出应该是一个新图像 并根据论文中的说明进行了修改 我对指令的理解是 获取边缘图像的梯度图像并对其进行修改 并使用修改后的梯度创建一个新图像 因此 在 MATLAB Open
  • OpenCv读/写视频色差

    我试图简单地使用 openCV 打开视频 处理帧并将处理后的帧写入新的视频文件 我的问题是 即使我根本不处理帧 只是打开视频 使用 VideoCapture 读取帧并使用 VideoWriter 将它们写入新文件 输出文件看起来比输入更 绿
  • 如何检测图像是否像素化

    之前有人在 SO 上提出过这样的问题 在Python中检测像素化图像 https stackoverflow com questions 12942365 detecting a pixelated image in python还有关于q
  • 使用python从gst管道抓取帧到opencv

    我在用着OpenCV http opencv org 和GStreamer0 10 我使用此管道通过自定义套接字通过 UDP 接收 MPEG ts 数据包sockfd由 python 提供并显示它xvimagesink 而且效果很好 以下命
  • 在骨架图像中查找线 OpenCV python

    我有以下图片 我想找到一些线来进行一些计算 平均长度等 我尝试使用HoughLinesP 但它找不到线 我能怎么做 这是我的代码 sk skeleton mask rows cols sk shape imgOut np zeros row
  • 让网络摄像头在 OpenCV 中工作

    我正在尝试让我的网络摄像头在 Windows 7 64 位中的 OpenCV 版本 2 2 中捕获视频 但是 我遇到了一些困难 OpenCV 附带的示例二进制文件都无法检测到我的网络摄像头 最近我发现这篇文章表明答案在于重新编译一个文件 o
  • opencv中如何去除二值图像噪声?

    将图像转换为二值图像 黑白 后如果有任何噪音怎么办 我消除了那些不需要的噪音 您可以看到下图的黑色区域内有一些白噪声 我该如何去除噪声 使用opencv http img857 imageshack us img857 999 blackn
  • 提取二值图像中的最中心区域

    我正在处理二进制图像 之前使用此代码来查找二进制图像中的最大区域 Use the hue value to convert to binary thresh 20 thresh thresh img cv2 threshold h thre
  • 在Python中从整个图像中检测表格部分

    我有一张尺寸为 3500x5000 的图像 现在我只想检测整个图像中的表格部分 如果不能直接进行 OCR 处理 则对其进行裁剪和旋转 经过所有搜索后 我想到了使用裁剪图像中的每个单元格的想法https medium com coinmonk
  • 旋转矩阵openCV

    我想知道如何找到框架中一组特征的旋转矩阵 我会更具体 我有 2 个具有 20 个特征的帧 假设第 1 帧和第 2 帧 我可以估计两个帧中特征的位置 例如 假设位置 x y 处的某个第 1 帧特征 并且我确切地知道它在哪里 所以假设为 x y
  • Opencv 对象检测:ORB GPU 检测器和 SURF GPU 描述符提取器

    我只是做了一个小实验来尝试不同的检测器 描述符组合 我的代码使用 ORB GPU 检测器来检测特征 并使用 SURF GPU 描述符来计算描述符 我使用 BruteForceMatcher GPU 来匹配描述符 并使用 knnMatch 方

随机推荐

  • 1--FreeRTOS操作系统介绍

    1 FreeRTOS 操作系统介绍 第3章 FreeRTOS 读作 34 free arr toss 34 是一个嵌入式系统使用的开源实时操作系统 FreeRTOS 被设计为 小巧 xff0c 简单 xff0c 和易用 xff0c 能支持许
  • 2--嵌入式操作系统FreeRTOS的原理与实现

    2 嵌入式操作系统FreeRTOS的原理与实现 摘自 xff1a http xilinx eetrend com article 7828 摘要 xff1a FreeRTOS 是一个源码公开的免费的嵌入式实时操作系统 xff0c 通过研究其
  • 自动驾驶技术-环境感知篇:V2X技术的介绍

    V2X技术概述 在前面的几篇文章分别介绍了自动驾驶在环境感知领域的相关技术点 xff0c 主要介绍了如何通过雷达配合视觉技术实现车辆自身的智能 其实在环境感知方面 xff0c 除了利用车辆自身的智能 xff0c 还可以借助外部环境实现信息的
  • 深度学习分布式策略优化、显存优化、通信优化、编译优化综述

    综述 因为我个人最近在从事可能是AI领域对性能挑战最大的方向 xff0c 自动驾驶领域 xff0c 所以对整个深度学习训练的优化尤为关注 xff0c 最近一直在学习相关内容 xff0c 谨以此篇文章做一个总结 我一直很看好深度学习训练优化这
  • 量子计算机的优势和建设挑战

    1 为什么需要量子计算机 目前大家日常使用的计算机都是经典计算机 xff0c 经典计算机计算性能的发展遵循摩尔定律 xff0c 在价格不变时 xff0c 集成电路上可容纳的晶体管数目 xff0c 约每隔18个月便会增加一倍 性能也将提升一倍
  • 浅谈ChatGPT对生产关系及工具的颠覆影响

    xff08 先歪个楼 xff0c 配图是三体乱纪元 xff0c 证明三体问题无解 xff0c 而ChatGPT证明了AIGC问题是可解的 xff09 最近ChatGPT越来越热 xff0c 仿佛看到了资本市场又一次的爆发 最近周末也会跟几个
  • 蓟门边studio-码农创业路的起点

    蓟门边工作室 xff0c 开张了 先简单介绍下lz的情况吧 xff01 lz是北邮在读硕士 xff0c 码农一枚 断断续续写代码也有一两个年头了 xff0c 但是感觉总是在外面飘着 xff0c 没写过什么大的项目 xff0c 也没真正依靠技
  • 【机器学习算法-python实现】逻辑回归的实现(LogicalRegression)

    转载请注明出处 xff1a http blog csdn net buptgshengod 1 背景知识 在刚刚结束的天猫大数据s1比赛中 xff0c 逻辑回归是大家都普遍使用且效果不错的一种算法 xff08 1 xff09 回归 先来说说
  • 计算机视觉~~~

    这两年 xff0c 计算机视觉似乎火了起来计算机视觉的黄金时代真的到来了吗 xff1f 生物医学 机械自动化 土木建筑等好多专业的学生都开始研究其在各自领域的应用 xff0c 一个视觉交流群里三分之一以上都不是计算机相关专业的 当然 xff
  • 新闻个性化推荐系统(python)-(附源码 数据集)

    1 背景 最近参加了一个评测 xff0c 是关于新闻个性化推荐 说白了就是给你一个人的浏览记录 xff0c 预测他下一次的浏览记录 花了一周时间写了一个集成系统 xff0c 可以一键推荐新闻 xff0c 但是准确率比较不理想 xff0c 所
  • 明天是我的生日,写给24岁的自己

    哎 xff0c 本来想把今晚留给蛋疼的latex 我的导师让我写一篇论文 xff0c 我正在研究怎么用latex 但是想了想 xff0c 明天就过生日了 xff0c 最后一晚还是写点东西 xff0c 静静地思考下 本来想写点东西发到朋友圈或
  • 【码农本色】用数据解读我的2014

    转眼2014就过去了 xff0c 不禁感叹又老了一岁的同时 xff0c 却发现已经快研究生毕业了 xff0c 趁着这个活动简单总结下2014 1 实习篇 2014年一月份拿到了人生第一个实习offer xff0c 在sony这样的大公司做a
  • 如何用PYTHON代码写出音乐

    如何用PYTHON代码写出音乐 什么是MIDI 博主本人虽然五音不全 xff0c 而且唱歌还很难听 xff0c 但是还是非常喜欢听歌的 我一直在做这样的尝试 xff0c 就是通过人工智能算法实现机器自动的作词和编曲 xff08 在这里预告下
  • 普通程序员如何入门AI

    毫无疑问 xff0c 人工智能是目前整个互联网领域最火的行业 xff0c 随着AlphaGo战胜世界围棋冠军 xff0c 以及各种无人驾驶 智能家居项目的布道 xff0c 人们已经意识到了AI就是下一个风口 当然 xff0c 程序员是我见过
  • 深度学习RNN实现股票预测实战(附数据、代码)

    背景知识 最近再看一些量化交易相关的材料 xff0c 偶然在网上看到了一个关于用 RNN实现股票预测的文章 xff0c 出于好奇心把文章中介绍的代码在本地跑了一遍 xff0c 发现可以 work 于是就花了两个晚上的时间学习了下代码 xff
  • 图像拐点检测-原理以及代码实现

    今天带来的内容只用两个字形容 干货 xff01 xff01 首先我们科普下图像识别的常识 xff0c 图片在电脑看来 xff0c 其实就是一个矩阵 xff0c 每个矩阵中的一个值都对应图片的一个像素点 xff08 下图摘自 机器学习实践应用
  • c#如何实现在两个窗体(Form)间传输数据或变量

    在父窗体中显示子窗体时 xff0c 加上子窗体 Owner 61 this 在子窗体中定义一个父窗体对象 xff0c 在Load函数里面让父窗体对象 61 xff08 父窗体类型 xff09 this Owner 然后用这个父窗体对象就可以
  • docker容器webui界面之portainer

    docker通常下都是命令行管理 xff0c 不太方便 xff0c web管理能直观一点 xff0c 如果是公司有运维组 xff0c ssh账号也不用给到开发这边 单机安装命令 docker run d p 19000 9000 name
  • Windows 10安装ubuntu18.04双系统(bios和boot manager)

    1 按照网上教程制作系统盘 xff1b 2 在windows下创建空白区 xff0c 为ubuntu分配空间 xff1b 3 用做好的系统盘安装系统 由于各个厂商计算机的bios和boot manager启动键不同 xff0c 自行百度 本
  • OpenCv入门(三)——阈值化处理

    目录 0x01 OTSU 0X02 固定阈值化 0x03 自适应阈值化 0x04 双阈值化 0x05 半阈值化 在图像处理中 xff0c 处理灰度图像的计算量要小于处理彩色图像 xff0c 而二值化图像 xff08 只含灰度值0或1 xff