天天看點

OpenCV C++開發 第二節:圖像處理(六、形态學操作、形态學應用之提取水準垂直線)一、形态學操作二、形态學應用之提取水準垂直線

一、形态學操作

代碼:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
int main(int argc, char** argv) {
	Mat src, dst;
	src = imread("C:\\Users\\Administrator\\Desktop\\test.png");
	if (!src.data) {
		printf("could not load image...\n");
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);
	char output_title[] = "morphology demo";
	namedWindow(output_title, CV_WINDOW_AUTOSIZE);

	Mat kernel = getStructuringElement(MORPH_RECT, Size(11, 11), Point(-1, -1));
	morphologyEx(src, dst, CV_MOP_OPEN, kernel);//形态學操作
	imshow(output_title, dst);

	waitKey(0);
	return 0;
}
           

以上代碼中主要的幾個知識點解釋下:

1.Mat kernel = getStructuringElement(MORPH_RECT, Size(11, 11), Point(-1, -1));

這裡還是之前講到的掩膜的設定。

MORPH_RECT是方形,MORPH_CROSS是十字形結構,MORPH_ELLIPSE是橢圓形。

第二個Size參數是掩膜的大小。

2.morphologyEx(src, dst, CV_MOP_OPEN, kernel);

這裡是形态學操作的方法,常用的五種類型:

(1)CV_MOP_OPEN

開操作。相當于先腐蝕後膨脹,可以去掉小的白色對象。如下圖。

OpenCV C++開發 第二節:圖像處理(六、形态學操作、形态學應用之提取水準垂直線)一、形态學操作二、形态學應用之提取水準垂直線

(2)CV_MOP_CLOSE

閉操作。相當于先膨脹後腐蝕,可以填充小的黑色洞。如下圖。

OpenCV C++開發 第二節:圖像處理(六、形态學操作、形态學應用之提取水準垂直線)一、形态學操作二、形态學應用之提取水準垂直線

(3)CV_MOP_GRADIENT

形态學梯度。相當于膨脹減去腐蝕。如下圖

OpenCV C++開發 第二節:圖像處理(六、形态學操作、形态學應用之提取水準垂直線)一、形态學操作二、形态學應用之提取水準垂直線

(4)CV_MOP_TOPHAT

頂帽。相當于原圖像與開操作的內插補點圖像。如下圖。

OpenCV C++開發 第二節:圖像處理(六、形态學操作、形态學應用之提取水準垂直線)一、形态學操作二、形态學應用之提取水準垂直線

(5)CV_MOP_BLACKHAT

黑帽。相當于閉操作與源圖像的內插補點圖像。如下圖。

OpenCV C++開發 第二節:圖像處理(六、形态學操作、形态學應用之提取水準垂直線)一、形态學操作二、形态學應用之提取水準垂直線

二、形态學應用之提取水準垂直線

代碼:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
int main(int argc, char** argv) {
	Mat src, dst;
	src = imread("C:\\Users\\Administrator\\Desktop\\line.png");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}

	char INPUT_WIN[] = "input image";
	char OUTPUT_WIN[] = "result image";
	namedWindow(INPUT_WIN, CV_WINDOW_AUTOSIZE);
	imshow(INPUT_WIN, src);

	Mat gray_src;
	cvtColor(src, gray_src, CV_BGR2GRAY);
	imshow("gray image", gray_src);

	Mat binImg;
	adaptiveThreshold(~gray_src, binImg, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
	imshow("binary image", binImg);

	// 水準結構元素
	Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1), Point(-1, -1));
	// 垂直結構元素
	Mat vline = getStructuringElement(MORPH_RECT, Size(1, src.rows / 16), Point(-1, -1));
	// 矩形結構
	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));

	Mat temp;
	erode(binImg, temp, hline);//hline是擷取橫線,vline是豎線
	dilate(temp, dst, hline);//hline是擷取橫線,vline是豎線
	// morphologyEx(binImg, dst, CV_MOP_OPEN, vline);//上面兩行可以用這個替代,開操作。
	bitwise_not(dst, dst);
	//blur(dst, dst, Size(3, 3), Point(-1, -1));
	imshow("Final Result", dst);

	waitKey(0);
	return 0;
}
           

這張是原圖,可右鍵另存做測試,也可以自己畫一張。

OpenCV C++開發 第二節:圖像處理(六、形态學操作、形态學應用之提取水準垂直線)一、形态學操作二、形态學應用之提取水準垂直線

以上代碼中主要的幾個知識點解釋下:

1.cvtColor(src, gray_src, CV_BGR2GRAY);

變灰階圖。

2.adaptiveThreshold(~gray_src, binImg, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);

變成二值圖像。就是隻有黑色和白色兩種的圖。

3.erode(binImg, temp, hline);

    dilate(temp, dst, hline);

這裡相是先腐蝕後膨脹,就是形态學開操作。

橫線擷取:用一像素高的水準掩膜去計算。

豎線擷取:用一像素寬的豎直掩膜去計算。

4.bitwise_not(dst, dst);

全部取反操作。白色變黑色,黑色變白色。

最後的效果如圖:

OpenCV C++開發 第二節:圖像處理(六、形态學操作、形态學應用之提取水準垂直線)一、形态學操作二、形态學應用之提取水準垂直線

繼續閱讀