#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
static void help(char* progName) //static 为静态方法和静态变量的关键字,范围会受约束,不加static的方法和变量实用于所有源程序。
{
cout << endl //endl 是换行
<< "This program shows how to filter images with mask: the write it yourself and the"
<< "filter2d way. " << endl
<< "Usage:" << endl
<< progName << " [image_path -- default ../data/lena.jpg] [G -- grayscale] " << endl << endl;
}
void Sharpen(const Mat& myImage,Mat& Result);//函数定义在调用之后,所以在调用之前要先声明。
int main( int argc, char* argv[])
/*argc和argv参数在用命令行编译程序时有用。main( int argc, char* argv[], char **env ) 中
第一个参数,int型的argc,为整型,用来统计程序运行时发送给main函数的命令行参数的个数,在VS中默认值为1。
第二个参数,char* 型的argv[],为字符串数组,用来存放指向的字符串参数的指针数组,每一个元素指向一个参数。各成员含义如下:
argv[0]指向程序运行的全路径名
argv[1]指向在DOS命令行中执行程序名后的第一个字符串
argv[2]指向执行程序名后的第二个字符串
argv[3]指向执行程序名后的第三个字符串
argv[argc]为NULL*/
{
help(argv[0]);
const char* filename = argc >=2 ? argv[1] : "D:\\opencv\\sources\\samples\\data\\lena.jpg";
//?:三目运算符 <表达式1>?<表达式2>:<表达式3> 如果表达式1成立,则输出表达式2,否则输出表达式3
Mat src, dst0, dst1;
if (argc >= 3 && !strcmp("G", argv[2])) //功能:比较字符串s1和s2。strcmp(字符串1,字符串2),当s1<s2时,返回值<0,当s1=s2时,返回值=0,当s1>s2时,返回值>0
src = imread( filename, IMREAD_GRAYSCALE); //imread(路径字符串指针,读取图片的模式枚举),IMREAD_GRAYSCALE始终将图像转换为单通道灰度图像(编解码器内部转换)。
else
src = imread( filename, IMREAD_COLOR); //始终将图像转换为3通道BGR彩色图像。
if (src.empty())
{
cerr << "Can't open image [" << filename << "]" << endl;
return -1;
}
namedWindow("Input", WINDOW_AUTOSIZE);
//namedWindow("Input", WINDOW_NORMAL);
//namedWindow()新建一个显示窗口,可以指定窗口的类型。
//WINDOW_AUTOSIZE 窗口大小自动适应图片大小,并且不可手动更改。
//WINDOW_NORMAL 用户可以改变这个窗口大小
//WINDOW_OPENGL 窗口创建的时候会支持OpenGL
namedWindow("Output", WINDOW_AUTOSIZE);
imshow( "Input", src );//显示一个图像在指定的窗口上
double t = (double)getTickCount();//getTickCount()返回从操作系统启动到现在所经过的计时周期数,返回的值为DWORD
Sharpen( src, dst0 );
t = ((double)getTickCount() - t)/getTickFrequency();//getTickFrequency()返回CPU的频率,单位为s.
cout << "Hand written function time passed in seconds: " << t << endl;
imshow( "Output", dst0 );
waitKey();
//![kern]
Mat kernel = (Mat_<char>(3,3) << 0, -1, 0,
-1, 5, -1,
0, -1, 0);
//![kern]
t = (double)getTickCount();
//![filter2D]
filter2D( src, dst1, src.depth(), kernel );
//![filter2D]
t = ((double)getTickCount() - t)/getTickFrequency();
cout << "Built-in filter2D time passed in seconds: " << t << endl;
imshow( "Output", dst1 );
waitKey();
return 0;
}
//! [basic_method]
void Sharpen(const Mat& myImage,Mat& Result) //增加对比度算法
{
//! [8_bit]
CV_Assert(myImage.depth() == CV_8U); // accept only uchar images CV_Assert(条件1),条件1错误停止程序运行
//! [8_bit]
//! [create_channels]
const int nChannels = myImage.channels();
Result.create(myImage.size(),myImage.type()); //创建一个输出图像大小和类型与输入图像相同
//! [create_channels]
//! [basic_method_loop]
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]);
}
}
//! [basic_method_loop]
//! [borders]
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));
//! [borders]
}
//! [basic_method]