由于opencv源码本身关于均值滤波、高斯滤波等都时调用opencv自带的滤波引擎实现,无法看到他到底怎么实现的滤波功能。但我们知道他的滤波原理,接下来我们自己写一个c++代码实现他的滤波功能(本代码可以虽然是均值滤波,但可以通过修改模板,及相应参数实现其他滤波功能,有兴趣的可以自己研究。),由于是3X3的模板效果不是很明显。
#include<iostream>
#include<opencv2\opencv.hpp>
#include<opencv2\core\core.hpp>
//均值模板
int TemplateSmoothAvg[9] = { 1, 1, 1,
1, 1, 1,
1, 1, 1 };
/****************************************
srcImg-输入图像(灰度图像)
nTempH-模板的高度
nTempW-模板的宽度
nTempMY与nTempMX-中心的坐标
fCoef-模板系数
****************************************/
void Template(const cv::Mat srcImg, cv::Mat& resultImg, int nTempH, int nTempW, int nTempMY, int nTempMX, int* fpArray, float fCoef)
{
if (srcImg.empty())
{
return ;
}
srcImg.copyTo(resultImg);
int i, j;
//扫描图像进行模板操作
for (i = nTempMY; i < resultImg.rows - (nTempH - nTempMY) + 1; i++)
{
for (j = nTempMX; j <resultImg.cols - (nTempW - nTempMX) + 1; j++)
{
int fResult = 0;
for (int k = 0; k < nTempH; k++)
{
for (int l = 0; l < nTempW; l++)
{
fResult += srcImg.at<uchar>(i + k - nTempMY, j + l - nTempMX)*fpArray[k*nTempW + l];
}
}
fResult *= fCoef;
if (fResult>255)
{
fResult = 255;
}
if (fResult <= 0)
{
fResult = 0;
}
resultImg.at<uchar>(i, j) = fResult;
}
}
}
int main()
{
cv::Mat testImg = cv::imread("test1.jpg");
cv::Mat grayImg;
cv::cvtColor(testImg, grayImg, CV_BGR2GRAY);
cv::imshow("原始图像", grayImg);
cv::Mat resultImg;
Template(grayImg, resultImg, 3, 3, 1, 1, TemplateSmoothAvg, (float)1 / 9);
cv::imshow("my均值滤波", resultImg);
cv::waitKey(0);
return 0;
}
原始图像:
均值滤波后: