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));
}
滤波器在图像处理中应用非常广泛,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 + γ 。