1. 程式人生 > >OpenCv--提取水平和垂直線(通過膨脹和腐蝕操作)

OpenCv--提取水平和垂直線(通過膨脹和腐蝕操作)

提取步驟

  • 輸入彩色影象
  • 轉換為灰度影象--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);

自適應二值化介紹:

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