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