理论
这里用到的掩膜,其实只是数学中卷积的概念的一个应用
上下左右4个像素值分别乘以-1,再加上中间像素值乘以5的值,最后得到的值再重新赋值给中间像素,这就是掩膜的一个例子
矩阵的掩膜操作比较简单,根据掩膜来重新计算每个像素的像素值,掩膜(mask)也被称为核(kernel)
相关API
CV_Assert(myImage.depth()==CV_8U); // 1.验证深度
Mat.ptr (int i=0); // 2.获取像素矩阵的指针,索引i表示第几行,从0开始
const uchar* pRowData = myImage.ptr(row); // 3.获取某行指针
pRowData[col]; // 4.获取某列指针
代码示例
Mat srcImageMat = cv::imread(...);
int nCols=(srcImageMat.cols-1)*srcImageMat.channels();
int nOffsetx=srcImageMat .channels();
int nRows=srcImageMat.rows;
Mat dstImageMat=Mat::zeros(srcImageMat.size(),srcImageMat.type());
for(int rowindex=1;rowindex<(nRows-1);rowindex++){
const uchar* pre=srcImageMat.ptr(rowindex-1);
const uchar* cur=srcImageMat.ptr(rowindex);
const uchar* next=srcImageMat.ptr(rowindex+1);
uchar* output=dstImageMat.ptr(rowindex);
for(int colindex=nOffsetx;colindex(5*cur[colindex]-(cur[colindex-nOffsetx]+cur[colindex+nOffsetx]+pre[colindex]+next[colindex]));
}
}
nameWindows("Test DstImage",CV_WINDOW_AUTOSIZE);
imshow("Test DstImage",dstImageMat);
// 上述代码中的saturate_cast(数值)这个东西的功能是保证其数值在0~255之内,超出部分会相应返回0或255
OpenCV现成的接口调用示例
// 这两步可以表示上边一堆代码的操作
Mat kernel=Mat_(3,3)<<0,-1,0,-1,5,-1,0,-1,0;
filter2D(srcImageMat,dstImageMat,srcImageMat.depth(),kernel);
计算时间消耗
double dOldTime = getTickCount();
Mat kernel=Mat_(3,3)<<0,-1,0,-1,5,-1,0,-1,0;
filter2D(srcImageMat,dstImageMat,srcImageMat.depth(),kernel);
double dTimeConsune = (getTickCount()-dOldTime)/getTickFrequency();
效果截图: