OpenCV学习笔记4 OpenCV核心模块与核心功能Core Module & Core Functionality(三)

2.3 矩阵上的掩码操作

矩阵掩码操作的两种方法: 基本方法 filter2D() 函数

基本方法:
void Sharpen(const Mat& myImage,Mat& Result)
{
    CV_Assert(myImage.depth() == CV_8U);  // 仅接受uchar图像

    Result.create(myImage.size(),myImage.type()); <span style="white-space:pre">	</span>// 创建一个与输入图像大小和类型相同的输出图像
    const int nChannels = myImage.channels();<span style="white-space:pre">		</span>// 输出图像通道数相同与输入图像相同

    for(int j = 1 ; j < myImage.rows-1; ++j)<span style="white-space:pre">		</span>// 对非边界的像素点进行运算
    {
        const uchar* previous = myImage.ptr<uchar>(j - 1);<span style="white-space:pre">	</span>// 因为需要同时访问多行像素(3×3的掩码矩阵需要访问3行像素),所以获取
        const uchar* current  = myImage.ptr<uchar>(j    );<span style="white-space:pre">	</span>// 中心像素所在行及其上下各一行的像素的指针,后面使用 [ ] 运算符访问
        const uchar* next     = myImage.ptr<uchar>(j + 1);<span style="white-space:pre">	</span>// 目标像素

        uchar* output = Result.ptr<uchar>(j);

        for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i)<span style="white-space:pre">	</span>// 利用上下左右四个邻接像素计算新的中心像素值
        {
            *output++ = saturate_cast<uchar>(5*current[i]
                         -current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]);
        }
    }

    Result.row(0).setTo(Scalar(0));<span style="white-space:pre">			</span>// 处于四个边界的像素点直接置0
    Result.row(Result.rows-1).setTo(Scalar(0));
    Result.col(0).setTo(Scalar(0));
    Result.col(Result.cols-1).setTo(Scalar(0));
}

filter2D函数:
滤波器在图像处理中应用非常广泛,OpenCV提供了滤波器掩码函数(也称为核)。使用该函数前需要先定义一个表示掩码的 Mat 对象:
Mat kern = (Mat_<char>(3,3) <<  0, -1,  0,
                               -1,  5, -1,
                                0, -1,  0);
然后调用 filter2D() 函数,参数包括输入图像,输出图像,输入图像的矩阵数据类型和核:
filter2D(I, K, I.depth(), kern );
它还有第五个可选参数——指定核的中心,第六个可选参数——指定函数在未定义区域(边界)的行为。

2.4 使用OpenCV对两幅图像求和(混合)

代码和注解说明问题。
实现两幅相同尺寸图像的透明叠加效果。
#include <cv.h>
#include <highgui.h>
#include <iostream>

using namespace cv;

int main( int argc, char** argv )
{
 double alpha = 0.5; double beta; double input;

 Mat src1, src2, dst;

 /// Ask the user enter alpha
 std::cout<<" Simple Linear Blender "<<std::endl;
 std::cout<<"-----------------------"<<std::endl;
 std::cout<<"* Enter alpha [0-1]: ";
 std::cin>>input;

 /// We use the alpha provided by the user iff it is between 0 and 1
 if( alpha >= 0 && alpha <= 1 )
   { alpha = input; }

 /// Read image ( same size, same type )
 src1 = imread("cat.jpg");
 src2 = imread("dog.jpg");

 if( !src1.data ) { printf("Error loading src1 \n"); return -1; }
 if( !src2.data ) { printf("Error loading src2 \n"); return -1; }

 /// Create Windows
 namedWindow("Linear Blend", 1);

 beta = ( 1.0 - alpha );
 addWeighted( src1, alpha, src2, beta, 0.0, dst);

 imshow( "Linear Blend", dst );

 waitKey(0);
 return 0;
}
addWeighted() 函数产生的结果:
dis = α * src1 + β * src2 + γ 。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值