OpenCV 矩阵的掩膜操作

简介: OpenCV 矩阵的掩膜操作

掩膜操作


什么是掩膜操作?


掩膜操作是指根据掩膜矩阵(也称作核kernel)重新计算图像中每个像素的值。掩膜矩阵中的值表示了邻近像素值(包括该像素自身的值)对新像素值有多大的影响。从数学的观点来看,我们用自己设置的权值,对像素领域内的值做了个加权平均。


比如,下面这个公式表示用5倍当前像素的值减去该像素上、下、左、右四个像素值和,得到的结果赋值给当前像素。使用该公式可以用于提升图像的对比度。调节I(i,j)的系数权重可以得到不同的对比度提升效果。



上面的公式可以用掩膜矩阵表示成如下的形式。



掩膜操作可以实现图像对比度的调整,使得图像可以锐化,提高图像对比度。


掩膜操作实现图像对比度调整


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



下面我们继续探究,如果要想进行掩膜操作,就要先获取图像像素指针和进行像素范围处理


如何获取图像像素指针?


CV_Assert(myImage.depth() == CV_8U);


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


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


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


如何像素范围处理?


什么是像素范围处理?


我们在设置图像像素的灰度值或者RGB值时候,如果不了解,会随意设置,以RGB为例,他们的取值范围是从0 到255,所以如果我们输入范围以外的数据,为防止程序出错,我们需要控制范围,保证我们输入非法数据时候,不会导致程序出现问题。


处理的原则如下:


如果我们输入小于0的值,它会返回0,
如果我们输入大于255的值,它会返回255,
如果我们输入0-255之间的值,它会正常返回。


那么我们用的时候怎么进行处理呢?


这里就要用到像素范围处理函数saturate_cast<uchar>


像素范围处理API——saturate_cast<uchar>


saturate_cast<uchar>(-100),返回 0。
saturate_cast<uchar>(288),返回255
saturate_cast<uchar>(100),返回100


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


掩膜操作的API——filter2D


掩膜操作的API是filter2D,函数原型是:


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


参数:


  1. InputArray类型的src ,输入图像。


  1. OutputArray类型的dst ,输出图像,图像的大小、通道数和输入图像相同。


  1. int类型的ddepth,目标图像的所需深度。


  1. InputArray类型的kernel,卷积核(或者更确切地说是相关核)是一种单通道浮点矩阵;如果要将不同的核应用于不同的通道,请使用split将图像分割成不同的颜色平面,并分别对其进行处理。。


  1. Point类型的anchor,表示锚点(即被平滑的那个点),注意他有默认值Point(-1,-1)。如果这个点坐标是负值的话,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。。


  1. double类型的delta,在将筛选的像素存储到dst中之前添加到这些像素的可选值。说的有点专业了其实就是给所选的像素值添加一个值delta。


  1. int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT。


使用步骤


定义掩膜: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等。


例如:


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


掩膜操作案例



#include <iostream>
#include <math.h>
#include <opencv2/opencv.hpp>
#include<opencv2/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>  
using namespace cv;
int main(int argc, char** argv) {
  Mat src, dst;
  src = imread("test2.jpg");
  if (!src.data) {
    printf("could not load image...\n");
    return -1;
  }
  namedWindow("input image", CV_WINDOW_AUTOSIZE);
  imshow("input image", src);
  // 矩阵计算 掩膜操作
  int cols = (src.cols - 1) * src.channels();
  int offsetx = src.channels();
  int rows = src.rows;
  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 < cols; col++) {
      output[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offsetx] + current[col + offsetx] + previous[col] + next[col]));
    }
  }
  namedWindow("contrast image demo", CV_WINDOW_AUTOSIZE);
  imshow("contrast image demo", dst);
  // 使用 掩膜操作API
  Mat dst2;
  double t = getTickCount();
  Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
  filter2D(src, dst2, src.depth(), kernel);
  double timeconsume = (getTickCount() - t) / getTickFrequency();
  printf("tim consume %.2f\n", timeconsume);
  namedWindow("filter2D contrast image demo", CV_WINDOW_AUTOSIZE);
  imshow("filter2D contrast image demo", dst2);
  waitKey(0);
  return 0;
}
相关文章
|
6月前
|
计算机视觉 Python 索引
【Python Opencv】图片与视频的操作
【Python Opencv】图片与视频的操作
189 0
【Python Opencv】图片与视频的操作
|
5月前
|
计算机视觉
OpenCV中图像算术操作与逻辑操作
OpenCV中图像算术操作与逻辑操作
68 1
|
5月前
|
存储 Cloud Native Linux
OpenCV鼠标操作(画红色方框截取图像)
OpenCV鼠标操作(画红色方框截取图像)
|
5月前
|
计算机视觉
OpenCV图像像素逻辑操作
OpenCV图像像素逻辑操作
|
5月前
|
算法 计算机视觉
【Qt&OpenCV 图像阈值操作 threshold】
【Qt&OpenCV 图像阈值操作 threshold】
60 0
|
6月前
|
计算机视觉
OpenCV(三十一):形态学操作
OpenCV(三十一):形态学操作
106 0
|
6月前
|
监控 API 计算机视觉
OpenCV这么简单为啥不学——1.7、实现OpenCV自带的七种形态学转换操作
OpenCV这么简单为啥不学——1.7、实现OpenCV自带的七种形态学转换操作
50 0
|
6月前
|
存储 定位技术 计算机视觉
Armadillo与OpenCV矩阵数据mat、vec与Mat的相互转换
Armadillo与OpenCV矩阵数据mat、vec与Mat的相互转换
|
6月前
|
机器学习/深度学习 算法 计算机视觉
python入门(六) opencv的安装,图片操作,绘制文字图形,视频操作
python入门(六) opencv的安装,图片操作,绘制文字图形,视频操作
105 0
|
6月前
|
编解码 计算机视觉 Python
OpenCV保存摄像头视频和视频文件操作实战(附Python源码)
OpenCV保存摄像头视频和视频文件操作实战(附Python源码)
621 0