opencv基础_2(图像的掩膜操作)

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、测试结果:

掩膜前图像:

掩膜后的图像:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mark-puls

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值