1、获取opencv图像(Mat)指针。
(1)、Mat.ptr<uchar>(int i=0) 获取像素矩阵的指针,索引i表示第几行,从0开始计行数。
(2)、获得当前行指针const uchar* current= myImage.ptr<uchar>(row )。
(3)、获取当前像素点Point(row, col)的像素值 Point(row, col) =current[col]。
2、因为像素的取值范围为0 ~ 255,opencv像素范围处理函数:saturate_cast<uchar>。
(1)、saturate_cast<uchar>(-100),返回0。
(2)、saturate_cast<uchar>(288),返回255。
(3)、saturate_cast<uchar>(100),返回100。
(4)、这个函数的功能就是确保RGB的值在范围0 ~ 255之间。
3、什么是图像掩膜操作?
(1)、图像的掩膜操作其实就是调整图像的对比,经过掩膜操作的图像的对比图会提高。
如图所示,红色是中心像素点,从上到下,从左到右对每个像素做同样的处理操作,得到最终结果就是对比度提高之后的输出图像matDst对象。
(2)、图像掩膜算法。
矩阵掩膜操作十分简单,根据掩膜来重新计算每个像素的像素值,掩膜单词mask,也被称为Kernel。通过掩膜操作会提高图像的对比度。算法如下:
I(i, j) = 5 * I(i, j) - [1 * I(i-1, j) + 1 * I(i+1, j) + 1 * I(i, j - 1) + 1 * I(i, j + 1) + 0 * I(i - 1, j - 1) + 0 * I(i + 1, j - 1) + 0 * I(i - 1, j + 1) + 0 * I(i + 1, j + 1)]
上面公式的 I(i, j) 表示中心红色像素的像素值,中心像素的像素等于它自身的像素值剩于掩膜矩阵的系数,减去它周围八个像素对应的像素值和系数的积。举例,某个像素点经过掩膜算法得到新数值,数据如下:
128 89 90
100 120 98
200 247 36
value = 5 * 240 + 0 * 128 + (-1) * 89 + 0 * 90 + (-1) * 100 + (-1) * 98 + 0 *(200) + (-1) * 247 + 0 * (36) = 66
所以中心红色像素值由120替换为66
4、opencv代码实现掩膜算法。
#include <iostream>
#include <math.h>
#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
//1. 加载图像
Mat matSrc = imread("./test.jpg");
if (!matSrc.data)
{
printf("could not load image...\n");
return -1;
}
//2. 显示图像
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", matSrc);
//3. 矩阵的掩膜操作,方法1手动遍历每个像素做掩膜
int cols = (matSrc.cols-1) * matSrc.channels();
int offsetx = matSrc.channels();
int rows = matSrc.rows;
Mat matDst = Mat::zeros(matSrc.size(), matSrc.type());
for (int row = 1; row < (rows - 1); row++)
{
const uchar* previous = matSrc.ptr<uchar>(row - 1); //指向上一行
const uchar* current = matSrc.ptr<uchar>(row); //指向中间行
const uchar* next = matSrc.ptr<uchar>(row + 1); //指向下一下行
uchar* output = matDst.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]));
}
}
//4. 矩阵的掩膜操作,方法2调用opencv的函数做掩膜
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0); //创建掩膜矩阵
filter2D(matSrc, matDst, matSrc.depth(), kernel); //做掩膜
//显示掩膜后的图像
namedWindow("contrast image demo", CV_WINDOW_AUTOSIZE);
imshow("contrast image demo", matDst);
waitKey(0);
return 0;
}
5、测试结果:
掩膜前图像:
掩膜后的图像: