博主力求用最简单的语言将此部分内容讲解清楚,但由于博主同样是刚刚接触OpenCV,积累下笔记。
博主机器配置为:VS2013+opencv3.1.0+Win-64bit。
======================分割线===============
有的时候,想知道要我们的程序一共运行了多长时间,这个很常用,也很简单,仅仅需要两个函数即可。
opencv里使用getTickCount()与getTickFrequency()函数记录时间;
函数解释:
getTickCount()函数:它返回从操作系统启动到当前所经的计时周期数。
getTickFrequency()函数:返回CPU的频率。
=====================分割线==================
#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
//1 记录程序开始点timeStart
double timeStart = (double)getTickCount();
//2 此部分为简单的循环,仅供测试使用
int a = 0;
while (a < 5000000)
{
a++;
}
//将以上部分替换成,自己需要计算运行程序的代码
//3 记录程序消耗的总时间
//getTickCount()函数:它返回从操作系统启动到当前所经的计时周期数
//getTickFrequency()函数:返回CPU的频率
double timeConsume = ((double)getTickCount() - timeStart)/getTickFrequency();
printf("timeConsume:%.2f",timeConsume);
system("pause");
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/3f8eea4817f5e4557f538bad55dbcf65.png)
=====================分割线==================
所谓掩膜其实就是一个矩阵,然后根据这个矩阵重新计算图片中像素的值。
掩膜主要有以下用途:- 提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0。
- 屏蔽作用,用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。
- 结构特征提取,用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征。
- 特殊形状图像的制作。
掩膜操作实现图像对比度的提高:
图像像素指针的获取:
Mat.ptr<uchar>(row):获取第row行的图像像素指针。图像的行数从0开始计数
获取点P(row,col)的像素值:P(row.col)= Mat.ptr<uchar>(row)[col]
- 1
- 2
- 3
使用的掩膜:
红色是中心元素I(i,j)。掩膜操作公式:
I(i,j)=5∗I(i,j)−[I(i−1,j)+I(i+1,j)+I(i,j−1)+I(i,j+1)]
用此掩膜从上至下,从左至右对图像进行操作,得到的图像就是增强对比度的图像。实例代码:
#include <opencv2\opencv.hpp>
#include <highgui.h>
using namespace cv;
int main()
{
Mat src, dst;
src = imread("D:/demo01.jpg");
if (!src.data)
{
printf("could not load image!");
return -1;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
/*
int cols = (src.cols - 1) * src.channels();//获取图像的列数,一定不要忘记图像的通道数
int offsetx = src.channels();//图像通道数
int rows = src.rows;//获取图像的行数
//生成一个和源图像大小相等类型相同的全0矩阵
dst = Mat::zeros(src.size(), src.type());//初始化一下dst
for (int row = 1; row < (rows - 1); row++) {
const uchar* previous = src.ptr<uchar>(row - 1);
//Mat.ptr<uchar>(int i = 0) 获取像素矩阵的指针,索引i表示第几行,从0开始计行数。
const uchar* current = src.ptr<uchar>(row);
//获得当前行指针const uchar* current = myImage.ptr<uchar>(row);
const uchar* next = src.ptr<uchar>(row + 1);
uchar* output = dst.ptr<uchar>(row);//
for (int col = offsetx; col < cols; col++) {
output[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offsetx] + current[col + offsetx] + previous[col] + next[col]));
//像素范围处理saturate_cast<uchar>
}
}*/
//定义掩膜:Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
//filter2D(src, dst, src.depth(), kernel); 其中src与dst是Mat类型变量、src.depth表示位图深度,有32、24、8等
double timeStart = (double)getTickCount();
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(src,dst,src.depth(),kernel);
double timeconsume = ((double)getTickCount() - timeStart) / getTickFrequency();
printf("timeconsume:%.2f",timeconsume);
namedWindow("contrast image demo", CV_WINDOW_AUTOSIZE);
imshow("contrast image demo", dst);
waitKey(0);
system("pause");
return 0;
}
filter2D()
opencv已经设计了一个函数用于掩模操作,首先你需要自定义一个Mat_<> :
Mat kern = (Mat_<char>(3,3) << 0, -1, 0,
-1, 5, -1,
0, -1, 0);
- 1
- 2
- 3
- 4
调用方法,依次是输入Mat 输出Mat 位深,mask矩阵:
filter2D(I, K, I.depth(), kern);
- 1
- 2
第五个参数可以设置mask矩阵的中心位置,第六个参数决定在操作不到的地方(边界)如何进行操作。使用这个函数最大的好处就是快。