C++实现均值滤波器和中值滤波器
生活随笔
收集整理的這篇文章主要介紹了
C++实现均值滤波器和中值滤波器
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
C++實現均值濾波器和中值濾波器
代碼實現均值濾波器和中值濾波器
由于中值濾波器是非線性濾波,不是卷積,所以均值和中值濾波分開實現。opencv版本為3.4.5
my_convolution.h
#ifndef MY_CONVOLUTION #define MY_CONVOLUTION#include <opencv2/opencv.hpp>class My_Convolution { public:My_Convolution();~My_Convolution();bool load_kernal(const cv::Mat kernal);//加載卷積核void convolute(const cv::Mat &image, cv::Mat &dst);//卷積操作private:bool kernal_loaded;//是否已經加載卷積核cv::Mat curr_kernal;//當前卷積核int bios_x, bios_y;//記錄偏移量//計算每一個像素的掩模乘積之和void compute_sum_of_product(int i, int j, int chan, cv::Mat &complete_image, cv::Mat & dst);//將原圖像轉換成邊框補全的圖像void complete_image_transform(const cv::Mat &image, cv::Mat &dst); };#endif // MY_CONVOLUTIONmy_convolution.cpp
#include "my_convolution.h"using namespace std; using namespace cv;My_Convolution::My_Convolution() {kernal_loaded = false; } My_Convolution::~My_Convolution() {}//加載卷積核 bool My_Convolution::load_kernal(const Mat kernal) {if (kernal.cols % 2 == 1 && kernal.rows % 2 == 1) {curr_kernal = kernal.clone();bios_x = (kernal.cols - 1) / 2;bios_y = (kernal.rows - 1) / 2;kernal_loaded = true;return true;}else {cout << "The size of kernal is not suitable!" << endl;return false;} }//卷積操作 void My_Convolution::convolute(const Mat &image, Mat &dst) {if (!kernal_loaded) {cout << "kernal is empty!Please load the kernal first!" << endl;return;}Mat complete_image;complete_image_transform(image, complete_image);dst = Mat::zeros(image.rows, image.cols, image.type());int channels = image.channels();//獲取圖像的通道數if (channels == 3) {for (int chan = 0;chan < channels;chan++) {for (int i = 0;i < dst.rows;i++) {for (int j = 0;j < dst.cols;j++) {compute_sum_of_product(i, j, chan, complete_image, dst);}}}return;}if (channels == 1) {for (int i = 0;i < dst.rows;i++) {for (int j = 0;j < dst.cols;j++) {compute_sum_of_product(i, j, 0, complete_image, dst);}}}}//計算掩模乘積之和 void My_Convolution::compute_sum_of_product(int i, int j, int chan, Mat &complete_image, Mat &dst) {if (complete_image.channels() == 3) {float sum = 0;int bios_rows = i;int bios_cols = j;for (int curr_rows = 0;curr_rows < curr_kernal.rows;curr_rows++) {for (int curr_cols = 0;curr_cols < curr_kernal.cols;curr_cols++) {float a = curr_kernal.at<float>(curr_rows, curr_cols)*complete_image.at<Vec3b>(curr_rows + bios_rows, curr_cols + bios_cols)[chan];sum += a;}}dst.at<Vec3b>(i, j)[chan] = (int)sum;}else if (complete_image.channels() == 1) {float sum = 0;int bios_rows = i;int bios_cols = j;for (int curr_rows = 0;curr_rows < curr_kernal.rows;curr_rows++) {for (int curr_cols = 0;curr_cols < curr_kernal.cols;curr_cols++) {float a = curr_kernal.at<float>(curr_rows, curr_cols)*complete_image.at<uchar>(curr_rows + bios_rows, curr_cols + bios_cols);sum += a;}}dst.at<uchar>(i, j) = (int)sum;}else {cout << "the type of image is not suitable!" << endl;return;}}//邊框像素補全 void My_Convolution::complete_image_transform(const Mat &image, Mat &dst) {if (!kernal_loaded) {cout << "kernal is empty!" << endl;return;}//Mat的type()成員函數生成CV_<位數>(S/U/F)C<通道數>//初始化一個補全圖像的大小。dst = Mat::zeros(2 * bios_y + image.rows, 2 * bios_x + image.cols, image.type());Rect real_roi_of_image = Rect(bios_x, bios_y, image.cols, image.rows);Mat real_mat_of_image = dst(real_roi_of_image);image.copyTo(real_mat_of_image); }my_nedianfilter.h
#ifndef MY_MEDIANFILTER #define MY_MEDIANFILTER#include <vector> #include <opencv2/opencv.hpp> using namespace cv; using namespace std;void MedianFilter(Mat& src, Mat& dst, int win_size); void Complete_Image_Transform(Mat &src, Mat &comp, int size); void Calc_Median(Mat& comp, Mat& dst, int r, int c, int s);#endifmy_nedianfilter.cpp
#include "my_medianfilter.h"void MedianFilter(Mat& src, Mat& dst, int win_size) {Mat comp = src.clone();Complete_Image_Transform(src, comp, win_size);int rows = comp.rows, cols = comp.cols;int start = win_size / 2;if (comp.channels() > 1){//彩色圖片通道分離vector<Mat> channels_c, channels_d;split(comp, channels_c);split(comp, channels_d);//濾波for (int i = 0; i < 3; i++)Calc_Median(channels_c[i], channels_d[i], rows, cols, start);//合并彩色通道merge(channels_d, dst);}elseCalc_Median(comp, dst, rows, cols, start); }//邊框像素補全 void Complete_Image_Transform(Mat &src, Mat &comp, int size) {//初始化一個補全圖像的大小comp = Mat::zeros(2 * (size / 2) + src.rows, 2 * (size / 2) + src.cols, src.type());Rect real_roi_of_image = Rect((size / 2), (size / 2), src.cols, src.rows);Mat real_mat_of_image = comp(real_roi_of_image);src.copyTo(real_mat_of_image); }void Calc_Median(Mat& comp, Mat& dst, int r, int c, int s) {for (int m = s; m < r - s; m++) {for (int n = s; n < c - s; n++) {vector<uchar> model;for (int i = -s + m; i <= s + m; i++) {for (int j = -s + n; j <= s + n; j++) {//cout << int(src.at<uchar>(i, j)) << endl;model.push_back(comp.at<uchar>(i, j));}}sort(model.begin(), model.end()); //采用快速排序進行dst.at<uchar>(m - s, n - s) = model[(s * 2 + 1) * (s * 2 + 1) / 2];}} }總結
以上是生活随笔為你收集整理的C++实现均值滤波器和中值滤波器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: asp.net web开发步骤_WEB开
- 下一篇: 大前端完整学习路线(完整版),路线完整版