1. 程式人生 > >【OpenCV計算機視覺程式設計攻略】用形態學濾波器檢測邊緣和角點

【OpenCV計算機視覺程式設計攻略】用形態學濾波器檢測邊緣和角點

準備工作:

腐蝕和膨脹是最基本的形態學運算, 數學形態學中最基本的概念是結構元素。 結構元素可以簡單地定義為畫素的組合(下圖的正方形) , 在對應的畫素上定義了一個原點(也稱錨點) 。 形態學濾波器的應用過程就包含了用這個結構元素探測影象中每個畫素的操作過程。 把某個畫素設為結構元素的原點後, 結構元素和影象重疊部分的畫素集(下圖的九個陰影畫素) 就是特定形態學運算的應用物件。 結構元素原則上可以是任何形狀, 但通常它是一個簡單形狀, 如正方形、 圓形或菱形, 並且把中心點作為原點(主要是因為效率) , 如下圖(摘錄自:OpenCV計算機視覺程式設計攻略):

因為形態學濾波器通常作用於二值影象, 所以我們採用

【OpenCV計算機視覺程式設計攻略】用直方圖統計畫素 中通過閾值化建立的二值影象。 但在形態學中, 我們習慣用高畫素值(白色) 表示前景物體, 用低畫素值(黑色) 表示背景物體, 因此我們對影象做了反向處理。在形態學術語中, 下面的影象稱為【OpenCV計算機視覺程式設計攻略】用直方圖統計畫素 所建影象的補碼:

第一個截圖是腐蝕影象:

第二個截圖是膨脹影象:  

部分程式碼如下:

	imshow("img",img);
	Mat merode;
	erode(img, merode, Mat(),Point(-1,-1),3);
	imshow("erode", merode);

	Mat mdilate;
	dilate(img, mdilate, Mat(),Point(-1,-1),3);
	imshow("dilate", mdilate);

檢測邊緣和角點

檢測到的邊緣和角點如下圖所示:  

把檢測到的角點和邊緣還原到原圖中,效果如下圖所示:

部分程式碼如下:

//morphology.hpp
#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

class morphology {
public:
	morphology();
	morphology(int it, int tld);
	~morphology(){}
	void drawCorners(Mat& img, Mat& corners);
	void getCorners(Mat& img, Mat& corners);
	void getCornersImage(Mat& image, Mat& cornersImage);

private:
	int iterator;
	Mat cross, diamond, square, x;
	int threshold;
};
//main.cpp
#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "morphology.hpp"

using namespace std;
using namespace cv;


int main()
{
	string picture = "5.jpg";
	Mat img = imread(picture, 0);

	if (img.empty()) {
		cout << "error" << endl;
		return 1;
	}
	
	imshow("img",img);
	Mat merode;
	erode(img, merode, Mat(),Point(-1,-1),3);
	imshow("erode", merode);

	Mat mdilate;
	dilate(img, mdilate, Mat(),Point(-1,-1),3);
	imshow("dilate", mdilate);
	Mat result = mdilate - merode;
	threshold(result,result,40, 255,THRESH_BINARY);
	imshow("gradient", result);
	
	morphology ml;
	Mat corners;
	ml.getCorners(img, corners);
	img = imread(picture);//讀入彩色影象畫角點
	ml.drawCorners(img, corners);
	imshow("corners", corners);
	imshow("cornersImage", img);
	
	
	waitKey(0);
	return 0;
}