二、矩阵的掩膜操作

一、获取图像像素指针

方法一、
主要用到的函数是

Mat.ptr<uchar>(int i = 0)

它的作用是得到图像矩阵的的开始地址,可以跟据图像的储存的关系:
单通道图像:

行列 column0 column1 columnn
row0 piexl(0,0) piexl(0,1) piexl(0,n)
row1 piexl(1,0) piexl(1,1) piexl(1,n)
rowm piexl(m,0) piexl(m,1) piexl(m,n)

RGB图像格式与上述相同,不过一个像素点由三个颜色分量表示。

//单通道图像为例:
const uchar * current = my_image.ptr<uchar>(row);//获取第row行地址指针
piexl_row_col = current[column];//得到第row行第column列像素的地址

//RGB图像操作:
//获取图像的Size与channel
int cols = src.cols * src.channels();
int offsetx = src.channels();
int rows = src.rows;

for (int row = 1; row < rows - 1; row++)
{
    //等到行和列的地址
    const uchar * previous = src.ptr<uchar>(row - 1);
    const uchar * carrent = 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>(carrent[col] * 5 - carrent[col - offsetx] - carrent[col + offsetx] - previous[col] - next[col]);
    }
}

RGB图像操作例子中有一个常用的函数:

saturate_cast<uchar>

这个函数的功能是确保像素值在uchar类型数据允许范围之内

  • saturate_cast(-100),函数返回0
  • saturate_cast(280),函数返回255
  • saturate_cast(100),函数返回100

二、掩膜操作

掩膜操作也可以成为卷积操作,就是把kernel(核)与图像卷积
如果把kernel定义为:

I(i,j)=5I(i,j)[I(i,j1)+I(i1,j)+I(i+1,j)+I(i,j+1)]

我们把该式对应像素点的系数写成矩阵形式:

010151010

这个算子的作用是提高图像对比度,如果把该算子换成Laplace算子

010141010
就成了边缘检测。

卷积操作API

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

用法:

//用opencv的API  filter2D
    Mat kernel = (Mat_<char>(3, 3) << 0, 1, 0, 1, -4, 1, 0, 1, 0);

    filter2D(src, dst, -1, kernel);//此处-1为万能参数,也可以用src.depth()来代替-1

All demo:

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

using namespace std;
using namespace cv;

int main(int argc, char ** argv)
{
    //读入图像
    Mat src, dst;
    src = imread("F:/Opencv/myimage/51CTO/4.jpg");
    //判断图像是否读取错误
    if (!src.data)
    {
        cout << "can not open the image ..." << endl;
        return -1;
    }
    //初始化结果图像
    dst = Mat::zeros(src.size(), src.type());
    double t = getTickCount();
    //掩膜操作
    //获取图像的Size与channel
    int cols = src.cols * src.channels();
    int offsetx = src.channels();
    int rows = src.rows;

    for (int row = 1; row < rows - 1; row++)
    {
        //等到行和列的地址
        const uchar * previous = src.ptr<uchar>(row - 1);
        const uchar * carrent = 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>(carrent[col] * 5 - carrent[col - offsetx] - carrent[col + offsetx] - previous[col] - next[col]);
        }
    }
    cout << "myself function cost time:" << (getTickCount() - t) / getTickFrequency() << endl;
    //display all image
    namedWindow("Myself function", CV_WINDOW_AUTOSIZE);
    imshow("Myself function", dst);

    namedWindow("source image", CV_WINDOW_AUTOSIZE);
    imshow("source image", src);

    t = getTickCount();

    //用opencv的API  filter2D
    Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);

    filter2D(src, dst, -1, kernel);//此处-1为万能参数,也可以用src.depth()来代替-1

    namedWindow("OpenCV API", CV_WINDOW_AUTOSIZE);
    imshow("OpenCV API", dst);

    cout << "OpenCV API: " << (getTickCount() - t) / getTickFrequency() << endl;

    waitKey(0);

    return 0;

}

ps:
本例中还有一个实用的函数
就是计算代码运行时间
传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值