1.12【OpenCV圖像處理】提取水平、垂直線與驗證碼
線狀結構元素、取反bitwise_not()、驗證碼
1.12.1 原理方法
圖像形態學操作時候,可以通過自定義的結構元素實現結構元素對輸入圖像一些對象敏感、另外一些對象不敏感,這樣就會讓敏感的對象改變而不敏感的對象保留輸出。
我們可以通過使用兩個最基本的形態學操作 – 膨脹與腐蝕,使用不同的結構元素實現對輸入圖像的操作、得到想要的結果。
膨脹:輸出的像素值是結構元素覆蓋下輸入圖像的最大像素值。
腐蝕:輸出的像素值是結構元素覆蓋下輸入圖像的最小像素值。
1.12.2 結構元素
上述膨脹與腐蝕過程可以使用任意的結構元素。
常見的形狀:矩形、圓、直線、磁碟形狀、磚石、字母形狀等各種自定義形狀。
如下圖的鑽石(diamond)形狀:
1.12.3 提取水平與垂直線步驟
提取步驟:
輸入圖像彩色圖像 - imread
轉換為灰度圖像 - cvtColor
轉換為二值圖像 - adaptiveThreshold
定義結構元素 - getStructuringElement
開操作 - morphologyEx
1)第一步輸入彩色圖像 - imread
src = imread("E:/OpenCV/testimage/line.jpg");
2)轉換為灰度圖像 – cvtColor
cvtColor(src, gray_src, CV_BGR2GRAY); //變成灰度圖像,等級0-255,單通道
3)轉換為二值圖像 – adaptiveThreshold(自適應閾值)
adaptiveThreshold(
Mat src, // 輸入的灰度圖像
Mat dest, // 二值圖像
double maxValue, // 二值圖像最大值
int adaptiveMethod // 自適應方法,只能其中之一 –
// ADAPTIVE_THRESH_MEAN_C 自適應閾值均值c, ADAPTIVE_THRESH_GAUSSIAN_C自適應閾值高斯c
int thresholdType,// 閾值類型-THRESH_BINARY 大於閾值的為最大值,THRESH_BINARY_INV 大於閾值的為0
int blockSize, // 塊大小
double C // 常量C 可以是正數,0,負數
)
閾值類型:
閾值:
adaptiveThreshold(~gray_src, binImg, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2); //二值化圖像,最大值,自適應閾值方法(平均或高斯),閾值類型(二值化),塊大小,常數
4)定義結構元素 - getStructuringElement
一個像素寬的水平線 - 水平長度 width/30
一個像素寬的垂直線 – 垂直長度 height/30
Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1), Point(-1,-1)); //水平結構元素,去垂直線Mat vline = getStructuringElement(MORPH_RECT, Size(1, src.rows / 30 ), Point(-1, -1)); //垂直結構元素,去水平線
5)開操作 - morphologyEx
morphologyEx(binImg, dst, CV_MOP_OPEN, hline); //開操作(腐蝕+膨脹)提取水平與垂直線
morphologyEx(binImg, dst, CV_MOP_OPEN, hline); //開操作
6)後處理 - 取反、模糊
bitwise_not(Mat bin, Mat dst);像素取反,255 – SrcPixel
blur(dst2, dst2, Size(3, 3), Point(-1, -1)); 模糊
bitwise_not(dst2, dst2); //按位非,取反,黑邊白,白變黑blur(dst2, dst2, Size(3, 3), Point(-1, -1)); //模糊
1.12.3 提取驗證碼
提取ORC驗證碼,濾除干擾,要轉化為二值圖像,通過圖像形態學手段進行處理,尋找合適的結構元素。
Mat kernel = getStructuringElement(MORPH_RECT, Size(4, 4), Point(-1, -1)); //矩形結構元素morphologyEx(binImg2, dst3, CV_MOP_OPEN, kernel); //開操作
完整程序:
/*1.12 提取水平線與垂直線*/#include <opencv2/opencv.hpp>#include <iostream> #include <math.h>using namespace cv; //使用cv命名空間int main(int argc, char** argv) { //argc 表示命令行輸入參數的個數(以空白符分隔),argv中存儲了所有的命令行參數Mat src,src2,dst,dst2,dst3; src = imread("E:/OpenCV/testimage/line.jpg"); src2 = imread("E:/OpenCV/testimage/驗證碼.jpg");if (src.empty()) { printf("could not load image...
");return -1; } namedWindow("input image", CV_WINDOW_AUTOSIZE); imshow("input image", src); imshow("~input image", ~src); //像素取反 imshow("input image2", src2);Mat gray_src, gray_src2; cvtColor(src, gray_src, CV_BGR2GRAY); //變成灰度圖像,等級0-255,單通道 cvtColor(src2, gray_src2 ,CV_BGR2GRAY); //變成灰度圖像,等級0-255,單通道 imshow("grary image", gray_src); imshow("~grary image", ~gray_src); //取反(變成了黑背景),黑邊白,白變黑Mat binImg; adaptiveThreshold(~gray_src, binImg, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2); //二值化圖像,最大值,自適應閾值方法(平均、高斯),閾值類型(二值化),塊大小,常數 imshow("binImg", binImg);Mat binImg2; adaptiveThreshold(~gray_src2, binImg2, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2); //二值化圖像,最大值,自適應閾值方法(平均、高斯),閾值類型(二值化),塊大小,常數 imshow("binImg2", binImg2);Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1), Point(-1,-1)); //水平結構元素,去垂直線Mat vline = getStructuringElement(MORPH_RECT, Size(1, src.rows / 30 ), Point(-1, -1)); //垂直結構元素,去水平線Mat kernel = getStructuringElement(MORPH_RECT, Size(4, 4), Point(-1, -1)); //矩形結構元素/*提取水平線,開操作*/// Mat temp;// erode(binImg, temp, hline); //腐蝕// dilate(temp, dst, hline); //膨脹 morphologyEx(binImg, dst, CV_MOP_OPEN, hline); //開操作 bitwise_not(dst, dst); //按位非,取反,黑邊白,白變黑 imshow("horizontal", dst);/*提取豎直線,開操作*/ morphologyEx(binImg, dst2, CV_MOP_OPEN, vline); //開操作 bitwise_not(dst2, dst2); //按位非,取反,黑邊白,白變黑 blur(dst2, dst2, Size(3, 3), Point(-1, -1)); //模糊 imshow("vertical", dst2);/*提取ORC驗證碼,濾除干擾*/ morphologyEx(binImg2, dst3, CV_MOP_OPEN, kernel); //開操作 bitwise_not(dst3, dst3); //按位非,取反,黑邊白,白變黑 blur(dst3, dst3, Size(2, 2), Point(-1, -1)); //模糊 imshow("驗證碼", dst3); waitKey(0);return 0;}
運行結果:
推薦閱讀:
※怎樣零基礎學習機器學習深度學習等進行圖像處理?
※SIFT特徵演算法是如何保證平移、旋轉不變的?
※如何看清監控錄像中的車牌?
※美圖公司的實驗室 MeituLabs 如何,有哪些大牛?
※搞機器視覺,演算法不是非常精通,但是熟悉嵌入式平台的代碼優化與演算法移植,找工作應如何定位自己的目標方向?