C++、Python实现高斯滤波,均值滤波,中值滤波

图片

在这里插入图片描述

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("img", img)
    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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值