OpenCV图像处理-矩阵掩模

  • 前言
  • 掩模操作的含义
  • 手动掩模
  • 自动掩模


前言

本文使用的环境为:Qt5.11 + OpenCV3.4.6
 

掩模操作的含义

首先把图像当作一个很大的矩阵,矩阵里的每一行和每一列均有一个数值。然而,我们可以通过对矩阵做处理,使得矩阵的对应的数据发生变化,这个处理过程可以理解为掩模。例如通过掩模操作把矩阵的某一行某一列的值清零,则对应的图像上的该像素点也同时置零。

图像掩模的主要作用如下:

  1. 提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0;
  2. 屏蔽作用,用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计;
  3. 结构特征提取,用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征;
  4. 特殊形状图像的制作。

手动掩模

  1. 获取像素指针
Mat.prt<uchar>(row)

作用:获取图像列的指针

输入参数

参数含义

row

图像的列

  1. 获取像素范围
static _Tp cv::saturate_castL<uchar  v>

作用:确保RGB值范围在0~255之间

输入参数

参数含义

v

当前RGB的值

  1. 手动掩模示例
    将图像通过以下矩阵进行掩模
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/opencv.hpp>
#include <QtDebug>

using namespace cv;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Mat dst;
    Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
    if(src.empty()){
        qDebug()<<"can not load image...\n";
        return ;
    }
    namedWindow("test_opencv setup",WINDOW_AUTOSIZE);
    imshow("test_opencv setup",src);
      //一个图像的列数应等于 整个图像的列数乘以这个图像每个像素的通道数
    int clos = (src.cols-1) * src.channels();
      //列的开始像素 
    int offsetx = src.channels();
      //行数
    int rows = src.rows;
      //创建与原图像相同大小的图像且全为0
    dst = Mat::zeros(src.size(),src.type());
    for(int row = 1 ; row < (rows -1) ; row++){
           //获取相对于当前像素指针向前偏移一列的指针
        const uchar* previous = src.ptr<uchar>(row-1);
            //获取目前像素指针
        const uchar* current = src.ptr<uchar>(row);
            //获取相对于当前像素指针向后偏移一列的指针
        const uchar* next = src.ptr<uchar>(row+1);
            //同步获得目标图像的当前像素位置指针
        uchar* output = dst.ptr<uchar>(row);
        for (int col = offsetx ; col < clos ; col++){
              //矩阵
              //0 -1 0
              //-1 5 -1
              //0 -1 0
              //掩模算法处理,且将值进行限定保证在0~255之间
            output[col] = saturate_cast<uchar>(5 *current[col] - (current[col-offsetx]+ current[col + offsetx] + previous[col] + next[col]));
        }
    }


    namedWindow("contrast image demo",WINDOW_AUTOSIZE);
    imshow("contrast image demo",dst);
    waitKey(0);
}

原图像

opencv 将 行向量转为列向量 opencv将矩阵显示为图像_矩阵

经过掩模后(锐化,提升对比度)

opencv 将 行向量转为列向量 opencv将矩阵显示为图像_矩阵_02

自动掩模

OpenCV也提供了API函数可以通过简单的调用来完成掩模的操作

void cv::filter2D 	( 
        InputArray  src,
		OutputArray  dst,
		int  ddepth,
		InputArray  kernel,
		Point  anchor = Point(-1,-1),
		double  delta = 0,
		int  borderType = BORDER_DEFAULT 
	)

作用:对源图像进行掩模,输出掩模后的图像

输入参数

参数含义

src

原图像

dst

输出图像,大小必须与原图像相同

ddepth

图像的深度 不填写或者-1则原图深度 一致

kernel

内核可理解为需要掩模的矩阵

anchor

内核的基准点,-1-1为中心点

delta

储存目标图像前可选的添加到像素的值 默认为0

borderType

像素向外逼近的方法

使用filter2D 对图像用矩阵进行掩模,矩阵如下:

opencv 将 行向量转为列向量 opencv将矩阵显示为图像_opencv 将 行向量转为列向量_03

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/opencv.hpp>
#include <QtDebug>

using namespace cv;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Mat dst;
    Mat src = imread("E:/OpenCV/OpenCVPicture/horse.png");
    if(src.empty()){
        qDebug()<<"can not load image...\n";
        return ;
    }
    namedWindow("test_opencv setup",WINDOW_AUTOSIZE);
    imshow("test_opencv setup",src);

    Mat kernel = (Mat_<char>(3,3) << 0,-1,0,-1,5,-1,0,-1,0);
    filter2D(src,dst,src.depth(),kernel);
    qDebug()<<"depth:"<<src.depth();
    namedWindow("contrast image demo",WINDOW_AUTOSIZE);
    imshow("contrast image demo",dst);
    waitKey(0);
}