OpenCV:三、矩阵的掩膜操作
2020-08-17 本文已影响0人
马洪滔
前言
在上一章中以及描述了如何使用cv ::cvtColor将BGR图像转换为灰度图像并通过cv :: imshow 将其显示在窗口中。点击进入修改和保存图像
目标
本章中,将学习如何:
- 像素范围处理
- 获取图像像素指针
- 掩膜操作解释
掩膜操作定义
矩阵上的掩膜操作非常简单。这个想法是,我们根据掩膜Mask矩阵(也称为内核Kernel)重新计算图像中的每个像素值。该掩膜保存将调整相邻像素(和当前像素)对新像素值有多大影响的值。从数学的角度来看,我们用加权平均值与我们指定的值进行比较。通过掩膜操作实现图像对比度提高。

第一个符号是使用公式,而第二个是通过使用掩码的第一个压缩版本。通过将掩模矩阵的中心(在零值索引的大写表示)放在要计算的像素上,并使用叠加的矩阵值乘以像素值,并使用掩码。这是同样的事情,但是在大型矩阵的情况下,后一种符号更容易查看。
在OpenCV中我们通过cv :: filter2D函数来实现,或自己手写掩膜运算函数
源代码
#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
String imageName("../data/HappyFish.jpg");
Mat src = imread(imageName, IMREAD_UNCHANGED);
if (src.empty()) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
return -1;
}
int cols = (src.cols-1)*src.channels();
int rows = src.rows;
int offsetx = src.channels();
Mat dst;
dst = Mat(src.size(), src.type());
int64 t = getTickCount();
//代码进行掩膜运行时间为0.003s
for (int row = 1; row < rows - 1; row++)
{
const uchar* current = src.ptr<uchar>(row);
const uchar* previous = src.ptr<uchar>(row - 1);
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])); // 像素范围处理,确保RGB值得范围在0-255之间,小于0的值返回0,大于255的值返回255;
}
}
//调用opencvAPI 时间为0.02s
/*Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(src, dst, src.depth(), kernel);*/
namedWindow("input_win", WINDOW_AUTOSIZE);
imshow("input_win", src);
namedWindow("output_win", WINDOW_AUTOSIZE);
imshow("output_win", dst);
double timesonsume = (getTickCount() - t) / getTickFrequency();
printf("time consume %.5f", timesonsume);
waitKey(0); // Wait for a keystroke in the window
return 0;
}
说明
- 像素范围处理saturate_cast<uchar>
- saturate_cast<uchar>(-100),返回0;
- saturate_cast<uchar>(288),返回255;
- saturate_cast<uchar>(100),返回100;
- 这个函数的功能是确保RGB值的范围在0~255之间;
- 函数调用filter2D功能
- 定义掩膜: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等
- 统计代码运行时间getTickCount
#include<iostream>
#include <opencv2/opencv.hpp>
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
int main(){
double t = (double)getTickCount();//开始时间
for (int i = 0; i <= 1000; i++){}//可替换成其他代码
t = (double)getTickCount() - t;//代码运行时间=结束时间-开始时间
printf("execution time = %gms\n", t*1000 / getTickFrequency());//转换时间单位并输出代码运行时间
system("pause");//让dos界面停留
return 0;
}