OpenCV2计算机视觉应用编程手册(自学版)初级四 图像邻域操作、滤波处理
介绍了锐化滤波器的四种实现方法
/*
第四个opencv程序---图像邻域操作、滤波处理
时间:2014年11月30日00:40:10
使用拉普拉斯算子对图像进行锐化滤波
锐化滤波的模板
0 -1 0
-1 5 -1
0 -1 0
下面介绍了四种图像锐化的方法,有的速度快,有的慢一些。在图像处理中
滤波是非常常见的,所以这个地方很重要。
几个知识点:
//1--- saturate_cast<uchar> 将小于的数据设置为大于的设置为
2---result.row(0).setTo(cv::Scalar(0));// 对第行的值都设置为下面类似
3---可以使用opencv自己定义的filter2D函数实现滤波器
*/
/*****************************************
锐化滤波器方法:
//1--- saturate_cast<uchar> 将小于0的数据设置为0 大于255的设置为255
2---result.row(0).setTo(cv::Scalar(0));// 对第一行的值都设置为0 下面类似
**********************************************/
#include "stdafx.h"
#include<iostream>
#include <opencv2/opencv.hpp>
using namespace std;// 使用STD
using namespace cv;// 使用名字空间
/*
第一个锐化函数 sharpen
*/
void sharpen(const cv::Mat &image, cv::Mat &result) {
result.create(image.size(), image.type()); // allocate if necessary
for (int j= 1; j<image.rows-1; j++)
{
// for all rows (except first and last)
const uchar* previous= image.ptr<const uchar>(j-1); // previous row
const uchar* current= image.ptr<const uchar>(j); // current row
const uchar* next= image.ptr<const uchar>(j+1); // next row
uchar* output= result.ptr<uchar>(j); // output row
for (int i=1; i<image.cols-1; i++) {
// saturate_cast<uchar> 将小于的数据设置为大于的设置为
*output++= cv::saturate_cast<uchar>(5*current[i]-current[i-1]-current[i+1]-previous[i]-next[i]);
//output[i]= cv::saturate_cast<uchar>(5*current[i]-current[i-1]-current[i+1]-previous[i]-next[i]);
}
}
// 对四个边界进行处理,最上面一行最下面最左边最右边。这个地方我们默认设置为了0
// Set the unprocess pixels to 00
result.row(0).setTo(cv::Scalar(0));// 对第一行的值都设置为下面类似
result.row(result.rows-1).setTo(cv::Scalar(0));
result.col(0).setTo(cv::Scalar(0));
result.col(result.cols-1).setTo(cv::Scalar(0));
}
/*****************************************
第二个锐化函数 sharpen2
锐化滤波器方法:
使用step访问下一行的首地址
**********************************************/
void sharpen2(const cv::Mat &image, cv::Mat &result) {
result.create(image.size(), image.type()); // allocate if necessary
int step= image.step1();
const uchar* previous= image.data; // ptr to previous row
const uchar* current= image.data+step; // ptr to current row
const uchar* next= image.data+2*step; // ptr to next row
uchar *output= result.data+step; // ptr to output row
for (int j= 1; j<image.rows-1; j++) { // for each row (except first and last)
for (int i=1; i<image.cols-1; i++) { // for each column (except first and last)
output[i]= cv::saturate_cast<uchar>(5*current[i]-current[i-1]-current[i+1]-previous[i]-next[i]);
}
previous+= step;// 这个地方使用step指向下一行的首地址
current+= step;
next+= step;
output+= step;
}
// Set the unprocess pixels to 0
result.row(0).setTo(cv::Scalar(0));
result.row(result.rows-1).setTo(cv::Scalar(0));
result.col(0).setTo(cv::Scalar(0));
result.col(result.cols-1).setTo(cv::Scalar(0));
}
/*****************************************
第三个锐化函数:sharpen3
锐化滤波器方法:
使用迭代器访问图像的数据
**********************************************/
void sharpen3(const cv::Mat &image, cv::Mat &result) {
cv::Mat_<uchar>::const_iterator it= image.begin<uchar>()+image.step;
cv::Mat_<uchar>::const_iterator itend= image.end<uchar>()-image.step;
cv::Mat_<uchar>::const_iterator itup= image.begin<uchar>();
cv::Mat_<uchar>::const_iterator itdown= image.begin<uchar>()+2*image.step;
result.create(image.size(), image.type()); // allocate if necessary
cv::Mat_<uchar>::iterator itout= result.begin<uchar>()+result.step;
for ( ; it!= itend; ++it, ++itup, ++itdown) {
*itout= cv::saturate_cast<uchar>(*it *5 - *(it-1)- *(it+1)- *itup - *itdown);
}
}
/*****************************************
第四个锐化函数:sharpen2D
锐化滤波器方法:
使用opencv自己定义的filter2D函数实现滤波器
********************************************/
void sharpen2D(const cv::Mat &image, cv::Mat &result) {
// Construct kernel (all entries initialized to 0)
cv::Mat kernel(3,3,CV_32F,cv::Scalar(0));
// assigns kernel values
kernel.at<float>(1,1)= 5.0;
kernel.at<float>(0,1)= -1.0;
kernel.at<float>(2,1)= -1.0;
kernel.at<float>(1,0)= -1.0;
kernel.at<float>(1,2)= -1.0;
//filter the image
cv::filter2D(image,result,image.depth(),kernel);
}
int main()
{
cv::Mat image= cv::imread("F:\\house.jpg",0);
if (!image.data)
return 0;
cv::Mat result;
result.create(image.size(),image.type());
double time= static_cast<double>(cv::getTickCount());// 计算各个滤波器的运行时间
sharpen(image, result);
time= (static_cast<double>(cv::getTickCount())-time)/cv::getTickFrequency();
std::cout << "time= " << 1000*time <<"ms"<< std::endl;
cv::namedWindow("Image");
cv::imshow("Image",result);
image= cv::imread("F:\\house.jpg",0);
time= static_cast<double>(cv::getTickCount());
sharpen3(image, result);
time= (static_cast<double>(cv::getTickCount())-time)/cv::getTickFrequency();
std::cout << "time iterator= " << 1000*time <<"ms"<< std::endl;
cv::namedWindow("Image 3");
cv::imshow("Image 3",result);
image= cv::imread("F:\\house.jpg",0);
time= static_cast<double>(cv::getTickCount());
sharpen2D(image, result);
time= (static_cast<double>(cv::getTickCount())-time)/cv::getTickFrequency();
std::cout << "time 2D= " << 1000*time <<"ms"<< std::endl;
cv::namedWindow("Image 2D");
cv::imshow("Image 2D",result);
cv::waitKey();
return 0;
}