这里是本人根据资料所写的均值滤波算子,可供参考,如有好的建议,可以指出。
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv.hpp>
#include <limits.h>
#include <iostream>
#include <ctime>
#include <limits>
#include <vector>
#include "opencv_Filter.h"
/*
功能:单通道常规均值滤波器算法
参数:
src:输入原图像
dst:输出图像
size:表示核大小
返回值:无
*/
void MeanFilter(cv::Mat &src, cv::Mat &dst, cv::Size wsize)
{
//图像的边缘扩充:窗口的半径
if (wsize.height % 2 == 0 || wsize.width % 2 == 0)//判断是否为奇数
{
fprintf(stderr, "Please enter odd size!");
exit(-1);
}
int hh = (wsize.height - 1) / 2;//半径
int ww = (wsize.width - 1) / 2;//半径
cv::Mat newSrc;
cv::copyMakeBorder(src, newSrc, hh, hh, ww, ww, cv::BORDER_REFLECT_101);//以边缘为轴,对称
//cv::imshow("test", newSrc);
dst = cv::Mat::zeros(src.size(), src.type());
//均值滤波
int sum = 0;//窗口像素值之和
int mean = 0;//均值
for (int i = hh; i < src.rows + hh; ++i)
{
for (int j = ww; j < src.cols + ww; ++j)
{
for (int r = i - hh; r <= i + hh; ++r)
{
for (int c = j - ww; c <= j + ww; ++c)
{
sum = newSrc.at<uchar>(r, c) + sum;
}
}
mean = sum / (wsize.area());
dst.at<uchar>(i - hh, j - ww) = mean;
sum = 0;
mean = 0;
}
}
//cv::imshow("test", dst);
}
void meanImage(cv::Mat &src, cv::Mat &dst, cv::Size wsize)
{
//初始化输出图像
dst = cv::Mat::zeros(src.size(),src.type());
//确保掩模宽高相等
if (wsize.height != wsize.width)
{
wsize.height = wsize.width;
}
//确保为奇数
if (wsize.height % 2 == 0 || wsize.width % 2 == 0)//判断是否为奇数
{
wsize.height = wsize.height + 1;
wsize.width = wsize.height;
}
//取窗口的半径
int hh = (wsize.height - 1) / 2;//半径
int ww = (wsize.width - 1) / 2;//半径
//扩充边缘
cv::Mat newSrc;
cv::copyMakeBorder(src, newSrc, hh, hh, ww, ww, cv::BORDER_REFLECT_101);//以边缘为轴,对称
//遍历除边界像素外的所有像素
int sum = 0;//区域像数值的和
for (int r = hh; r < src.rows + hh; r++) {
for (int c = ww; c < src.cols + ww; c++) {
//计算掩模覆盖的所有像素值的和
for (int i = r - hh; i <= r + hh; i++) {
for (int j = c - ww; j <= c + ww; j++) {
sum += newSrc.at<uchar>(i, j);
}
}
//求均值并赋值给相应位置的像素
dst.at<uchar>(r - hh, c - ww) = sum / wsize.area();
sum = 0;
}
}
}
/*
功能:单通道快速均值滤波(积分图快速均值滤波)
参数:
src:输入原图像
dst:生成目标图像
wsize:核大小
返回值:无
*/
void Fast_MeanFilter(cv::Mat &src, cv::Mat &dst, cv::Size wsize)
{
//图像边界扩充
//图像的边缘扩充:窗口的半径
if (wsize.height % 2 == 0 || wsize.width % 2 == 0)//判断是否为奇数
{
fprintf(stderr, "Please enter odd size!");
exit(-1);
}
int hh = (wsize.height - 1) / 2;//半径
int ww = (wsize.width - 1) / 2;//半径
cv::Mat newSrc;
cv::copyMakeBorder(src, newSrc, hh, hh, ww, ww, cv::BORDER_REFLECT_101);//以边缘为轴,对称
//cv::imshow("test", newSrc);
dst = cv::Mat::zeros(src.size(), src.type());
//imshow("test1", newSrc);
//计算积分图
cv::Mat inte;
//Im_integral(newSrc, inte);
Fast_integral(newSrc, inte);
//imshow("test2", inte);
//均值滤波
double mean = 0;
for (int i = hh + 1; i < src.rows + hh + 1; ++i)
{
for (int j = ww + 1; j < src.cols + ww + 1; ++j)
{
double top_left = inte.at<double>(i - hh - 1, j - ww - 1);
double top_right = inte.at<double>(i - hh - 1, j + ww);
double buttom_left = inte.at<double>(i + hh, j - ww - 1);
double buttom_right = inte.at<double>(i + hh, j + ww);
mean = (top_left + buttom_right - top_right - buttom_left) / wsize.area();
if (mean < 0)
{
mean = 0;
}
else if (mean > 255)
{
mean = 255;
}
dst.at<uchar>(i - hh - 1, j - ww - 1) = static_cast<uchar>(mean);
}
}
}
/*
功能:计算积分图 常规方法
参数:
src:原图像
dst:生成目标图像
返回值:无
*/
void Im_integral(cv::Mat &src, cv::Mat &dst)
{
int row = src.rows;
int column = src.cols;
//imshow("test3", src);
//dst = cv::Mat::zeros(src.size(), src.type());
//创建一个目标图像标准格式
dst = cv::Mat::zeros(row + 1, column + 1, CV_64F);
for (int i = 1; i < dst.rows; ++i)
{
for (int j = 1; j < dst.cols; ++j)
{
double top_left = dst.at<double>(i - 1, j - 1);
double top_right = dst.at<double>(i - 1, j);
double buttom_left = dst.at<double>(i, j - 1);
int buttom_right = src.at<uchar>(i - 1, j - 1);
dst.at<double>(i, j) = buttom_left + top_right - top_left + buttom_right;
}
}
//imshow("test4", dst);
}
/*
功能:计算积分图 快速方法
参数:
src:原图像
dst:生成目标图像
返回值:无
*/
void Fast_integral(cv::Mat &src, cv::Mat &dst)
{
int row = src.rows;
int column = src.cols;
//imshow("test3", src);
//dst = cv::Mat::zeros(src.size(), src.type());
//创建一个目标图像标准格式
dst = cv::Mat::zeros(row + 1, column + 1, CV_64F);
int sum = 0;
for (int i = 1; i < dst.rows; ++i)
{//列扫描
for (int j = 1,sum = 0; j < dst.cols; ++j)
{//行累加
sum += src.at<uchar>(i - 1, j - 1);
dst.at<double>(i, j) = dst.at<double>(i-1,j) + sum;
}
}
//imshow("test4", dst);
}
/*
功能:给图像添加椒盐噪声
参数:
src 输入原图像
n 椒盐噪声个数
返回值:
dstImage 返回椒盐结果图像
*/
Mat addSaltNoise(const Mat srcImage, int n)
{
Mat dstImage = srcImage.clone();
for (int k = 0; k < n; k++)
{
//随机取值行列
int i = rand() % dstImage.rows;
int j = rand() % dstImage.cols;
//图像通道判定
if (dstImage.channels() == 1)
{
dstImage.at<uchar>(i, j) = 255; //盐噪声
}
else
{
dstImage.at<Vec3b>(i, j)[0] = 255;
dstImage.at<Vec3b>(i, j)[1] = 255;
dstImage.at<Vec3b>(i, j)[2] = 255;
}
}
for (int k = 0; k < n; k++)
{
//随机取值行列
int i = rand() % dstImage.rows;
int j = rand() % dstImage.cols;
//图像通道判定
if (dstImage.channels() == 1)
{
dstImage.at<uchar>(i, j) = 0; //椒噪声
}
else
{
dstImage.at<Vec3b>(i, j)[0] = 0;
dstImage.at<Vec3b>(i, j)[1] = 0;
dstImage.at<Vec3b>(i, j)[2] = 0;
}
}
return dstImage;
}
/*
功能:多通道均值滤波 动态地址实现
参数:
返回值:
*/
void AverFiltering(const Mat& srcImage, Mat& dstImage)
{
if (!srcImage.data)
return;
dstImage.create(srcImage.size(), srcImage.type());
for (int i = 1; i < srcImage.rows-1; i++)
{
for (int j = 1; j < srcImage.cols-1; ++j)
{
//if (((i - 1) >= 0) && ((j - 1) >= 0) && ((i + 1) < srcImage.rows) && ((j + 1) < srcImage.cols))
//{
dstImage.at<Vec3b>(i, j)[0] = (srcImage.at<Vec3b>(i - 1, j - 1)[0] + srcImage.at<Vec3b>(i, j - 1)[0] + srcImage.at<Vec3b>(i + 1, j - 1)[0] +
srcImage.at<Vec3b>(i - 1, j)[0] + srcImage.at<Vec3b>(i, j)[0] + srcImage.at<Vec3b>(i + 1, j)[0] + srcImage.at<Vec3b>(i - 1, j + 1)[0] +
srcImage.at<Vec3b>(i, j + 1)[0] + srcImage.at<Vec3b>(i + 1, j + 1)[0]) / 9;
dstImage.at<Vec3b>(i, j)[1] = (srcImage.at<Vec3b>(i - 1, j - 1)[1] + srcImage.at<Vec3b>(i, j - 1)[1] + srcImage.at<Vec3b>(i + 1, j - 1)[1] +
srcImage.at<Vec3b>(i - 1, j)[1] + srcImage.at<Vec3b>(i, j)[1] + srcImage.at<Vec3b>(i + 1, j)[1] +
srcImage.at<Vec3b>(i - 1, j + 1)[1] + srcImage.at<Vec3b>(i, j + 1)[1] + srcImage.at<Vec3b>(i + 1, j + 1)[1]) / 9;
dstImage.at<Vec3b>(i, j)[2] = (srcImage.at<Vec3b>(i - 1, j - 1)[2] + srcImage.at<Vec3b>(i, j - 1)[2] + srcImage.at<Vec3b>(i + 1, j - 1)[2] +
srcImage.at<Vec3b>(i - 1, j)[2] + srcImage.at<Vec3b>(i, j)[2] + srcImage.at<Vec3b>(i + 1, j)[2] +
srcImage.at<Vec3b>(i - 1, j + 1)[2] + srcImage.at<Vec3b>(i, j + 1)[2] + srcImage.at<Vec3b>(i + 1, j + 1)[2]) / 9;
// }
//else
//{
// //边缘处理 无需处理
// /*dstImage.at<Vec3b>(i, j)[0] = srcImage.at<Vec3b>(i, j)[0];
// dstImage.at<Vec3b>(i, j)[1] = srcImage.at<Vec3b>(i, j)[1];
// dstImage.at<Vec3b>(i, j)[2] = srcImage.at<Vec3b>(i, j)[2];*/
//}
}
}
}
/*
功能:多通道均值滤波 动态地址实现
参数:
返回值:
*/
void AverFilteringPonter(Mat& srcImage, Mat& dstImage)
{
//dstImage = srcImage.clone();
dstImage.create(srcImage.size(), srcImage.type());
int channels = srcImage.channels();
for (int i = 1; i < srcImage.rows - 1; ++i)
{
uchar *proPtr = srcImage.ptr<uchar>(i - 1);
uchar *curPtr = srcImage.ptr<uchar>(i);
uchar *nextPtr = srcImage.ptr<uchar>(i + 1);
uchar *data = dstImage.ptr<uchar>(i);
for (int j = channels; j < (srcImage.cols-1)*channels; ++j)
{
data[j] = (proPtr[j - channels] + proPtr[j] + proPtr[j + channels] +
curPtr[j - channels] + curPtr[j] + curPtr[j + channels] +
nextPtr[j - channels] + nextPtr[j] + nextPtr[j + channels]) / 9;
if (data[j] < 1)
{
data[j] = 0;
}
}
}
}
/*
常规方法均值滤波 指针 单 三
*/
void myBlur(Mat& srcimage, Mat& dstimage, Size wsize)
{
if (wsize.height % 2 == 0 || wsize.width % 2 == 0)//判断是否为奇数
{
fprintf(stderr, "Please enter odd size!");
exit(-1);
}
int hh = (wsize.height - 1) / 2;//半径
int ww = (wsize.width - 1) / 2;//半径
cv::Mat newSrc;
cv::copyMakeBorder(srcimage, newSrc, hh, hh, ww, ww, cv::BORDER_REFLECT_101);//以边缘为轴,对称
dstimage.create(srcimage.size(), srcimage.type());
//均值滤波
int channels = newSrc.channels();
int i;
for (i = 0; i < newSrc.rows-wsize.height; i++)
{
uchar *data = dstimage.ptr<uchar>(i);//此处的i只能是dstimage的位置 不可以与newSrc的混淆
int sum = 0;
int mean = 0;
for (int j = 0; j < (newSrc.cols - hh)*channels; ++j)
{
int count = 0;
for(int s = i;s<i+wsize.height;s++)//分配多少个指针
for (int x = 0; x < wsize.height; x++)
{
sum += newSrc.ptr(s)[j + x * channels];
count++;
}
mean = sum / (wsize.height*wsize.width);
data[j + hh*channels] = mean;
sum = 0;
mean = 0;
}
}
}
/*
均值滤波 指针 三
*/
void myBlurPointer(Mat& srcimage, Mat& dstimage, Size wsize)
{
if (wsize.height % 2 == 0 || wsize.width % 2 == 0)//判断是否为奇数
{
fprintf(stderr, "Please enter odd size!");
exit(-1);
}
int hh = (wsize.height - 1) / 2;//半径
int ww = (wsize.width - 1) / 2;//半径
cv::Mat newSrc;
cv::copyMakeBorder(srcimage, newSrc, hh, hh, ww, ww, cv::BORDER_REFLECT_101);//以边缘为轴,对称
dstimage.create(srcimage.size(), srcimage.type());
//imshow("hello", newSrc);
//均值滤波
int sumR = 0;
int sumG = 0;
int sumB = 0;
int averageR = 0;
int averageG = 0;
int averageB = 0;
int count = 0;
for (int i = hh; i < srcimage.rows + hh; ++i)
{
for (int j = ww; j < srcimage.cols + ww; ++j)
{
for (int r = i - hh; r <= i + hh; r++)
{
Vec3b* data1 = newSrc.ptr<Vec3b>(r);//指针 行
for (int k = j - hh; k <= j + hh; k++)
{
sumR += data1[k][0];
sumG += data1[k][1];
sumB += data1[k][2];
count++;
}
}
/*std::cout << count << std::endl;
count = 0;*/
averageR = sumR / wsize.area();
averageG = sumG / wsize.area();
averageB = sumB / wsize.area();
//赋值给目标图像
Vec3b* data = dstimage.ptr<Vec3b>(i - hh);
data[j - ww][0] = averageR;
data[j - ww][1] = averageG;
data[j - ww][2] = averageB;
sumR = 0;
sumG = 0;
sumB = 0;
averageR = 0;
averageG = 0;
averageB = 0;
}
}
}
/*
积分均值滤波
*/
void myBlurFlation(Mat& srcimage, Mat& dstimage, Size wsize)
{
if (wsize.height % 2 == 0 || wsize.width % 2 == 0)//判断是否为奇数
{
fprintf(stderr, "Please enter odd size!");
exit(-1);
}
int hh = (wsize.height - 1) / 2;//半径
int ww = (wsize.width - 1) / 2;//半径
cv::Mat newSrc;
cv::copyMakeBorder(srcimage, newSrc, hh, hh, ww, ww, cv::BORDER_REFLECT_101);//以边缘为轴,对称
dstimage = cv::Mat::zeros(srcimage.size(), srcimage.type());
//dstimage.create(srcimage.size(), srcimage.type());
Mat inte;
//均值滤波积分
//blurIntegral(newSrc,inte);
testIntegral(newSrc, inte);
//myBlurIntegral(newSrc, inte);
//均值滤波
double mean1 = 0;
double mean2 = 0;
double mean3 = 0;
for (int i = hh + 1; i <= srcimage.rows + hh - 1; ++i)
{
for (int j = ww + 1; j <= srcimage.cols + ww + 1; ++j)
{
double top_left1 = inte.at<Vec3d>(i - hh - 1, j - ww - 1)[0];
double top_left2 = inte.at<Vec3d>(i - hh - 1, j - ww - 1)[1];
double top_left3 = inte.at<Vec3d>(i - hh - 1, j - ww - 1)[2];
double top_right1 = inte.at<Vec3d>(i - hh - 1, j + ww)[0];
double top_right2 = inte.at<Vec3d>(i - hh - 1, j + ww)[1];
double top_right3 = inte.at<Vec3d>(i - hh - 1, j + ww)[2];
double buttom_left1 = inte.at<Vec3d>(i + hh, j - ww - 1)[0];
double buttom_left2 = inte.at<Vec3d>(i + hh, j - ww - 1)[1];
double buttom_left3 = inte.at<Vec3d>(i + hh, j - ww - 1)[2];
double buttom_right1 = inte.at<Vec3d>(i + hh, j + ww)[0];
double buttom_right2 = inte.at<Vec3d>(i + hh, j + ww)[1];
double buttom_right3 = inte.at<Vec3d>(i + hh, j + ww)[2];
mean1 = (top_left1 + buttom_right1 - top_right1 - buttom_left1) / wsize.area();
mean2 = (top_left2 + buttom_right2 - top_right2 - buttom_left2) / wsize.area();
mean3 = (top_left3 + buttom_right3 - top_right3 - buttom_left3) / wsize.area();
if (mean1 < 0 )
{
mean1 = 0;
}
else if (mean1 > 255)
{
mean1 = 255;
}
if (mean2 < 0)
{
mean2 = 0;
}
else if (mean2 > 255)
{
mean2 = 255;
}
if (mean3 < 0)
{
mean3 = 0;
}
else if (mean3 > 255)
{
mean3 = 255;
}
dstimage.at<Vec3b>(i - hh - 1, j - ww - 1)[0] = static_cast<int>(mean1);
dstimage.at<Vec3b>(i - hh - 1, j - ww - 1)[1] = static_cast<int>(mean2);
dstimage.at<Vec3b>(i - hh - 1, j - ww - 1)[2] = static_cast<int>(mean3);
}
std::cout << std::endl;
}
}
void blurIntegral(cv::Mat &src, cv::Mat &dst)
{
int row = src.rows;
int column = src.cols;
//创建一个目标图像标准格式
dst = cv::Mat::zeros(row + 1, column + 1,CV_64FC3);
double sum1 = 0;
double sum2 = 0;
double sum3 = 0;
for (int i = 1; i < dst.rows; ++i)
{//列扫描
for (int j = 1,sum1 = 0,sum2 = 0,sum3 = 0; j < dst.cols; ++j)
{//行累加
//行累加,因为积分图相当于在原图上方加一行,
//左边加一列,所以积分图的(1,1)对应原图(0,0),(i,j)对应(i-1,j-1)
sum1 += src.at<Vec3b>(i - 1, j - 1)[0];
sum2 += src.at<Vec3b>(i - 1, j - 1)[1];
sum3 += src.at<Vec3b>(i - 1, j - 1)[2];
dst.at<Vec3d>(i, j)[0] = dst.at<Vec3d>(i - 1, j)[0] + sum1;
dst.at<Vec3d>(i, j)[1] = dst.at<Vec3d>(i - 1, j)[1] + sum2;
dst.at<Vec3d>(i, j)[2] = dst.at<Vec3d>(i - 1, j)[2] + sum3;
}
}
}
void myBlurIntegral(cv::Mat &src, cv::Mat &dst)
{
int row = src.rows;
int column = src.cols;
//创建一个目标图像标准格式
dst = cv::Mat::zeros(row + 1, column + 1, CV_64FC3);
for (int i = 1; i < dst.rows; ++i)
{
for (int j = 1; j < dst.cols; ++j)
{
double top_left0 = dst.at<Vec3d>(i - 1, j - 1)[0];
double top_left1 = dst.at<Vec3d>(i - 1, j - 1)[1];
double top_left2 = dst.at<Vec3d>(i - 1, j - 1)[2];
double top_right0 = dst.at<Vec3d>(i - 1, j)[0];
double top_right1 = dst.at<Vec3d>(i - 1, j)[1];
double top_right2 = dst.at<Vec3d>(i - 1, j)[2];
double buttom_left0 = dst.at<Vec3d>(i, j - 1)[0];
double buttom_left1 = dst.at<Vec3d>(i, j - 1)[1];
double buttom_left2 = dst.at<Vec3d>(i, j - 1)[2];
double buttom_right0 = src.at<Vec3b>(i - 1, j - 1)[0];
double buttom_right1 = src.at<Vec3b>(i - 1, j - 1)[1];
double buttom_right2 = src.at<Vec3b>(i - 1, j - 1)[2];
dst.at<Vec3d>(i, j)[0] = buttom_left0 + top_right0 - top_left0 + buttom_right0;
dst.at<Vec3d>(i, j)[1] = buttom_left1 + top_right1 - top_left1 + buttom_right1;
dst.at<Vec3d>(i, j)[2] = buttom_left2 + top_right2 - top_left2 + buttom_right2;
}
//std::cout <<"一行结束" <<std::endl;
}
}
/*
指针形式积分
未完善
*/
void test(Mat& src, Mat& dst, Size wsize)
{
if (wsize.height % 2 == 0 || wsize.width % 2 == 0)//判断是否为奇数
{
fprintf(stderr, "Please enter odd size!");
exit(-1);
}
int hh = (wsize.height - 1) / 2;//半径
int ww = (wsize.width - 1) / 2;//半径
std::cout << wsize.area()<<std::endl;
cv::Mat newSrc;
cv::copyMakeBorder(src, newSrc, hh, hh, ww, ww, cv::BORDER_REFLECT_101);//以边缘为轴,对称
int row = newSrc.rows;
int col = newSrc.cols;
Mat inte;
//均值滤波
testIntegral(newSrc, inte);
dst.create(src.size(), CV_8UC3);
for (int i = hh + 1; i < row - hh - 1; ++i)
{
for (int j = ww + 1; j < col - ww - 1; ++j)
{
double sum0 = (inte.ptr<Vec3d>(i + hh)[j + ww][0] - inte.ptr<Vec3d>(i - hh - 1)[j + ww][0]
- inte.ptr<Vec3d>(i + hh)[j - ww - 1][0] + inte.ptr<Vec3d>(i - hh - 1)[j - ww - 1][0]);
dst.ptr<Vec3b>(i - hh-1)[j - ww-1][0] =static_cast<int>(sum0 / wsize.area());
double sum1 = (inte.ptr<Vec3d>(i + hh)[j + ww][1] - inte.ptr<Vec3d>(i - hh - 1)[j + ww][1]
- inte.ptr<Vec3d>(i + hh)[j - ww - 1][1] + inte.ptr<Vec3d>(i - hh - 1)[j - ww - 1][1]);
dst.ptr<Vec3b>(i - hh -1)[j - ww-1][1] = static_cast<int>(sum1 / wsize.area());
double sum2 = (inte.ptr<Vec3d>(i + hh)[j + ww][2] - inte.ptr<Vec3d>(i - hh - 1)[j + ww][2]
- inte.ptr<Vec3d>(i + hh)[j - ww - 1][2] + inte.ptr<Vec3d>(i - hh - 1)[j - ww - 1][2]);
dst.ptr<Vec3b>(i - hh-1)[j - ww-1][2] = static_cast<int>(sum2 / wsize.area());
}
}
}
void testIntegral(cv::Mat &src, cv::Mat &dst)
{
int row = src.rows;
int column = src.cols;
//imshow("test3", src);
//dst = cv::Mat::zeros(src.size(), src.type());
//创建一个目标图像标准格式
dst = cv::Mat::zeros(row + 1, column + 1, CV_64FC3);//创建一个黑色图像
for (int i = 1; i < dst.rows; ++i)
{
for (int j = 1; j < dst.cols; ++j)
{
double top_left0 = dst.ptr<Vec3d>(i - 1)[j - 1][0];
double top_left1 = dst.ptr<Vec3d>(i - 1)[j - 1][1];
double top_left2 = dst.ptr<Vec3d>(i - 1)[j - 1][2];
double top_right0 = dst.ptr<Vec3d>(i - 1)[j][0];
double top_right1 = dst.ptr<Vec3d>(i - 1)[j][1];
double top_right2 = dst.ptr<Vec3d>(i - 1)[j][2];
double buttom_left0 = dst.ptr<Vec3d>(i)[j - 1][0];
double buttom_left1 = dst.ptr<Vec3d>(i)[j - 1][1];
double buttom_left2 = dst.ptr<Vec3d>(i)[j - 1][2];
double buttom_right0 = src.ptr<Vec3b>(i - 1)[j - 1][0];
double buttom_right1 = src.ptr<Vec3b>(i - 1)[j - 1][1];
double buttom_right2 = src.ptr<Vec3b>(i - 1)[j - 1][2];
dst.ptr<Vec3d>(i)[j][0] = buttom_left0 + top_right0 - top_left0 + buttom_right0;
dst.ptr<Vec3d>(i)[j][1] = buttom_left1 + top_right1 - top_left1 + buttom_right1;
dst.ptr<Vec3d>(i)[j][2] = buttom_left2 + top_right2 - top_left2 + buttom_right2;
}
}
std::cout << std::endl;
}
/*
通道分离实现积分均值滤波
*/
void testSplit(Mat& src, Mat& dst, Size size)
{
dst = src.clone();
std::vector<cv::Mat>channels1;
split(src, channels1);
std::vector<cv::Mat>channels2;
split(dst, channels2);
Fast_MeanFilter(channels1[0], channels2[0], size);
Fast_MeanFilter(channels1[1], channels2[1], size);
Fast_MeanFilter(channels1[2], channels2[2], size);
merge(channels2, dst);
}
/*
功能:综合均值滤波
*/
void MyBlur(Mat& src, Mat& dst, Size size)
{
if (src.channels() == 1)
{
Fast_MeanFilter(src, dst,size);
}
else if (src.channels() == 3)
{
//myBlurPointer(src, dst, size);
//myBlurFlation(src,dst,size);
test(src, dst, size);
}
else
{
myBlur(src, dst, size);
}
}
本人在这里写了很多的算子,其测试结果大部分都一样,时间和效果有一点不同。以下是测试的原图和均值滤波图。