c语言学mask作用,跟我一起学opencv 第二课之图像的掩膜操作

1.掩膜(mask)概念

用选定的图像,图形或物体,对处理的图像(全部或局部)进行遮挡,来控制图像处理的区域或处理过程。用于覆盖的特定图像或物体称为掩模或模板。光学图像处理中,掩模可以足胶片,滤光片等。掩模是由0和1组成的一个二进制图像。当在某一功能中应用掩模时,1值区域被处理,被屏蔽的0值区域不被包括在计算中。通过指定的数据值,数据范围,有限或无限值,感兴趣区和注释文件来定义图像掩模,也可以应用上述选项的任意组合作为输入来建立掩模。

2.掩膜的作用

数字图像处理中,掩模为二维矩阵数组,有时也用多值图像数字图像处理中,图像掩模主要用于:

提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0。

屏蔽作用,用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。

结构特征提取,用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征。

特殊形状图像的制作

掩膜是一种图像滤镜的模板,实用掩膜经常处理的是遥感图像。当提取道路或者河流,或者房屋时,通过一个N * N的矩阵来对图像进行像素过滤,然后将我们需要的地物或者标志突出显示出来。这个矩阵就是一种掩膜。

在OpenCV的中,掩模操作是相对简单的。大致的意思是,通过一个掩模矩阵,重新计算图像中的每一个像素值。掩模矩阵控制了旧图像当前位置以及周围位置像素对新图像当前位置像素值的影响力度。用数学术语讲,即我们自定义一个权重表

3.通过掩膜操作实现图像对比图的改变

矩阵的掩膜操作十分简单,根据掩膜来重新计算每个像素的像素值,掩膜(mask)也被称为内核。

通过掩膜操作实现图像对比度提高,公式如下

c语言学mask作用,跟我一起学opencv 第二课之图像的掩膜操作_第1张图片

Mat kern = (Mat_(,) << , -, ,

-, , -,

, -, );

红色是中心像素,从上到下,从左到右对每个像素做同样的处理操作,得到最终结果就是对比度提高之后的输出图像垫对象。

c语言学mask作用,跟我一起学opencv 第二课之图像的掩膜操作_第2张图片

4.像素范围处理saturate_cast ()

saturate_cast ( - 100),返回0

saturate_cast (288),返回255

saturate_cast (100),返回100

这个函数的功能是确保RGB值范围在0〜255之间。

5.自定义使用掩膜操作实现图像对比度的提高

(1)获取对象像素指针

------CV_Assert(myImage.depth())

------Mat.ptr(int i=0)获取像素矩阵的指针,索引i表示第几行,从0行开始计数

------获得当前行指针const uchar * current= myImage.ptr(row);

------获取当前像素点P(row,col)的像素值p(row,col)=current[col]

上源代码:

using namespace std;

using namespace cv;

int main(int argc, char **argv)

{

Mat src = imread("E:\\vsprom\\learn02\\nv1.jpg");

if (src.empty())

{

cout << "can not load imagefile...." << endl;

return -;

}

namedWindow("in image win", CV_WINDOW_AUTOSIZE);

imshow("in image win", src);

Mat dst;

dst = Mat::zeros(src.size(), src.type());//用原图像的尺寸和类型初始化目标图像并将所有像素值清零

int cols = src.cols * src.channels();//图像矩阵的宽度(列数)=原图像列数*图像的通道数,因为掩膜矩阵要在图像矩阵内,所以计算时要给列和行减1

int rows = src.rows;//图像的高度(行数)

int offsetx = src.channels();//掩膜计算偏移量等于图像通道数

for (int row = ; row < (rows - ); row++)//从第二行开始到倒数第二行结束

{

const uchar* previous = src.ptr(row - );//上一行

const uchar* current = src.ptr(row);//获取row行的像素指针

const uchar* next = src.ptr(row + );//下一行

uchar* outcurrent = dst.ptr(row);//输出图像的当前行像素指针

for (int col = offsetx; col < (cols - offsetx); col++)//从第二列(按通道偏移计算)到倒数第二列

{

outcurrent[col] = saturate_cast( * current[col] - (current[col - offsetx] + current[col + offsetx] + previous[col] + next[col]));//分别对应中间,左右,右边,上面,下面;使用掩膜修改输出图像每一点的像素值,然后saturate_cast限制像素范围为0-255

}

}

//将修改完的输出图像在窗口展示出来

namedWindow("out win", CV_WINDOW_AUTOSIZE);

imshow("out win", dst);

waitKey();

return ;

}

效果图:第一张为原图,第二张位对比度提高后的图

6.使用opencv 的API实现图像掩膜

1.定义一个3*3的掩膜如下

Mat kernal = (Mat_(, ) << , -, , -, , -, , -, );

2.使用opencv函数进行掩膜操作

filter2D(src, dst, src.depth(), kernal);

源代码如下:

#include

#include

using namespace std;

using namespace cv;

int main(int argc, char **argv)

{

Mat src = imread("E:\\vsprom\\learn02\\nv1.jpg");

if (src.empty())

{

cout << "can not load imagefile...." << endl;

return -;

}

namedWindow("in image win", CV_WINDOW_AUTOSIZE);

imshow("in image win", src);

Mat dst;

//dst = Mat::zeros(src.size(), src.type());//用原图像的尺寸和类型初始化目标图像并将所有像素值清零

//int cols = src.cols * src.channels();//图像矩阵的宽度(列数)=原图像列数*图像的通道数,因为掩膜矩阵要在图像矩阵内,所以计算时要给列和行减1

//int rows = src.rows;//图像的高度(行数)

//int offsetx = src.channels();//掩膜计算偏移量等于图像通道数

//for (int row = 1; row < (rows - 1); row++)//从第二行开始到倒数第二行结束

//{

// const uchar* previous = src.ptr(row - 1);//上一行

// const uchar* current = src.ptr(row);//获取row行的像素指针

// const uchar* next = src.ptr(row + 1);//下一行

// uchar* outcurrent = dst.ptr(row);//输出图像的当前行像素指针

// for (int col = offsetx; col < (cols - offsetx); col++)//从第二列(按通道偏移计算)到倒数第二列

// {

// outcurrent[col] = saturate_cast( 5 * current[col] - (current[col - offsetx] + current[col + offsetx] + previous[col] + next[col]));//分别对应中间,左右,右边,上面,下面;使用掩膜修改输出图像每一点的像素值,然后saturate_cast限制像素范围为0-255

// }

//}

//创建掩膜 3*3

Mat kernal = (Mat_(, ) << , -, , -, , -, , -, );

//掩膜操作

filter2D(src, dst, src.depth(), kernal);

//将修改完的输出图像在窗口展示出来

namedWindow("dst win", CV_WINDOW_AUTOSIZE);

imshow("dst win", dst);

waitKey();

return ;

}

处理结果如下图:

c语言学mask作用,跟我一起学opencv 第二课之图像的掩膜操作_第3张图片

OpenCV 第二课 认识图像的存储结构

OpenCV 第二课 认识图像的存储结构 Mat Mat 类包含两部分,矩阵头和矩阵体.矩阵头包含矩阵的大小,存储方式和矩阵体存储空间的指针.因此,Mat中矩阵头的大小是固定的,矩阵体大小是不定的. ...

跟我一起学opencv 第一课之图像加载,修改,保存

使用opencv前记得引入库和头文件: #include 1.加载图像(cv::imread)(OPENCV 支持 JPG,PNG,TIFF等常见格 ...

opencv第二课 进行缩放图片~

#include #include #include using namespace ...

opencv第二课,使用cmake编译OpenCV,并添加opencv_contrib模块

一.下载安装cmake 想要在Windows平台下生成OpenCV的解决方案,我们需要一个名为cmake的开源软件,可以在camke的官网:http://www.cmake.org/上下载到 或者点击 ...

小哈学Python第二课:Hello Word

Python入门 1.Hello World 2.Hello World

OpenCV第二课,嵌入MFC

单纯显示图片,只需链接 opencv_core2411d.libopencv_highgui2411d.lib 1.首先创建一个MFC的dlg,添加Picture Control控件 void CCO ...

快学Scala 第二课 (apply, if表达式,循环,函数的带名参数,可变长参数,异常)

apply方法是Scala中十分常见的方法,你可以把这种用法当做是()操作符的重载形式. 像以上这样伴生对象的apply方法是Scala中构建对象的常用手法,不再需要使用new. if 条件表达式的值 ...

opencv学习笔记(五)----图像的形态学操作

图像的形态学操作有基本的腐蚀和膨胀操作和其余扩展形态学变换操作(高级操作)-----开运算,闭运算,礼帽(顶帽)操作,黑帽操作...(主要也是为了去噪声,改善图像) 形态学操作都是用于处理二值图像(其 ...

跟我一起学opencv 第四课之图像的基本操作

1.图像是由像素组成的,所以修改了像素就可以实现图像的改变. 2先看灰度图像(单通道): *****2.获取灰度图像的像素值使用:  int gray = gray_src.at

随机推荐

eclipse中maven install和build,clean

eclipse插件,m2eclipse 1.maven install相当于maven原生的命令: mvn install 2.aven build是 m2eclipse这个插件自己创造的概念,需要你 ...

C# Array

一.声明数组时,方括号[]必须跟在类型后面,而不是标识符后面 int[] table;  //而不是 int table[]; 二.数组的大小不是其类型的一部分 int[] numbers; numb ...

2659: [Beijing wc2012]算不出的算式 - BZOJ

最近有点颓废,刷水题,数学题(根本不会做啊) 题意:求 q,p是两个奇质数 网上题解就直接说是几何意义,问了别人才知道 我们在坐标轴上画出来就是在线段y=(q/p)x下方的格点和y=(p/q)x下方的 ...

JS全局变量VAR和THIS

(注意)JS全局变量VAR和THIS 很多人都觉得在javascript声明一个变量,加var和不加var没有什么区别,实际上是一个错误的观点,如果在函数外面,也就是说在window区域加不加var确 ...

堆排序 C++

1 堆排序拥有插入排序的优点 (是一种原地排序算法只需要存储常数个元素在输入数组以外 即省空间), 同时拥有合并排序算法的复杂度 nlgn,逼格有点高 2 堆数据结构 是一个数组对象,可以被视为一颗完 ...

Eclipse中安装git后pull远程仓库出现错误解决方法

该图中位置为false 在配置文件中添加如下语句 -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2

来啊踩fastjson打印入参导致业务跑偏的坑

线上代码对日志的记录,重要性自不必说.但是怎样记录日志也是有讲究的! 日志可以直接在每个方法中进行日志记录,优点是想怎么记就怎么记,缺点是记日志的代码可能会超过你的业务代码,可读性急剧下降,这也是日志 ...

Netty:option和childOption参数设置说明

Channel配置参数 (1).通用参数 CONNECT_TIMEOUT_MILLIS :   Netty参数,连接超时毫秒数,默认值30000毫秒即30秒. MAX_MESSAGES_PER_REA ...

vim中将小写替换为大写--快速解决变量名风格

将C语言的下划线分割快速替换为Java的驼峰方式. 命令如下 :%s/_\([a-zA-Z]\)/\U\1/g 参考文档

mysql执行计划常用说明

MYSQL执行计划顺序原则上是:在所有组中,id值越大,优先级越高,越先执行,id如果相同,可以认为是一组,从上往下顺序执行做执行计划之前,要了解下表统计信息情况:mysql.innodb_table ...

你可能感兴趣的:(c语言学mask作用)