C++:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<windows.h>
using namespace std;
using namespace cv;
Mat fastmeanblur(Mat src, Size ksize, int borderType,Scalar value=Scalar())
{
//滤波窗口的宽高
int h = ksize.height;
int w = ksize.width;
//滤波窗口半径
int m = (h - 1) / 2;
int n = (w - 1) / 2;
//滤波窗口面积
float area = float(h*w);
// 边界扩充图像
Mat expand_img;
copyMakeBorder(src, expand_img, m, m, n, n, borderType,value);
// 图像积分
Mat dst;
integral(expand_img, dst, CV_32FC1);
int rows = src.rows;
int cols = src.cols;
int r = 0, c = 0;
Mat meanimg = Mat::zeros(src.size(), CV_32FC1);
for (int i = m; i < m + rows; i++)
{
for (int j = n; j < n + cols; j++)
{
float BR = dst.at<float>(i + m + 1, j + n + 1);
float TL = dst.at<float>(i - m , j - n);
float TR = dst.at<float>(i + m + 1, j - n );
float BL = dst.at<float>(i - m , j + n + 1);
meanimg.at<float>(r, c) = (BR + TL - TR - BL) / area;
c++;
};
r++;
c = 0;
};
return meanimg;
};
int main()
{
Mat img,dst,meanimg,pic;
img = imread("D:/testimage/orange.jpg");
cvtColor(img, dst, COLOR_BGR2GRAY);
imshow("original image", dst);
double t1 = GetTickCount();
meanimg=fastmeanblur(dst, Size(13, 13), BORDER_DEFAULT);
double t2 = GetTickCount();
meanimg.convertTo(meanimg,CV_32F,1.0/255,0);
cout << "waste time:" << t2 - t1 << endl;
imshow("result image", meanimg);
//系统自带快速均值滤波
double t3 = GetTickCount();
boxFilter(dst, pic,-1,Size(13,13), Point(-1, -1));
double t4 = GetTickCount();
cout << "system_waste time:" << t4 - t3 << endl;
imshow("result image1", pic);
waitKey(0);
return 0;
};
时间对比:
62毫秒;而系统自带的快速均值滤波由于太快直接为0了
结果:
Python:
import cv2 as cv
import numpy as np
#图像积分
def Integral(image):
rows,cols=image.shape
inteImageC=np.zeros((rows,cols),np.float32)
for r in range(rows):
for c in range(cols):
if c == 0:
inteImageC[r][c]=image[r][c]
else:
inteImageC[r][c]=inteImageC[r][c-1]+image[r][c]
inteImage = np.zeros((rows,cols), np.float32)
for c in range(cols):
for r in range(rows):
if r == 0:
inteImage[r][c]=inteImageC[r][c]
else:
inteImage[r][c]=inteImage[r-1][c]+inteImageC[r][c]
inteImage_0=np.zeros((rows+1,cols+1),np.float32)
inteImage_0[1:rows+1,1:cols+1]=inteImage
return inteImage_0
def fastmeanblur(img,window_size,borderType=cv.BORDER_DEFAULT):
#获取滤波窗口的宽高和面积系数
h= int((window_size[0] - 1) /2)
w= int((window_size[1] - 1) / 2)
rate=1.0/(window_size[0]*window_size[1])
#边界扩充
expand_img=cv.copyMakeBorder(img,h,h,w,w,borderType)
#图像积分函数integral()
img_inergral=Integral(expand_img)
rows,cols=img.shape
fastmeanblur_image=np.zeros((rows,cols),np.float32)
#初始化快速均值滤波图像下标
r,c=0,0
for m in range(h,h+rows,1):
for n in range(w,w+cols,1):
fastmeanblur_image[r][c]=(img_inergral[m+h+1][n+w+1]+img_inergral[m-h][n-w]
-img_inergral[m+h+1][n-w]-img_inergral[m-h][n+w+1])*rate
c+=1
r+=1
c=0
return fastmeanblur_image
if __name__=="__main__":
img=cv.imread("D:/testimage/orange.jpg",cv.IMREAD_GRAYSCALE)
src=fastmeanblur(img,(15,15),borderType=cv.BORDER_DEFAULT)
src=src.astype(np.uint8)
cv.imshow("original image",img)
cv.imshow("result image",src)
cv.waitKey(0)
cv.destroyAllWindows()