提取步骤

  • 输入彩色图像
  • 转换为灰度图像--cvtcolor
  • 转换为二值图像--adaptiveThreshold(Threshold)
  • 定义结构元素  *(重点)
  • 开操作(腐蚀+膨胀)提取,水平和垂直线

二值图像
 

二值图像是指在图像中,灰度等级只有两种,也就是说,图像中的任何像素不是0就是1,再无其他过渡的灰度值。

图像二值化的作用是为了方便提取图像中的信息,二值图像在进行计算机识别时可以增加识别效率。

参数说明

src:源图像,可以为8位的灰度图,也可以为32位的彩色图像。(两者由区别)

dst:输出图像

thresh:阈值

maxval:dst图像中最大值

type:阈值类型,可以具体类型如下:

编号 阈值类型枚举

注意

1 THRESH_BINARY

 

2 THRESH_BINARY_INV

 

3 THRESH_TRUNC

 

4 THRESH_TOZERO

 

5 THRESH_TOZERO_INV

 

6 THRESH_MASK

不支持

7 THRESH_OTSU

不支持32位

8 THRESH_TRIANGLE

不支持32位

具体如下表

生成关系如下表

Otsu算法原理

Otsu算法(大津法或最大类间方差法)使用的是聚类的思想,把图像的灰度数按灰度级分成2个部分,使得两个部分之间的灰度值差异最大,每个部分之间的灰度差异最小,通过方差的计算来寻找一个合适的灰度级别来划分。 所以可以在二值化的时候采用otsu算法来自动选取阈值进行二值化。otsu算法被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响。因此,使类间方差最大的分割意味着错分概率最小。

设t为设定的阈值。

w0 分开后前景像素点数占图像的比例
u0 分开后前景像素点的平均灰度
w1 分开后背景像素点数占图像的比例
u1 分开后背景像素点的平均灰度

图像总平均灰度为: u = w0∗u0 + w1∗u1 

从L个灰度级遍历 t,使得 t 为某个值的时候,前景和背景的方差最大,则 这个 t 值便是我们要求得的阈值。其中,方差的计算公式如下:

 g = wo∗(u0−u)∗(u0−u) + w1∗(u1−u)∗(u1−u) 

此公式计算量较大,可以采用:

 g = w0∗w1∗(u0−u1)∗(u0−u1) 

由于Otsu算法是对图像的灰度级进行聚类,因此在执行Otsu算法之前,需要计算该图像的灰度直方图。


 //自动化找阈值的两种方法

threshold(src2, dst,0,255,THRESH_OTSU|thresh_type);

threshold(src2, dst, 0, 255,THRESH_TRIANGLE|thresh_type);

 

adaptiveThreshold

自适应二值化介绍:

opencv中adaptiveThreshold函数分析:

参数:

  _src      要二值化的灰度图
  _dst      二值化后的图
  maxValue  二值化后要设置的那个值
  method   块计算的方法(ADAPTIVE_THRESH_MEAN_C 平均值,ADAPTIVE_THRESH_GAUSSIAN_C 高斯分布加权和)
  type      二值化类型(CV_THRESH_BINARY 大于为最大值,CV_THRESH_BINARY_INV 小于为最大值)
  blockSize  块大小(奇数,大于1,通过计算每个像素周围(blocksize x blocksize)大小像素块的加权均值并减去常量C得到。)
  delta     差值(负值也可以)

如果使用平均的方法,则所有像素周围的权值相同;如果使用高斯的方法,则(x,y)周围的像素的权值则根据其到中心点的距离通过高斯方程得到。

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
	Mat src1, src2, dst,dst1;
	src1 = imread("C:\\Users\\马迎伟\\Desktop\\hs.png");
	if (src1.empty())
	{
		cout << "could not find src1" << endl;
	}
	namedWindow("input",CV_WINDOW_AUTOSIZE);
	imshow("input",src1);
	//先对 src1  转换成单通道灰度值
	cvtColor(src1,src2,CV_BGR2GRAY);
	//imshow("x",src2);
	//只有转换成灰度才能将图像进行二值化处理(自适应阈值操作)   ~为取反操作,有助于后面步骤的进行
	adaptiveThreshold(src2,dst,255,CV_ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,15,2);//15为块大小,通过对15*15的矩阵进行CV_ADAPTIVE_THRESH_MEAN_C操作,求和平均与c比较
	//对二值化的图像进行 开操作
	bitwise_not(dst, dst);
	imshow("s", dst);
		//水平结构元素
	Mat hkernel = getStructuringElement(MORPH_RECT,Size(dst.cols/16,1));
	    //垂直结构元素
	//Mat skernel = getStructuringElement(MORPH_RECT,Size(1,dst.rows / 16));
	morphologyEx(dst, dst1, CV_MOP_TOPHAT, hkernel, Point(-1, -1));
	imshow("wa",dst1);
	waitKey(0);
	return 0;
}