码迷,mamicode.com
首页 > 其他好文 > 详细

OpenCV Tutorials —— Mask operations on matrices

时间:2014-11-16 17:07:47      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:style   http   io   color   ar   os   sp   for   div   

Mask operations on matrices are quite simple. The idea is that we recalculate each pixels value in an image according to a mask matrix (also known as kernel). This mask holds values that will adjust how much influence neighboring pixels (and the current pixel) have on the new pixel value

蒙版操作或者核操作 ~~

bubuko.com,布布扣

The first notation is by using a formula, while the second is a compacted version of the first by using a mask. You use the mask by putting the center of the mask matrix (in the upper case noted by the zero-zero index) on the pixel you want to calculate and sum up the pixel values multiplied with the overlapped matrix values.

 

void Sharpen(const Mat& myImage, Mat& Result)
{
    CV_Assert(myImage.depth() == CV_8U);  // accept only uchar images

    Result.create(myImage.size(), myImage.type());
    const int nChannels = myImage.channels();

    for(int j = 1; j < myImage.rows - 1; ++j)
    {
        const uchar* previous = myImage.ptr<uchar>(j - 1);	// 前一行
        const uchar* current  = myImage.ptr<uchar>(j    );	// 当前行
        const uchar* next     = myImage.ptr<uchar>(j + 1);  // 后一行

        uchar* 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));
}

We’ll use the plain C [] operator to access pixels. Because we need to access multiple rows at the same time we’ll acquire the pointers for each of them (a previous, a current and a next line). We need another pointer to where we’re going to save the calculation.

 

Border

On the borders of the image the upper notation results inexistent pixel locations (like minus one - minus one). In these points our formula is undefined. A simple solution is to not apply the kernel in these points and, for example, set the pixels on the borders to zeros:

Result.row(0).setTo(Scalar(0));               // The top row
Result.row(Result.rows - 1).setTo(Scalar(0)); // The bottom row
Result.col(0).setTo(Scalar(0));               // The left column
Result.col(Result.cols - 1).setTo(Scalar(0)); // The right column

setTo (Scalar) —— 将矩阵置为某一元素

 

The filter2D function

上面的方式,自己实现了整个过滤过程 —— 其实可以把公共部分代码提取出来

For this you first need to define a Mat object that holds the mask:

Mat kern = (Mat_<char>(3,3) <<  0, -1,  0,
                               -1,  5, -1,
                                0, -1,  0);

Then call the filter2D function specifying the input, the output image and the kernell to use:

filter2D(I, K, I.depth(), kern);

The function even has a fifth optional argument to specify the center of the kernel, and a sixth one for determining what to do in the regions where the operation is undefined (borders).

这种方式更加简洁,并且比硬编码的方式效率更高

滤波的方法非常常用,而且不同mask的不同效果应该熟悉

 

#include "stdafx.h"

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

using namespace std;
using namespace cv;

static void help(char* progName)
{
	cout << endl
		<<  "This program shows how to filter images with mask: the write it yourself and the"
		<< "filter2d way. " << endl
		<<  "Usage:"                                                                        << endl
		<< progName << " [image_name -- default lena.jpg] [G -- grayscale] "        << endl << endl;
}


void Sharpen(const Mat& myImage,Mat& Result);

int main( int argc, char* argv[])
{
	help(argv[0]);
	const char* filename = argc >=2 ? argv[1] : "lena.jpg";

	Mat I, J, K;

	if (argc >= 3 && !strcmp("G", argv[2]))
		I = imread( filename, CV_LOAD_IMAGE_GRAYSCALE);
	else
		I = imread( filename, CV_LOAD_IMAGE_COLOR);

	namedWindow("Input", WINDOW_AUTOSIZE);
	namedWindow("Output", WINDOW_AUTOSIZE);

	imshow("Input", I);
	double t = (double)getTickCount();

	Sharpen(I, J);

	t = ((double)getTickCount() - t)/getTickFrequency();
	cout << "Hand written function times passed in seconds: " << t << endl;

	imshow("Output", J);
	waitKey(0);

	Mat kern = (Mat_<char>(3,3) <<  0, -1,  0,
		-1,  5, -1,
		0, -1,  0);
	t = (double)getTickCount();
	filter2D(I, K, I.depth(), kern );
	t = ((double)getTickCount() - t)/getTickFrequency();
	cout << "Built-in filter2D time passed in seconds:      " << t << endl;

	imshow("Output", K);

	waitKey(0);
	return 0;
}
void Sharpen(const Mat& myImage,Mat& Result)
{
	CV_Assert(myImage.depth() == CV_8U);  // accept only uchar images

	const int nChannels = myImage.channels();
	Result.create(myImage.size(),myImage.type());

	for(int j = 1 ; j < myImage.rows-1; ++j)
	{
		const uchar* previous = myImage.ptr<uchar>(j - 1);
		const uchar* current  = myImage.ptr<uchar>(j    );
		const uchar* next     = myImage.ptr<uchar>(j + 1);

		uchar* 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));
}

OpenCV Tutorials —— Mask operations on matrices

标签:style   http   io   color   ar   os   sp   for   div   

原文地址:http://www.cnblogs.com/sprint1989/p/4101540.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!