OpenCV識別提取圖像中的水平線與垂直線
本文實例為大家分享了OpenCV識別提取圖像中的水平線與垂直線,供大家參考,具體內(nèi)容如下
1).原理
圖像形態(tài)學(xué)操作時候,可以通過自定義的結(jié)構(gòu)元素實現(xiàn)結(jié)構(gòu)元素 對輸入圖像一些對象敏感、另外一些對象不敏感,這樣就會讓敏感的對象改變而不敏感的對象保留輸出。通過使用兩個最基本的形態(tài)學(xué)操作 – 膨脹與腐蝕,使用不同的結(jié)構(gòu)元素實現(xiàn)對輸入圖像的操作、得到想要的結(jié)果。
-膨脹,輸出的像素值是結(jié)構(gòu)元素覆蓋下輸入圖像的最大像素值
-腐蝕,輸出的像素值是結(jié)構(gòu)元素覆蓋下輸入圖像的最小像素值
常見的形狀:矩形、園、直線、磁盤形狀、磚石形狀等各種自定義形狀。
2).步驟
1.輸入圖像彩色圖像 imread
2.轉(zhuǎn)換為灰度圖像 – cvtColor
3.轉(zhuǎn)換為二值圖像 – adaptiveThreshold
4.定義結(jié)構(gòu)元素
5.開操作 (腐蝕+膨脹)提取 水平與垂直線
3).完整代碼
(本人的運行環(huán)境是:vs2017+OpenCV3.4)
#include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespace std; using namespace cv; //灰度化圖像 Mat gray_Img(Mat src) { Mat dst = Mat::zeros(src.size(), src.type()); cvtColor(src, dst, CV_BGR2GRAY); return dst; } //自適應(yīng)閾值(二值化圖像) Mat threshold_Img(Mat src) { Mat dst = Mat::zeros(src.size(), src.type()); //參數(shù):輸入, 輸出, 二值圖像的最大值 , 在一個鄰域內(nèi)計算閾值所采用的算法,有兩個取值分別為 ADAPTIVE_THRESH_MEAN_C 和 ADAPTIVE_THRESH_GAUSSIAN_C , 閾值類型只有兩個取值,分別為 THRESH_BINARY 和THRESH_BINARY_INV,(blockSize)adaptiveThreshold的計算單位是像素的鄰域塊,鄰域塊取多大就由這個值作決定, 偏移值調(diào)整量 adaptiveThreshold(~src, dst, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2); return dst; } //結(jié)構(gòu)元素(獲取垂直算子) Mat get_Vertical(Mat src) { Mat dst = Mat::zeros(src.size(), src.type()); return getStructuringElement(MORPH_RECT,Size(src.cols/16,1),Point(-1,-1)); } //結(jié)構(gòu)元素(獲取水平算子) Mat get_Horizontal(Mat src) { Mat dst = Mat::zeros(src.size(), src.type()); return getStructuringElement(MORPH_RECT, Size(1, src.rows / 16), Point(-1, -1)); } //腐蝕 Mat erode_Img(Mat src,Mat kernel) { Mat dst = Mat::zeros(src.size(), src.type()); erode(src, dst, kernel); return dst; } //膨脹 Mat dilate_Img(Mat src, Mat kernel) { Mat dst = Mat::zeros(src.size(), src.type()); dilate(src, dst, kernel); return dst; } int main() { Mat src = imread("001.png"); if (src.empty()) { cout << "fail to load image" << endl; return -1; } namedWindow("input_Img", 0); imshow("input_Img", src); //輸入圖像轉(zhuǎn)灰度 Mat grayImg = gray_Img(src); namedWindow("input_Img_gray", 0); imshow("input_Img_gray", grayImg); //二值化圖像 Mat thresholdImg = threshold_Img(grayImg); namedWindow("input_Img_threshold", 0); imshow("input_Img_threshold", thresholdImg); Mat verticalLine = get_Vertical(src); Mat horizontalLine = get_Horizontal(src); //先腐蝕再膨脹 Mat vertical_Line_erode = erode_Img(thresholdImg, verticalLine); Mat vertical_Line_dilate = dilate_Img(vertical_Line_erode, verticalLine); //顯示圖像中的垂直線 namedWindow("verticalLine", 0); imshow("verticalLine", vertical_Line_dilate); Mat horizontal_Line_erode = erode_Img(thresholdImg, horizontalLine); Mat horizontal_Line_dilate = dilate_Img(horizontal_Line_erode, horizontalLine); //顯示圖像中的垂直線 namedWindow("horizontalLine", 0); imshow("horizontalLine", horizontal_Line_dilate); waitKey(); return 0; }
4).我的運行結(jié)果
1.灰度化結(jié)果
2.二值化
3.提取的垂直線
4.提取的水平線
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
c++將數(shù)組名作為函數(shù)參數(shù)對數(shù)組元素進行相應(yīng)的運算
這篇文章主要介紹了c++將數(shù)組名作為函數(shù)參數(shù)對數(shù)組元素進行相應(yīng)的運算,需要的朋友可以參考下2014-05-05C++操作MySQL大量數(shù)據(jù)插入效率低下的解決方法
這篇文章主要介紹了C++操作MySQL大量數(shù)據(jù)插入效率低下的解決方法,需要的朋友可以參考下2014-07-07