OpenCV Lesson 3 : Mask operations on matrices

矩阵上的掩码运算

Mask operations on matrices are quite simple. The idea is that we recalculate each pixel's value in an image according to a mask matrix (also known as kernel). This mask holds values that will adjust how much influence neighboring pixels (and the current pixel) have on the new pixel value. From a mathematical point of view we make a weighted average, with our specified values.

矩阵上的掩模运算非常简单。这个想法是我们根据掩模矩阵(也称为内核)重新计算图像中每个像素的值。该掩码保存的值将调整相邻像素(和当前像素)对新像素值的影响程度。从数学的角度来看,我们使用指定的值进行加权平均值。

Let's consider the issue of an image contrast enhancement method.

让我们考虑图像对比度增强方法的问题。

I ( i , j ) = 5 ∗ I ( i , j ) − [ I ( i − 1 , j ) + I ( i + 1 , j ) + I ( i , j − 1 ) + I ( i , j + 1 ) ] I(i,j) = 5 * I(i,j) - [I(i-1, j) + I(i+1, j)+I(i,j-1)+I(i,j+1)] I(i,j)=5∗I(i,j)−[I(i−1,j)+I(i+1,j)+I(i,j−1)+I(i,j+1)]

⟺    I ( i , j ) ∗ M , w h e r e M = i / j − 1 0 + 1 − 1 0 − 1 0 0 − 1 5 − 1 + 1 0 − 1 0 \iff I(i,j)*M, where M = \begin{matrix} {i \ / j} & -1 & 0 & +1 \\ -1 & 0 & -1 & 0 \\ 0 & -1 & 5 & -1 \\ +1 & 0 & -1 & 0 \end{matrix} ⟺I(i,j)∗M,whereM=i /j−10+1−10−100−15−1+10−10

The first notation is by using a formula, while the second is a compacted version of the first by using a mask. You use the mask by putting the center of the mask matrix (in the upper case noted by the zero-zero index) on the pixel you want to calculate and sum up the pixel values multiplied with the overlapped matrix values. It's the same thing, however in case of large matrices the latter notation is a lot easier to look over.

第一个表示法是使用公式,而第二个表示法是使用掩码的第一个表示法的压缩版本。您可以通过将掩码矩阵的中心(以零零索引表示的大写字母)放在要计算的像素上来使用掩码,并将像素值与重叠矩阵值相乘求和。这是同样的事情,但是在大型矩阵的情况下,后一种表示法更容易查看。

Built-in filter2D

First, we load one image

bash 复制代码
cv::Mat dst0, dst1;
cv::Mat src = imread( "Lena.png", IMREAD_GRAYSCALE);

Then, we need a kernel

bash 复制代码
    Mat kernel = (Mat_<char>(3,3) <<  0, -1,  0,
                                   -1,  5, -1,
                                    0, -1,  0);

Finally, do filter2D

bash 复制代码
filter2D( src, dst1, src.depth(), kernel );

Hand written

bash 复制代码
void Sharpen(const Mat& myImage,Mat& Result)
{
    CV_Assert(myImage.depth() == CV_8U);  // accept only uchar images
 
    const int nChannels = myImage.channels();
    Result.create(myImage.size(),myImage.type());
 
    for(int j = 1 ; j < myImage.rows-1; ++j)
    {
        const uchar* previous = myImage.ptr<uchar>(j - 1);
        const uchar* current  = myImage.ptr<uchar>(j    );
        const uchar* next     = myImage.ptr<uchar>(j + 1);
 
        uchar* output = Result.ptr<uchar>(j);
 
        for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i)
        {
            output[i] = saturate_cast<uchar>(5*current[i]
                         -current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]);
        }
    }
 
    Result.row(0).setTo(Scalar(0));
    Result.row(Result.rows-1).setTo(Scalar(0));
    Result.col(0).setTo(Scalar(0));
    Result.col(Result.cols-1).setTo(Scalar(0));
}

Use getTickCount(), and getTickFrequency() get the time passed

bash 复制代码
t = ((double)getTickCount() - t)/getTickFrequency();
相关推荐
西西弗Sisyphus3 分钟前
如果让计算机理解人类语言- Word2Vec(Word to Vector,2013)
人工智能·word·word2vec
前端双越老师27 分钟前
30 行代码 langChain.js 开发你的第一个 Agent
人工智能·node.js·agent
东坡肘子43 分钟前
高温与奇怪的天象 | 肘子的 Swift 周报 #092
人工智能·swiftui·swift
KaneLogger1 小时前
视频转文字,别再反复拖进度条了
前端·javascript·人工智能
度假的小鱼1 小时前
从 “人工编码“ 到 “AI 协同“:大模型如何重塑软件开发的效率与范式
人工智能
zm-v-159304339862 小时前
ArcGIS 水文分析升级:基于深度学习的流域洪水演进过程模拟
人工智能·深度学习·arcgis
拓端研究室3 小时前
视频讲解|核密度估计朴素贝叶斯:业务数据分类—从理论到实践
人工智能·分类·数据挖掘
灵智工坊LingzhiAI3 小时前
人体坐姿检测系统项目教程(YOLO11+PyTorch+可视化)
人工智能·pytorch·python
昨日之日20063 小时前
Video Background Remover V3版 - AI视频一键抠像/视频换背景 支持50系显卡 一键整合包下载
人工智能·音视频
SHIPKING3934 小时前
【机器学习&深度学习】什么是下游任务模型?
人工智能·深度学习·机器学习