学习OpenCV范例(三)——矩阵的掩码操作
来源:互联网 发布:阿里云异地登录 编辑:程序博客网 时间:2024/05/01 05:24
矩阵的掩码操作在图形图像上面来说就是矩阵的卷积运算,使像素点与周围临近的像素点关联起来,可以进行中值滤波,均值滤波,锐化,等等功能,具体想达到怎样的一个功能效果,在OpenCV的其他函数中都有给出,也可以自己给定算子,得到属于自己的滤波器,下面就看看范例的介绍吧。
1、矩阵的掩码操作
矩阵的掩码操作很简单。其思想是:根据掩码矩阵(也称作核)重新计算图像中每个像素的值。掩码矩阵中的值表示近邻像素值(包括该像素自身的值)对新像素值有多大影响。从数学观点看,我们用自己设置的权值,对像素邻域内的值做了个加权平均。
2、测试用例
思考一下图像对比度增强的问题。我们可以对图像的每个像素应用下面的公式:
上面那种表达法是公式的形式,而下面那种是以掩码矩阵表示的紧凑形式。使用掩码矩阵的时候,我们先把矩阵中心的元素(上面的例子中是(0,0)位置的元素,也就是5)对齐到要计算的目标像素上,再把邻域像素值和相应的矩阵元素值的乘积加起来。虽然这两种形式是完全等价的,但在大矩阵情况下,下面的形式看起来会清楚得多。
现在,我们来看看实现掩码操作的两种方法。一种方法是用基本的像素访问方法,另一种方法是用 filter2D 函数。
3、函数实现
#include "stdafx.h"#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <iostream>using namespace std;using namespace cv;static void help(){cout << endl<< "This program shows how to filter images with mask: the write it yourself and the"<< "filter2d way. " << endl<< "Usage:" << endl<< " [image_name -- default lena.jpg] [G -- grayscale] " << endl << endl;}void Sharpen(const Mat& myImage,Mat& Result);int main( int argc, char* argv[]){help();const char* filename = "Lena.jpg";Mat I, J, K;printf("GRAUSCAL OR COLOR? please enter G/C");char ch=getchar();if (ch=='G')I = imread( filename, CV_LOAD_IMAGE_GRAYSCALE);elseI = imread( filename, CV_LOAD_IMAGE_COLOR);printf("%s\n",filename);namedWindow("Input", WINDOW_AUTOSIZE);namedWindow("Output", WINDOW_AUTOSIZE);imshow("Input", I);double t = (double)getTickCount();Sharpen(I, J);//实现掩码操作t = ((double)getTickCount() - t)/getTickFrequency();cout << "Hand written function times passed in seconds: " << t << endl;imshow("Output", J);waitKey(0);Mat kern = (Mat_<char>(3,3) << 0, -1, 0,-1, 5, -1,0, -1, 0);t = (double)getTickCount();filter2D(I, K, I.depth(), kern );//使用滤波器掩码函数t = ((double)getTickCount() - t)/getTickFrequency();cout << "Built-in filter2D time passed in seconds: " << t << endl;imshow("Output", K);waitKey(0);return 0;}void Sharpen(const Mat& myImage,Mat& Result){CV_Assert(myImage.depth() == CV_8U); // 只接受unchar类型图片//根据图像的通道数,我们有一个或多个子列。我们用指针在每一个通道上迭代,因此通道数就决定了需计算的元素总数。const int nChannels = myImage.channels();Result.create(myImage.size(),myImage.type());//创建了一个与输入有着相同大小和类型的输出图像。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]);}}//在图像的边界上,我们未对其做任何掩码操作,所以都赋值为0Result.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));}
4、运行结果
图1、原图像 图2、Sharpen图像 图3、Filter2D图像
图4、运行时间对比
5、结论
在实现掩码操作的过程中,我们可以自己手动编写函数,也可以调用OpenCV提供的函数如Filter2D来实现,但从两者的运行时间上看,OpenCV提供的函数效率高一些,主要是OpenCV对提供的函数进行了优化。所以没有特殊的情况,直接调用提供的函数就可以啦。
6、使用的类和函数
CV_Assert:
功能:检查运行时的条件,如果条件不成立则抛出异常
结构:
CV_Assert(expr None)None:检查的条件
filter2D:
功能:对一副图像进行卷积运算
结构:
void filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT )src:输入的图片
dst:输出和src一样的size和channel的图片
ddepth:原图像的深度,src.depth
kernel:卷积核,是一个单通道浮点型的矩阵,如果你想使用不同的核在不同的通道,那么可以使用函数Split()将通道分离,再逐个使用核运算
anchor:核的中心,默认在核的中点处
delta:不知
borderType:不知
这个函数实现的其实是相关运算,如果要进行卷积运算,则将利用flip()函数将卷积核反转一下再进行运算就行了,还有一些资料说卷积核大小不能大于11*11,这个我也不清楚,希望知道的大神们,可以给点意见,如果有错误的地方也希望大家改正过来。
- 学习OpenCV范例(三)——矩阵的掩码操作
- 学习OpenCV(三)用filter2D实现矩阵掩码操作
- 学习OpenCV(三)用filter2D实现矩阵掩码操作
- OpenCV学习笔记:矩阵的掩码操作
- OpenCV学习:矩阵的掩码操作
- OpenCV学习之四: 矩阵的掩码操作
- OpenCV实践(2)- 矩阵的掩码操作
- 7.OpenCv矩阵的掩码操作
- Opencv之矩阵的掩码操作
- Opencv之矩阵的掩码操作
- 矩阵的掩码操作
- 矩阵的掩码操作
- 矩阵的掩码操作
- opencv c++函数 基础3 矩阵的掩码操作
- 理解矩阵的掩码操作 使用opencv锐化图片
- opencv(C++)在矩阵上进行掩码操作
- opencv:图像的掩码操作
- 从零开始 OpenCV (三) —— 矩阵/图像的基本操作
- C语言测试错题解析
- 献给想创业或者正在创业的伙伴
- 【VC编程技巧】窗体☞3.3利用CPropertySheet制作向导(或安装程序)
- java的服务器空间
- loadView、viewDidLoad及viewDidUnload的关系
- 学习OpenCV范例(三)——矩阵的掩码操作
- OV2640帧率的计算
- python内置函数
- 告别合服的苦恼
- word2013 论文引用参考文献
- 关于签名后的apk的优化
- 阿里校招之类实例化的顺序
- 免费的文本编辑器 (copied)
- 点跟多边形的碰撞检测