【圖像處理】sift特徵——生成高斯金字塔圖像c++

【圖像處理】sift特徵——生成高斯金字塔圖像c++

計算sift特徵第一步是生成高斯金字塔圖像
計算過程:
1.設置參數,高斯濾波初始化標準差,Lowe設置的爲1.6,每一組層數,這裏設置爲3。
2.計算每一組每一層的標準差float cal_scale(int group, int layer);
3.圖像首先放大爲原先的兩倍(上採樣),計算每一層的高斯濾波圖像,然後降採樣,循環至最後一組。

代碼如下:

#include <vector>
#include <assert.h>
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
class build_gauss_pyrmaid{
public:
	void set_param(float delta0, int s);
	void process(const cv::Mat& src);
public:
	void test_save_mats();//test saved images
	void test_printf_scales();//test scales
protected:
	void cal_nums_of_group(cv::Size imageSize, int a = 3);//calculate the group number
	void build_pyrmaid(const cv::Mat& src);
	cv::Mat bgr2gray(const cv::Mat& src);
	float cal_scale(int group, int layer);
private:
	vector<vector<cv::Mat>> _gauss_pyrmaid;
	int _nums_of_group;
	float _delta0;
	int _layer_each_group;
	float _K;
	vector<vector<float>> _scales;
};

void build_gauss_pyrmaid::set_param(float delta0, int s)
{
	_delta0 = delta0;
	_layer_each_group = s;
	_K = (float)std::pow(2, 1.0/_layer_each_group);
}

float build_gauss_pyrmaid::cal_scale(int group, int layer)
{
	assert(group < _nums_of_group);
	assert(layer < _layer_each_group);
	return _delta0 * std::pow(2, (group+layer)/(float)_layer_each_group);
}

void build_gauss_pyrmaid::process(const cv::Mat& src)
{
	cal_nums_of_group(src.size(), 3);
	build_pyrmaid(src);
}	

void build_gauss_pyrmaid::cal_nums_of_group(cv::Size imageSize, int a)
{
	int lens = std::min(imageSize.width, imageSize.height);
	_nums_of_group = (int)std::log(lens) / std::log(2) - a;
}

cv::Mat build_gauss_pyrmaid::bgr2gray(const cv::Mat& src)
{
	cv::Mat mat8;
	if(src.type() == CV_8UC3) cv::cvtColor(src, mat8, CV_BGR2GRAY);
	else mat8 = src.clone();
	return mat8;
}

void build_gauss_pyrmaid::build_pyrmaid(const cv::Mat& src)
{

	cv::Mat I0 = bgr2gray(src);
	cv::pyrUp(I0, I0);

	cv::Mat each_mat;
	for(int group = 0; group < _nums_of_group; group++)
	{
		std::vector<cv::Mat> scale_mats;
		std::vector<float> scales;
		for(int layer = 0; layer < _layer_each_group; layer++)
		{
			float delta = cal_scale(group, layer);
			cv::GaussianBlur(I0, each_mat, cv::Size(0,0), delta);

			scale_mats.push_back(each_mat.clone());
			scales.push_back(delta);
		}
		cv::pyrDown(I0, I0);
		_scales.push_back(scales);
		_gauss_pyrmaid.push_back(scale_mats);
	}
}

void build_gauss_pyrmaid::test_save_mats()//test saved images
{
	int group(0);
	for(auto iter = _gauss_pyrmaid.begin(); iter != _gauss_pyrmaid.end(); iter++)
	{
		std::vector<cv::Mat> mats(*iter);
		char buf[128];
		int layer = 0;
		for(auto jter = mats.begin(); jter != mats.end(); jter++)
		{
			sprintf(buf, "scale_image/%d-%d.jpg", group,layer);
			cv::imwrite(buf, *jter);
			layer++;
		}
		group++;
	}
}

void build_gauss_pyrmaid::test_printf_scales()//test scales
{
	int group(0);
	for(auto iter = _scales.begin(); iter != _scales.end(); iter++)
	{
		std::vector<float> scale(*iter);
		int layer = 0;
		for(auto jter = scale.begin(); jter != scale.end(); jter++)
		{
			printf("%dth group %dth layer sacles: %.3f\n", group,layer,*jter);
			layer++;
		}
		group++;
	}
}

int main(int argc, char** argv)
{
	cv::Mat src = cv::imread("lena.jpg");
	build_gauss_pyrmaid* ptr = new build_gauss_pyrmaid;
	ptr->set_param(1.6, 3);
	ptr->process(src);
	ptr->test_save_mats();
	ptr->test_printf_scales();
	
	delete ptr;
	return 0;
}

爲了測試結果是否正確,添加測試接口。
void test_save_mats();//test saved images
void test_printf_scales();//test scales
結果爲:
在這裏插入圖片描述
存儲的高斯金字塔圖像爲:
只貼出第二層圖像
delta = 2.016
在這裏插入圖片描述
delta = 2.540
在這裏插入圖片描述
delta = 3.200
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章