欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenCv--提取水平和垂直线(通过膨胀和腐蚀操作)

程序员文章站 2022-03-22 17:49:40
...

提取步骤

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

二值图像
 

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

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

OpenCv--提取水平和垂直线(通过膨胀和腐蚀操作)

参数说明

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位

具体如下表

OpenCv--提取水平和垂直线(通过膨胀和腐蚀操作)

生成关系如下表

OpenCv--提取水平和垂直线(通过膨胀和腐蚀操作)

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;
}

 

相关标签: opencv