1.掩膜(mask)概念

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

2.掩膜的作用

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

  • 提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0。
  • 屏蔽作用,用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。
  • 结构特征提取,用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征。
  • 特殊形状图像的制作
  • 掩膜是一种图像滤镜的模板,实用掩膜经常处理的是遥感图像。当提取道路或者河流,或者房屋时,通过一个N * N的矩阵来对图像进行像素过滤,然后将我们需要的地物或者标志突出显示出来。这个矩阵就是一种掩膜。
  • 在OpenCV的中,掩模操作是相对简单的。大致的意思是,通过一个掩模矩阵,重新计算图像中的每一个像素值。掩模矩阵控制了旧图像当前位置以及周围位置像素对新图像当前位置像素值的影响力度。用数学术语讲,即我们自定义一个权重表

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

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

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

Mat kern = (Mat_<char>(,) <<  , -,  ,
-, , -,
, -, );

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

4.像素范围处理saturate_cast <typename _Tp>()

  • saturate_cast <UCHAR>( - 100),返回0
  • saturate_cast <UCHAR>(288),返回255
  • saturate_cast <UCHAR>(100),返回100

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

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

(1)获取对象像素指针

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

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

------获得当前行指针const uchar * current= myImage.ptr<uchar>(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<uchar>(row - );//上一行
const uchar* current = src.ptr<uchar>(row);//获取row行的像素指针
const uchar* next = src.ptr<uchar>(row + );//下一行
uchar* outcurrent = dst.ptr<uchar>(row);//输出图像的当前行像素指针
for (int col = offsetx; col < (cols - offsetx); col++)//从第二列(按通道偏移计算)到倒数第二列
{
outcurrent[col] = saturate_cast<uchar>( * 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_<char>(, ) << , -, , -, , -, , -, );

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

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

源代码如下:

#include<opencv2\opencv.hpp>
#include<iostream> 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<uchar>(row - 1);//上一行
// const uchar* current = src.ptr<uchar>(row);//获取row行的像素指针
// const uchar* next = src.ptr<uchar>(row + 1);//下一行
// uchar* outcurrent = dst.ptr<uchar>(row);//输出图像的当前行像素指针
// for (int col = offsetx; col < (cols - offsetx); col++)//从第二列(按通道偏移计算)到倒数第二列
// {
// outcurrent[col] = saturate_cast<uchar>( 5 * current[col] - (current[col - offsetx] + current[col + offsetx] + previous[col] + next[col]));//分别对应中间,左右,右边,上面,下面;使用掩膜修改输出图像每一点的像素值,然后saturate_cast限制像素范围为0-255
// } //} //创建掩膜 3*3
Mat kernal = (Mat_<char>(, ) << , -, , -, , -, , -, );
//掩膜操作
filter2D(src, dst, src.depth(), kernal); //将修改完的输出图像在窗口展示出来
namedWindow("dst win", CV_WINDOW_AUTOSIZE);
imshow("dst win", dst); waitKey();
return ;
}

处理结果如下图:

跟我一起学opencv 第二课之图像的掩膜操作的更多相关文章

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

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

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

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

  3. opencv第二课 进行缩放图片~

    #include<stdio.h> #include<iostream> #include<opencv2\opencv.hpp> using namespace ...

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

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

  5. 从零开始学Kotlin第二课

    字符串模板 fun main(args:Array<String>){ //主函数main方法 println(diaryGenerater("天安门")); } // ...

  6. 小哈学Python第二课:Hello Word

    Python入门 1.Hello World 2.Hello World

  7. OpenCV第二课,嵌入MFC

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

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

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

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

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

随机推荐

  1. WinForm时间选择控件(DateTimePicker)如何选择(显示)时分秒

    C# Windows窗体应用中,用到时间选择控件DateTimePicker,发现不能选择时分秒,难道要自己写一个控件?! 答案是否定的,通过属性修改是可以选择时间的,DateTimePicker完全 ...

  2. log4j的配置与使用

    配置log4j的步骤如下: 1.导入jar包 如log4j-1.2.15.jar 2.在src下添加log4j.properties 使用时把下面内容中的注释去掉: //日志级别及位置 log4j.r ...

  3. volume_manager.go

    package ) type) ],,) ,)             vms.CanCreateVolume = false         } else {             vms.Can ...

  4. Java语言 链接Oracle数据库

    package com.tao.pojo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Pre ...

  5. python使用sqlmap API检测SQL注入

    0x00前言: 大家都知道sqlmap是非常强大的sql注入工具,最近发现他有个sqlmap API,上网查了一下.发现这是 sqlmap的微端.(可以叫做sqlmap在线检测sql注入= =) 0x ...

  6. CSRF攻击【转载】

     CSRF(cross-site request forgery )跨站请求伪造,攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,通 ...

  7. html select 标签设置默认选中

    方法有两种. 第一种通过<select>的属性来设置选中项,此方法可以在动态语言如php在后台根据需要控制输出结果. 1 2 3 4 5 < select  id =  " ...

  8. 一次搞懂 Generator 函数

    1.什么是 Generator 函数 在Javascript中,一个函数一旦开始执行,就会运行到最后或遇到return时结束,运行期间不会有其它代码能够打断它,也不能从外部再传入值到函数体内 而Gen ...

  9. python——对图像进行卷积操作,使用多个滤波器

    线性滤波可以说是图像处理最基本的方法,它可以允许我们对图像进行处理,产生很多不同的效果.做法很简单.首先,我们有一个二维的滤波器矩阵(有个高大上的名字叫卷积核)和一个要处理的二维图像.然后,对于图像的 ...

  10. [深度应用]·实战掌握Dlib人脸识别开发教程

    [深度应用]·实战掌握Dlib人脸识别开发教程 个人网站--> http://www.yansongsong.cn/ 项目GitHub地址--> https://github.com/xi ...