话说程序猿们在开始一门语言前都喜欢写这么一句话:“Hello,world!”,但关于Lena其实我也不知道是哪家的女人,MATLAB和OpenCV好像都碰过,O(∩_∩)O哈哈~
新建一个空的win32控制台应用程序,具体就不啰嗦实现了,进入今日主题:
- Mat对象使用;
- 读入一张图片 imread( const String& filename, int flags = IMREAD_COLOR );
- 创建一个窗体 namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);
- 显示窗体 imshow(const String& winname, InputArray mat);
- 统计时间 getTickCount();
- 初始化Mat对象 zeros(Size size, int type);
- 获取图像指针 ptr<uchar>();
- 确保RGB值得到的范围在0~255之间 saturate_cast<uchar>();
- 定义一个掩膜 Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
- OpenCV API 矩阵掩膜处理 filter2D( InputArray src, OutputArray dst, int ddepth,InputArray kernel, Point anchor = Point(-1,-1),double delta = 0, int borderType = BORDER_DEFAULT );
不同的图像事实上就是不同的矩阵,而矩阵的掩膜操作就是通过掩膜重新计算每个像素的像素值,一般通过掩膜过程提高图像的对比度。逻辑就是从上到下、从左到有依次对每个像素做同样处理的过程,得到的最终结果就是对比度提高后的图像Mat对象。
插入掩膜计算数学公式(不要问我怎么来,我旨在应用^_^)
I(i , j)= 5 * I(i , j) - [I(i-1 , j) + I(i+1 , j) + I(i , j-1) + I(i , j+1)]
1. 实现纯数学公式的矩阵掩膜处理过程
具体效果图(可以看到处理后的图片对比度看好,looks like very good!^_^,而且处理过程时间为1.21ms):
具体实现的伪代码:
#include "main.h"
#include <math.h>
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
int main(int args, char** argv) {
Mat src, dst;
src = imread("D:/OpenCV/lena512color.tif");
if (!src.data)
{
printf("could not output image...\n");
return -1;
}
namedWindow("Hello,Lena!", CV_WINDOW_AUTOSIZE);
imshow("Hello,Lena!", src);
double startT = getTickCount();
dst = Mat::zeros(src.size(), src.type());
int cols = (src.cols - 1)*src.channels();
int rows = src.rows;
int offsetx = src.channels();
for (int row = 1; row < rows; row++) {
const uchar* perivou = src.ptr(row-1);
const uchar* current = src.ptr(row);
const uchar* next = src.ptr(row+1);
uchar* data = dst.ptr(row);
for (int col = offsetx; col < cols; col++) {
data[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offsetx] + current[col + offsetx] + perivou[col] + next[col]));
}
}
/*Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(src, dst, src.depth(), kernel);
*/
double endT = (getTickCount() - startT) / getTickFrequency();
printf("image process speed: %.2f ms.\n", endT * 1000);
namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
imshow("Output Image", dst);
waitKey(0);
return 0;
}
2. OpenCV API的矩阵掩膜处理过程
具体效果图(效果和上面基本一样,貌似更快了1.02ms):
具体伪代码:
int main(int args, char** argv) {
Mat src, dst;
src = imread("D:/OpenCV/lena512color.tif");
if (!src.data)
{
printf("could not output image...\n");
return -1;
}
namedWindow("Hello,Lena!", CV_WINDOW_AUTOSIZE);
imshow("Hello,Lena!", src);
double startT = getTickCount();
/*
//dst = Mat::zeros(src.size(), src.type());
//int cols = (src.cols - 1)*src.channels();
//int rows = src.rows;
//int offsetx = src.channels();
//for (int row = 1; row < rows; row++) {
// const uchar* perivou = src.ptr(row-1);
// const uchar* current = src.ptr(row);
// const uchar* next = src.ptr(row+1);
// uchar* data = dst.ptr(row);
// for (int col = offsetx; col < cols; col++) {
// data[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offsetx] + current[col + offsetx] + perivou[col] + next[col]));
// }
//}
*/
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(src, dst, src.depth(), kernel);
double endT = (getTickCount() - startT) / getTickFrequency();
printf("image process speed: %.2f ms.\n", endT * 1000);
namedWindow("Output Image", CV_WINDOW_AUTOSIZE);
imshow("Output Image", dst);
waitKey(0);
return 0;
}
码代码真心累啊~!