OpenCv阈值操作(超详细)

Posted 散散汪

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCv阈值操作(超详细)相关的知识,希望对你有一定的参考价值。

一、阈值化操作

1、阈值滑动条:

createTrackbar使用方法及步骤

第一个参数:conststring& trackbarname,表示轨迹条的名字
第二个参数:conststring& winname,表示轨迹条依托窗口的名称
Threshold_Demo:是回调函数,实时返回。

2、阈值函数:

threshold(gray_dst, dst2, threshold_value, threshold_max, THRESH_BINARY);
gray_dst:原图像
threshold_value:阈值
threshold_max:最大值,一般为255
type:
cv2.THRESH_BINARY:二值化,超过阈值的像素设置为max,不超过的设置为0
cv2.THRESH_BINARY_INV:反二值化,不超过阈值的设置为max,超过的设置为0
cv2.THRESH_TRUNC:截断,超过阈值的设置为threshold
cv2.THRESH_TOZERO:低于阈值的设置为0
cv2.THRESH_TOZERO_INV:低于阈值的设置为max
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;

Mat src, dst, dst2, gray_dst;
int threshold_value = 127;
int threshold_max = 255;
const char* output = "binary image";
void Threshold_Demo(int, void*);
int main()
{
	src = imread("D:/PT/circle_stone.jpg");
	if (!src.data) {
		printf("could not load the image...\\n");
		return  -1;
	}
	double scale = 0.5;
	Size dsize = Size(src.cols * scale, src.rows * scale);
	resize(src, dst, dsize);

	//为图像创建边框
	//copyMakeBorder(dst, dst2, 20, 20, 20, 20, cv::BORDER_CONSTANT, Scalar(116, 73, 16));
	//阈值化操作
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	namedWindow(output, CV_WINDOW_AUTOSIZE);
	imshow("input", dst);
	createTrackbar("阈值滑条:", output, &threshold_value, threshold_max, Threshold_Demo);
	//imwrite("D:/PT/shan/shan12345.jpg",dst2);
	Threshold_Demo(0, 0);
	waitKey(0);
	return 0;
}
void Threshold_Demo(int, void*) {
	cvtColor(dst, gray_dst, CV_BGR2GRAY);
	threshold(gray_dst, dst2, threshold_value, threshold_max, THRESH_BINARY);
	imshow(output, dst2);

}



注:这里可以暂停思考一下,为什么阈值拉低,黑色逐渐减少,白色逐渐增多。
cv2.THRESH_BINARY_INV:反二值化:

3、OTSU算法(大津法)

什么是大津法?
大津法是一种图像灰度自适应的阈值分割算法,又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景图像的类间方差最大

它被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响,因此在数字图像处理上得到了广泛的应用。它是按图像的灰度特性,将图像分成背景和前景两部分。因方差是灰度分布均匀性的一种度量,背景和前景之间的类间方差越大,说明构成图像的两部分的差别越大,当部分前景错分为背景或部分背景错分为前景都会导致两部分差别变小。因此,使类间方差最大的分割意味着错分概率最小。

应用:是求图像全局阈值的最佳方法,应用不言而喻,适用于大部分需要求图像全局阈值的场合。

优点:计算简单快速,不受图像亮度和对比度的影响。

缺点:对图像噪声敏感;只能针对单一目标分割;当目标和背景大小比例悬殊、类间方差函数可能呈现双峰或者多峰,这个时候效果不好。



代码链接:C++实现Otsu(大津法)
OpenCV学堂公众号链接:二值化算法OTSU源码解析

4、自适应阈值二值化

为什么要提出自适应呢?
对于色彩均匀的图像,一个阈值就可以完成,但是色彩不均匀,图像光照变暗了,单阈值的二值化效果就会大大折扣。

自适应阈值可以使用变换的阈值,通过计算每个像素点临近区域的甲醛平均值获得阈值,然后处理。这个方法可以更好地处理明暗差异较低的图像。

OpenCV提供的API:

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

src:源图像,8位单通道图像。

adaptiveMethod:在一个邻域内计算阈值所采用的算法,分别为:

ADAPTIVE_THRESH_MEAN_C (邻域所有像素点的权重值是一致的)-double C
ADAPTIVE_THRESH_GAUSSIAN_C (与邻域各个像素点到中心的距离有关,通过高斯方程得到各个点的权重值)-double c

thresholdType:

THRESH_BINARY
THRESH_BINARY_INV

blockSize:adaptiveThreshold的计算单位是像素的邻域块,这是局部邻域大小,3、5、7…

double C:偏移值调整量.

以上是关于OpenCv阈值操作(超详细)的主要内容,如果未能解决你的问题,请参考以下文章

超详细OpenCV之python操作

OpenCV 基本阈值操作

OpenCV 基本阈值操作

图像的OTSU阈值化双阈值化半阈值化的原理及OpenCV代码实现

OpenCV之基本阈值操作

OpenCV之基本阈值操作