图片
C++实现
高斯滤波
#include <opencv2/opencv.hpp>
#include <iostream>
#define PI 3.14
void GenerateGaussianMask(cv::Mat& mask, const int& k_size, const double& sigma) {
int center_h = (k_size - 1) / 2;
int center_w = (k_size - 1) / 2;
double sum = 0;
double x, y;
for (int i = 0; i < k_size; i++) {
for (int j = 0; j < k_size; j++) {
x = pow(i - center_w, 2);
y = pow(j - center_h, 2);
double g = exp(-(x + y) / (2 * sigma * sigma)) / (2 * PI * sigma);
mask.at<double>(i, j) = g;
sum += g;
}
}
mask /= sum;
}
void GaussianFilter(const cv::Mat& src) {
int k_size = 3;
double sigma = 1.5;
cv::Mat mask(k_size, k_size, CV_64F);
cv::Mat dst;
cv::Mat comsrc;
GenerateGaussianMask(mask, k_size, sigma);
dst = cv::Mat::zeros(src.size(), src.type());
int hh = (k_size - 1) / 2;
int ww = (k_size - 1) / 2;
cv::copyMakeBorder(src, comsrc, hh, hh, ww, ww, cv::BORDER_REFLECT);
for (int i = hh; i < src.rows + hh; i++) {
for (int j = ww; j < src.cols + ww; j++) {
double sum[3] = { 0 };
for (int r = -hh; r <= hh; r++) {
for (int c = -ww; c <= ww; c++) {
cv::Vec3b rgb = comsrc.at<cv::Vec3b>(i + r, j + c);
sum[0] += rgb[0] * mask.at<double>(r + hh, c + ww);
sum[1] += rgb[1] * mask.at<double>(r + hh, c + ww);
sum[2] += rgb[2] * mask.at<double>(r + hh, c + ww);
}
}
for (int k = 0; k < src.channels(); k++) {
if (sum[k] < 0)
sum[k] = 0;
else if (sum[k] > 255)
sum[k] = 255;
}
cv::Vec3b rgb = { static_cast<uchar>(sum[0]), static_cast<uchar>(sum[1]), static_cast<uchar>(sum[2]) };
dst.at<cv::Vec3b>(i-hh, j-ww) = rgb;
}
}
cv::imshow("src", src);
cv::imshow("Gaussian", dst);
cv::waitKey();
cv::destroyAllWindows();
}
int main() {
cv::Mat src = cv::imread("../red.jpg");
if (src.empty()) return -1;
GaussianFilter(src);
return 0;
}
均值滤波
#include <opencv2/opencv.hpp>
#include <iostream>
void MeanFilter(const cv::Mat& src) {
cv::Mat dst;
cv::Mat comsrc;
int k_size = 3;
int hh = (k_size - 1) / 2;
int ww = (k_size - 1) / 2;
cv::copyMakeBorder(src, comsrc, hh, hh, ww, ww, cv::BORDER_REFLECT_101);
dst = cv::Mat::zeros(src.size(), src.type());
for (int i = hh; i < src.rows + hh; i++) {
for (int j = ww; j < src.cols + ww; j++) {
double sum[3] = { 0 };
for (int r = -hh; r <= hh; r++) {
for (int c = -ww; c <= ww; c++) {
cv::Vec3b rgb = comsrc.at<cv::Vec3b>(i + r, j + c);
sum[0] += rgb[0];
sum[1] += rgb[1];
sum[2] += rgb[2];
}
}
sum[0] /= (k_size * k_size);
sum[1] /= (k_size * k_size);
sum[2] /= (k_size * k_size);
cv::Vec3b rgb = { static_cast<uchar>(sum[0]), static_cast<uchar>(sum[1]),static_cast<uchar>(sum[2]) };
dst.at<cv::Vec3b>(i - hh, j - ww) = rgb;
}
}
cv::imshow("src", src);
cv::imshow("Mean", dst);
cv::waitKey();
cv::destroyAllWindows();
}
int main() {
cv::Mat src = cv::imread("../red.jpg");
if (src.empty()) return -1;
MeanFilter(src);
return 0;
}
中值滤波
#include <opencv2/opencv.hpp>
#include <iostream>
void mediumFilter(const cv::Mat& src) {
cv::Mat dst;
cv::Mat comsrc;
int k_size = 3;
int hh = (k_size - 1) / 2;
int ww = (k_size - 1) / 2;
cv::copyMakeBorder(src, comsrc, hh, hh, ww, ww, cv::BORDER_REFLECT_101);
dst = cv::Mat::zeros(src.size(), src.type());
for (int i = hh; i < src.rows + hh; i++) {
for (int j = ww; j < src.cols + ww; j++) {
std::vector<int> sum0;
std::vector<int> sum1;
std::vector<int> sum2;
for (int r = -hh; r <= hh; r++) {
for (int c = -ww; c <= ww; c++) {
cv::Vec3b rgb = comsrc.at<cv::Vec3b>(i + r, j + c);
sum0.push_back(rgb[0]);
sum1.push_back(rgb[1]);
sum2.push_back(rgb[2]);
}
}
sort(sum0.begin(), sum0.end());
sort(sum1.begin(), sum1.end());
sort(sum2.begin(), sum2.end());
cv::Vec3b rgb = { static_cast<uchar>(sum0[4]),static_cast<uchar>(sum1[4]), static_cast<uchar>(sum2[4]) };
dst.at<cv::Vec3b>(i - hh, j - ww) = rgb;
}
}
cv::imshow("src", src);
cv::imshow("Medium", dst);
cv::waitKey();
cv::destroyAllWindows();
}
int main() {
cv::Mat src = cv::imread("../red.jpg");
if (src.empty()) return -1;
mediumFilter(src);
return 0;
}
Python实现
高斯滤波
import cv2
import numpy as np
def GaussKernel(k_size, pad, sigma):
K = np.zeros((k_size, k_size), dtype=np.float)
for x in range(-pad, -pad + k_size):
for y in range(-pad, pad + k_size):
K[-pad + y, -pad + x] = np.exp(-(x*x + y*y)/2*sigma*sigma)
K /= 2 * np.pi * sigma * sigma
K /= K.sum()
return K
def GaussFilter(img):
k_size = 3
sigma = 1.3
h, w, c = img.shape
pad = k_size // 2
out = np.zeros((h + 2*pad, w + 2*pad, c), dtype=np.float)
out[pad: pad+h, pad: pad+w] = img.copy().astype(np.float)
Gauss_filter = GaussKernel(k_size, pad, sigma)
tmp = out.copy()
for ci in range(c):
for y in range(h):
for x in range(w):
out[pad+y, pad+x, ci] = np.sum(Gauss_filter * tmp[y: y+k_size, x: x+k_size, ci])
out = out[pad: pad+h, pad: pad+w].astype(np.uint8)
cv2.imshow("img", img)
cv2.imshow("Gauss", out)
cv2.waitKey()
if __name__ == "__main__":
img = cv2.imread("red.jpg")
GaussFilter(img)
均值滤波
import cv2
import numpy as np
def MeanFilter(img):
k_size = 3
pad = k_size // 2
h, w, c = img.shape
out = np.zeros((h+2*pad, w+2*pad, c), dtype=np.float)
out[pad: pad+h, pad: pad+w] = img.copy().astype(np.float)
temp = out.copy()
for ci in range(c):
for y in range(h):
for x in range(w):
out[pad+y, pad+x, ci] = np.mean(temp[y: y+k_size, x: x+k_size, ci])
out = out[pad: pad+h, pad: pad+w].astype(np.uint8)
cv2.imshow("Mean", out)
cv2.waitKey(0)
if __name__ == "__main__":
img = cv2.imread("red.jpg")
MeanFilter(img)
中值滤波
import cv2
import numpy as np
def mediumFilter(img):
k_size = 3
h, w, c = img.shape
pad = k_size // 2
out = np.zeros((h+2*pad, w+2*pad, c), dtype=np.float)
out[pad:pad+h, pad:pad+w] = img.copy().astype(np.float)
temp = out.copy()
for ci in range(c):
for y in range(h):
for x in range(w):
out[pad+y, pad+x, ci] = np.median(temp[y:y+k_size, x:x+k_size, ci])
out = out[pad:pad+h, pad:pad+w].astype(np.uint8)
cv2.imshow("img", img)
cv2.imshow("medium", out)
cv2.waitKey(0)
if __name__ == "__main__":
img = cv2.imread("red.jpg")
mediumFilter(img)