1. 阈值设置
- 输入图像:灰度图,单通道,8 或 32位浮点数类型的深度。
- 输出图像
- 用来对像素值进行分类的阈值
- 当像素值高于(有时是小于)阈值时应该被赋予的新的像素值
- 阈值类型
double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type);
阈值类型
• cv2.THRESH_BINARY
• cv2.THRESH_BINARY_INV
• cv2.THRESH_TRUNC
• cv2.THRESH_TOZERO
• cv2.THRESH_TOZERO_INV
2. 最大类间方差 OTSU
适用范围:双峰图像
算法假设图像像素能够根据阈值,被分成背景[background]和目标[objects]两部分。然后,计算该最佳阈值来区分这两类像素,使得两类像素区分度最大。OTSU阈值可以不设置或随意设置,函数会自动计算最合适的阈值。
计算过程:
设图像Img长宽尺寸为M*N, T为二值化的阈值;
N0为灰度小于T的像素的个数,N0的平均灰度为μ0。
N1 为灰度大于T的像素的个数,N1的平均灰度为μ1。
ω0=N0/ M×N (1) //落在N0的概率
ω1=N1/ M×N (2) //落在N1的概率
N0+N1=M×N (3)
ω0+ω1=1 (4)
μ=ω0μ0+ω1μ1 (5) //平均灰度乘以概率 再相加
g=ω0(μ0-μ)2+ω1(μ1-μ)2 (6) //类间方差
将式(5)代入式(6),得到等价公式: g=ω0ω1(μ0-μ1)^2 (7)
参考:https://www.cnblogs.com/jyxbk/p/9638541.html
3. 自适应阈值
前面的部分我们使用是全局阈值,整幅图像采用同一个数作为阈值。这种方法并不适应与所有情况,尤其是当同一幅图像上的不同部分的具有不同亮度时。根据图像上的每一个小区域计算与其对应的阈值,得到最优的效果。
void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C)
-
原图像
-
输出图像
-
一个邻域内计算阈值所采用的算法:
ADAPTIVE_THRESH_MEAN_C
计算出领域的平均值再减去第七个参数double C的值ADAPTIVE_THRESH_GAUSSIAN_C
计算出领域的高斯均值再减去第七个参数double C的值 -
int thresholdType:阈值类型,只有两个取值,
THRESH_BINARY
THRESH_BINARY_INV -
int blockSize:adaptiveThreshold的计算单位是像素的邻域块,邻域块取多大,就由这个值作决定
-
double C :一个常数偏移值调整量,阈值就等于平均值或者加权平均值减去C。
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Mat src, graysrc, dst, thresh;
const char*output_title = "binaryimage";
int threshhold_value = 127;
int threshhold_max = 255;
int type_value = 2;
int type_max = 4;
void Threshhold_Demo(int, void*);
int main(int argc, char** argv)
{
src = imread("F:\\timg.jpg");
if (src.empty())
{
printf("could not load image src...\n");
return -1;
}
namedWindow("input image", WINDOW_AUTOSIZE);
imshow("input image", src);
namedWindow(output_title, WINDOW_AUTOSIZE);
createTrackbar("threshold value", output_title, &threshhold_value, threshhold_max, Threshhold_Demo);
createTrackbar("type value", output_title, &type_value, type_max, Threshhold_Demo);
Threshhold_Demo(0, 0);
//imwrite("F:\\xzbi.jpg", dst);
waitKey(0);
return 0;
}
void Threshhold_Demo(int, void*)
{
cvtColor(src, graysrc, CV_BGR2GRAY);
//threshold(graysrc, dst, threshhold_value, threshhold_max, THRESH_BINARY);
/*printf("%d", THRESH_BINARY);
printf("%d", THRESH_BINARY_INV);
printf("%d", THRESH_TRUNC);
printf("%d", THRESH_TOZERO);
printf("%d", THRESH_TOZERO_INV);*/
//threshold(graysrc, dst, threshhold_value, threshhold_max, type_value);
//threshold(graysrc, dst, 0, 255, THRESH_OTSU | type_value);//自动计算阈值
threshold(graysrc, dst, 0, 255, THRESH_TRIANGLE | type_value);
imshow(output_title, dst);
}
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2\core\core.hpp>
#include <opencv2/core/core_c.h>
#include <opencv2\objdetect\objdetect.hpp>
#include <opencv2\imgproc\types_c.h>
using namespace std;
using namespace cv;
Mat src, graysrc, dst;
const char*output_title = "ATMimage";
void Threshhold_Demo(int, void*);
int main(int argc, char** argv)
{
src = imread("F:\\timg.jpg");
if (src.empty())
{
printf("could not load image src...\n");
return -1;
}
namedWindow("input image", WINDOW_AUTOSIZE);
imshow("input image", src);
namedWindow(output_title, WINDOW_AUTOSIZE);
Threshhold_Demo(0, 0);
//imwrite("F:\\xzbi.jpg", dst);
waitKey(0);
return 0;
}
void Threshhold_Demo(int, void*)
{
int blockSize = 5;
int constValue = 10;
const int maxVal = 255;
/* 自适应阈值算法
0:ADAPTIVE_THRESH_MEAN_C
1: ADAPTIVE_THRESH_GAUSSIAN_C
阈值类型
0: THRESH_BINARY
1: THRESH_BINARY_INV */
//int adaptiveMethod = 0;
int thresholdType = 1;
cvtColor(src, graysrc, CV_BGR2GRAY);
//adaptiveThreshold(graysrc, dst, maxVal, adaptiveMethod, thresholdType, blockSize, constValue);
//adaptiveThreshold(graysrc, dst, maxVal, ADAPTIVE_THRESH_GAUSSIAN_C, thresholdType, blockSize, constValue);
adaptiveThreshold(graysrc, dst, maxVal, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, blockSize, constValue);
imshow(output_title, dst);
}