opencv4 学习 09 使用形态学算子提取水平线和垂直线
1.提取水平线时,主要使用 w×1 形状的核,w为核的宽度,然后再进行腐蚀和膨胀操作。
2.提取垂直线时,主要使用 1×h 形状的核,h为核的高度,然后再进行腐蚀和膨胀操作。
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> using namespace std; using namespace cv; void show_wait_destory(const char* winname, cv::Mat img){ imshow(winname, img); moveWindow(winname,500,0); waitKey(0); destroyWindow(winname); } int main(int argc, char* argv[]) { Mat src = imread("notes.png", IMREAD_COLOR); imshow("src", src); Mat gray; if(src.channels()==3){ cvtColor(src, gray, COLOR_BGR2GRAY); } else { gray = src; } show_wait_destory("gray",gray); Mat bw; adaptiveThreshold(~gray, bw ,255, ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,15,-2); show_wait_destory("binary", bw); Mat horizontal = bw.clone(); Mat vertical = bw.clone(); int horizontal_size = horizontal.cols / 30; Mat horizontalStructure = getStructuringElement(MORPH_RECT, Size(horizontal_size, 1)); erode(horizontal, horizontal,horizontalStructure, Point(-1,-1)); dilate(horizontal,horizontal,horizontalStructure, Point(-1,-1)); show_wait_destory("horizontal", horizontal); int vertical_size = vertical.rows / 30; Mat verticalStructure = getStructuringElement(MORPH_RECT, Size(1, vertical_size)); erode(vertical, vertical, verticalStructure, Point(-1,-1)); dilate(vertical, vertical, verticalStructure, Point(-1,-1)); show_wait_destory("vertical",vertical); bitwise_not(vertical, vertical); show_wait_destory("vertical_bit", vertical); // Extract edges Mat edges; adaptiveThreshold(vertical,edges,255,ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 3, -2); show_wait_destory("edges", edges); Mat kernel = Mat::ones(2,2,CV_8UC1); dilate(edges,edges,kernel); show_wait_destory("dilate",edges); Mat smooth; vertical.copyTo(smooth); blur(smooth, smooth, Size(2,2)); smooth.copyTo(vertical,edges); show_wait_destory("smooth - final", vertical); return 0; }
参考:
https://docs.opencv.org/3.4/dd/dd7/tutorial_morph_lines_detection.html