目录
1、矩阵的掩膜操作 简介
2、获取图像像素指针
3、掩膜操作解释
4、代码演示
1、矩阵的掩膜操作 简介
在OpenCV中,矩阵的掩膜操作是一种通过使用一个二进制掩膜来选择性地修改或提取图像或矩阵的特定区域的方法。
掩膜是一个与原始图像或矩阵具有相同大小的二进制图像或矩阵,其中像素值为0表示对应位置的像素或元素将被忽略,而像素值为1表示对应位置的像素或元素将被保留或处理。
掩膜操作常用于图像处理中的滤波、图像增强、边缘检测等任务。
2、获取图像像素指针
(1)CV_Assert(myImage.depth() == CV_8U);
(2)Mat.ptr<uchar>(int i=0) 获取像素矩阵的指针,索引i表示第几行,从0开始计行数。
(3)获得当前行指针const uchar* current= myImage.ptr<uchar>(row );
(4)获取当前像素点P(row, col)的像素值 p(row, col) =current[col]
像素范围处理saturate_cast<uchar>
(1)saturate_cast<uchar>(-100),返回 0。
(2)saturate_cast<uchar>(288),返回255
(3)saturate_cast<uchar>(100),返回100
这个函数的功能是确保RGB值得范围在0~255之间
3、掩膜操作解释
(1)掩膜操作实现图像对比度调整(提高图像的对比度)
红色是中心像素,从上到下,从左到右对每个像素做同样的处理操作,得到最终结果就是对比度提高之后的输出图像Mat对象。
(2)矩阵的掩膜操作:
根据掩膜来重新计算每个像素的像素值,掩膜(mask也称为Kernel)
4、代码演示
(1)用简单掩膜算法:
#include<opencv2\opencv.hpp>
#include<iostream>int main(int argc, char** argv)
{Mat myImage = imread("test.jpg");CV_Assert(myImage.depth() == CV_8U);namedWindow("mask_demo", CV_WINDOW_AUTOSIZE);imshow("mask_demo", myImage);Mat resultImage;myImage.copyTo(resultImage);int nchannels = myImage.channels();int height = myImage.rows;int cols = myImage.cols;int width = myImage.cols * nchannels;for (int row = 1; row < height - 1; row++){const uchar* previous = myImage.ptr<uchar>(row - 1);const uchar* current = myImage.ptr<uchar>(row);const uchar* next = myImage.ptr<uchar>(row + 1);uchar* output = resultImage.ptr<uchar>(row);for (int col = nchannels; col < nchannels * (myImage.cols - 1); col++){*output = saturate_cast<uchar>(5 * current[col] - previous[col] - next[col] - current[col - nchannels] - current[col + nchannels]);output++;}}namedWindow("mask_result", CV_WINDOW_AUTOSIZE);imshow("mask_result", resultImage);waitKey(0);return 0;
}
(2)其实OpenCV已经把掩膜的相关算法封装起来,使用filter2D能实现一样的效果:
函数调用 filter2D 功能:
1、定义掩膜:Mat kernel = (Mat_<char>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
2、filter2D( src, dst, src.depth(), kernel );其中src与dst是Mat类型变量、src.depth表示位图深度,有32、24、8等。
#include<opencv2\opencv.hpp>
#include<iostream>int main(int argc, char** argv)
{Mat src, dst;src = imread("test.jpg");if (!src.data){printf("could not load image...\n");}namedWindow("input image", CV_WINDOW_AUTOSIZE);imshow("input image", src);double t = getTickCount();Mat kenel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);filter2D(src, dst, src.depth(), kenel);// 处理的时间double timeconsume = (getTickCount() - t) / getTickFrequency();printf("time consume %.2f\n", timeconsume);namedWindow("mask_result", CV_WINDOW_AUTOSIZE);imshow("mask_result", dst);waitKey(0);return 0;
}