0 定义及用途
均值滤波,即以模板内算术平均数的值代替中心像素值,可以降低高斯噪声。
中值滤波,即以模板内进行有序排列后位于中间的像素值代替中心像素值,可以降低椒盐噪声。
最大值滤波,即以模板内进行有序排列后最大像素值代替中心像素值,可以去除图像中的暗斑,使亮斑增大。
最小值滤波,即以模板内进行有序排列后最小像素值代替中心像素值,可以去除图像中的亮斑,使暗斑增大。
1 代码
class Filter{ public: Filter(int width, int height) : width_(width), height_(height) { dst_img_.create(height, width, CV_8UC1); } ~Filter() { } virtual cv::Mat& do_filter(cv::Mat& src_img) = 0; const int radius_ = 1; // 3 * 3 model int height_; int width_; cv::Mat dst_img_; };
class MeanFilter : public Filter{ public: MeanFilter(int width, int height) : Filter(width, height) { }; ~MeanFilter() { }; cv::Mat& do_filter(cv::Mat& src_img) { int template_size = (2 * radius_ + 1)*(2 * radius_ + 1); for (int i = 0; i < src_img.rows; ++i) { for (int j = 0; j < src_img.cols; ++j) { int roi_sum = 0; for (int m = -radius_; m <= radius_; m++) { int r_offset = m + i; r_offset = (r_offset < 0) ? 0 : (r_offset >= src_img.rows ? src_img.rows : r_offset); for (int n = -radius_; n <= radius_; n++) { int c_offset = n + j; c_offset = (c_offset < 0) ? 0 : (c_offset >= src_img.cols ? src_img.cols : c_offset); roi_sum += static_cast<int>(src_img.at<unsigned char>(r_offset, c_offset)); } } dst_img_.at<unsigned char>(i, j) = roi_sum / template_size; } } return dst_img_; } }; // 均值滤波,最大值滤波,最小值滤波 class MiddleFilter : public Filter { public: enum { MIN = 0, MIDDLE = 1, MAX = 2 }Method; MiddleFilter(int width, int height, int method = MIDDLE) : Filter(width, height), method_(method){ }; ~MiddleFilter() { }; cv::Mat& do_filter(cv::Mat& src_img) { int template_size = (2 * radius_ + 1)*(2 * radius_ + 1); unsigned char *template_value = new unsigned char[template_size]; for (int i = 0; i < src_img.rows; ++i) { for (int j = 0; j < src_img.cols; ++j) { int index = 0; memset(template_value, 0, template_size); for (int m = -radius_; m <= radius_; m++) { int r_offset = m + i; r_offset = (r_offset < 0) ? 0 : (r_offset >= src_img.rows ? src_img.rows : r_offset); for (int n = -radius_; n <= radius_; n++) { int c_offset = n + j; c_offset = (c_offset < 0) ? 0 : (c_offset >= src_img.cols ? src_img.cols : c_offset); template_value[index++] = src_img.at<unsigned char>(r_offset, c_offset); } } quick_sort(template_value, 0, template_size - 1); if (method_ == MIN) { dst_img_.at<uchar>(i, j) = template_value[0]; } else if (method_ == MIDDLE) { dst_img_.at<uchar>(i, j) = template_value[template_size / 2]; } else { dst_img_.at<uchar>(i, j) = template_value[template_size - 1]; } } } delete[] template_value; return dst_img_; } int method_; }; |