Opencv之矩阵的掩码操作

矩阵的掩码操作很简单。其思想是:根据掩码矩阵(也称作核)重新计算图像中每个像素的值。掩码矩阵中的值表示近邻像素值(包括该像素自身的值)对新像素值有多大影响。从数学观点看,我们用自己设置的权值,对像素邻域内的值做了个加权平均。

#include
#include
using namespace std;
using namespace cv;

static void Sharpen(const Mat&myImage,Mat& Result) {
	CV_Assert(myImage.depth() == CV_8U);
	const int nChannels = myImage.channels();
	Result.create(myImage.size(), myImage.type());
	for (int j = 1; j < myImage.rows - 1; ++j) {
		auto previous = myImage.ptr<uchar>(j - 1);
		auto current = myImage.ptr<uchar>(j);
		auto next = myImage.ptr<uchar>(j + 1);
		auto output = Result.ptr<uchar>(j);

		for (int i = nChannels; i < nChannels*(myImage.cols - 1); ++i) {
			*output++ = saturate_cast<uchar>(5 * current[i]
				- current[i - nChannels] 
				- current[i + nChannels] 
				- previous[i] - next[i]);
		}
		Result.row(0).setTo(Scalar(0));
		Result.row(Result.rows - 1).setTo(Scalar(0));
		Result.col(0).setTo(Scalar(0));
		Result.col(Result.cols - 1).setTo(Scalar(0));
	}
}

static void test() {
	Mat mImage, Result;
	const string path("E:/picture/renwu1.jpg");
	const string input_image("input image");
	const string output_image("output image");

	mImage = imread(path);
	if (!mImage.data) {
		cout << "image could not to be failed..." << endl;
		return;
	}

	namedWindow(input_image, WINDOW_AUTOSIZE);
	namedWindow(output_image, WINDOW_AUTOSIZE);

	imshow(input_image, mImage);
	double t = (double)getTickCount();
	Sharpen(mImage, Result);
	t = ((double)getTickCount() - t) / getTickFrequency();
	cout << "Hand wrritten function times passed in seconds:" << t << endl;

	imshow(output_image, Result);
	waitKey(0);	
}

static void test01() {
	Mat mImage, K;
	const string path("E:/picture/renwu1.jpg");
	const string input_image("input image");
	const string output_image("output image");
	mImage = imread(path);
	if (!mImage.data) {
		cout << "image could not to be failed..." << endl;
		return;
	}
	namedWindow(input_image, WINDOW_AUTOSIZE);
	namedWindow(output_image, WINDOW_AUTOSIZE);
	Mat kern = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	double t = (double)getTickCount();
	filter2D(mImage, K, mImage.depth(), kern);
	t = ((double)getTickCount() - t) / getTickFrequency();
	cout << "Built-in filter2D time passed in seconds:      " << t << endl;

	imshow(output_image, K);
	waitKey(0);
}

int main()
{
	test();
	return 0;
}

结果
Opencv之矩阵的掩码操作_第1张图片
filter2D函数
滤波器在图像处理中的应用太广泛了,因此OpenCV也有个用到了滤波器掩码(某些场合也称作核)的函数。不过想使用这个函数,你必须先定义一个表示掩码的 Mat 对象:
Mat kern = (Mat_(3,3) <<
0, -1, 0,
-1, 5, -1,
0, -1, 0);
然后调用 filter2D 函数,参数包括输入、输出图像以及用到的核:
它还带有第五个可选参数——指定核的中心,和第六个可选参数——指定函数在未定义区域(边界)的行为。使用该函数有一些优点,如代码更加清晰简洁、通常比 自己实现的方法 速度更快(因为有一些专门针对它实现的优化技术)等等。例如,我测试的滤波器方法仅花了13毫秒,而前面那样自己实现迭代方法花了约31毫秒,二者有着不小差距。

int main()
{
	test01();
	return 0;
}

Opencv之矩阵的掩码操作_第2张图片

你可能感兴趣的:(Opencv,opencv)