03_Opencv图像的掩膜操作

03_Opencv图像的掩膜操作

一.获取图像的像素指针

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

  • 获取当前行指针

    const uchar* current = src.ptr<uchar>(row);
    
  • 获取当前像素点P(row,col)的像素值P(row,col)=current[col]

  • 像素值的范围处理:使用saturate_cast§函数保证RGB值的范围在0~255之间

    • saturate_cast(-80):返回0
    • saturate_cast(260):返回255
    • saturate_cast(90):返回90

二.图像的掩膜操作

  • 图像的掩膜操作是指使用掩膜矩阵从上到下,从左到右对图像的每个像素进行卷积,卷积后的结果重新组成的新结果即为掩膜操作后的图像

  • 图像的矩阵表示(其中i从1~rows-1,j从1~cols-1,掩膜矩阵为3x3矩阵)
    src=[I(i1,j1)I(i1,j)I(i1,j+1)I(i,j1)I(i,j)I(i,j+1)I(i+1,j1)I(i+1,j)I(i+1,j+1)]src= \left[ \begin{matrix} I(i-1, j-1) &amp; I(i-1, j) &amp; I(i-1, j+1)\\ I(i, j-1) &amp; I(i, j) &amp; I(i, j+1)\\ I(i+1, j-1) &amp; I(i+1, j) &amp; I(i+1, j+1) \end{matrix} \right]

  • 掩膜矩阵
    kernel=[010151010]kernel= \left[ \begin{matrix} 0 &amp; -1 &amp; 0\\ -1 &amp; 5 &amp; -1\\ 0 &amp; -1 &amp; 0 \end{matrix} \right]

  • 掩膜操作

    I(i,j) = 5*I(i,j) - [I(i-1, j) + I(i+1, j) + I(i, j-1) + I(i, j+1)]
    
  • 通过掩膜操作可以提高图像对比度

三.通过调用filter2D函数实现图像掩膜操作

  • 定义掩膜:

    Mat kernel = 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等

四.示例

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;
int main(int argc, const char * argv[]) {
    
    Mat src,dst1,dst2;
    src = imread("/Users/zhixingao/Downloads/android/OpencvForCPlus/素材/莱娜.png");
    
    if(!src.data) {
        printf("could not load image...\n");
        return -1;
    }
    
    namedWindow("input image", CV_WINDOW_AUTOSIZE);
    imshow("input image", src);
    
    //通过获取图像像素指针实现图像掩膜操作
    //1.获取图像通道数
    int channels = src.channels();
    //2.获取图像宽度
    int cols = src.cols * channels;
    //3.获取图像高度
    int rows = src.rows;
    //4.获取图像像素指针实现图像掩膜操作
    dst1 = 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 = dst1.ptr<uchar>(row);
        for(int col = channels; col < cols - channels; col++) {
            output[col] = saturate_cast<uchar>(5*current[col] - (previous[col] + next[col] + current[col-channels] + current[col+channels]));
        }
    }
    
    if(!dst1.data) {
        printf("could not load image...\n");
        return -1;
    }
    namedWindow("output image1", CV_WINDOW_AUTOSIZE);
    imshow("output image1", dst1);

    
    //通过调用filter2D实现图像掩膜操作
    //1.定义掩膜
    Mat kernel = (Mat_<char>(3,3)<<0,-1,0,-1,5,-1,0,-1,0);
    //2.调用filter2D实现图像掩膜操作
    filter2D(src, dst2, src.depth(), kernel);
    
    if(!dst2.data) {
        printf("could not load image...\n");
        return -1;
    }
    namedWindow("output image2", CV_WINDOW_AUTOSIZE);
    imshow("output image2", dst2);
    
    waitKey(0);
    
    return 0;
}

五.结果

03_Opencv图像的掩膜操作
图中input image窗口为原始输入图像,output image1窗口为通过获取图像像素指针实现图像掩膜操作的结果,image2窗口为通过调用filter2D实现图像掩膜操作的结果