OpenCV C++ 最小值 最大值 滤波
取邻域内最值。
#include <opencv2/opencv.hpp> #include <iostream> #include <string> using namespace cv; /* 自定义最小值滤波,邻域内最小,卷积核大小默认3 */ void MinFilter(Mat &src_image, Mat &dst_image, int k_size = 3) { int max_rows = src_image.rows; // 行像素数 int max_cols = src_image.cols; // 列像素数 int channels = src_image.channels(); // 图片是几通道的 int p = (k_size - 1) / 2; // -(k−1)/2 ~ (k−1)/2 int kernel[k_size * k_size]; // 卷积核,k*k的矩阵,k为奇数 int mint = 255; // 初始最大值 // 对每个像素点进行处理 for (int row = 0; row < max_rows; ++row) { for (int col = 0; col < max_cols; ++col) { // 1通道,灰度值 if (channels == 1) { // 以当前像素点为中心的k*k的矩阵中,取最小值 for (int i = row - p; i <= row + p; ++i) for (int j = col - p; j <= col + p; ++j) if(i >= 0 && i < max_rows && j >= 0 && j < max_cols) if (src_image.at<uchar>(i, j) < mint) mint = src_image.at<uchar>(i, j); dst_image.at<uchar>(row, col) = mint; // 像素值赋最小值 }//if // 3通道,RGB else if (channels == 3) { // 分别获取R G B for(int chn = 0; chn < channels; ++chn) { mint = 255; // 以当前像素点为中心的k*k的矩阵中,取最小值 for (int i = row - p; i <= row + p; ++i) for (int j = col - p; j <= col + p; ++j) if(i >= 0 && i < max_rows && j >= 0 && j < max_cols) if (src_image.at<Vec3b>(i, j)[chn] < mint) mint = src_image.at<Vec3b>(i, j)[chn]; dst_image.at<Vec3b>(row, col)[chn] = mint; // 像素值赋最小值 }//for }// else if }// for }// for } /* 自定义最大值滤波,邻域内最大,卷积核大小默认3 */ void MaxFilter(Mat &src_image, Mat &dst_image, int k_size = 3) { int max_rows = src_image.rows; // 行像素数 int max_cols = src_image.cols; // 列像素数 int channels = src_image.channels(); // 图片是几通道的 int p = (k_size - 1) / 2; // -(k−1)/2 ~ (k−1)/2 int kernel[k_size * k_size]; // 卷积核,k*k的矩阵,k为奇数 int maxt = 0; // 初始最小值; // 对每个像素点进行处理 for (int row = 0; row < max_rows; ++row) { for (int col = 0; col < max_cols; ++col) { // 1通道,灰度值 if (channels == 1) { // 以当前像素点为中心的k*k的矩阵中,取最大值 for (int i = row - p; i <= row + p; ++i) for (int j = col - p; j <= col + p; ++j) if(i >= 0 && i < max_rows && j >= 0 && j < max_cols) if (src_image.at<uchar>(i, j) > maxt) maxt = src_image.at<uchar>(i, j); dst_image.at<uchar>(row, col) = maxt; // 像素值赋最大值 }// if // 3通道,RGB else if (channels == 3) { // 分别获取R G B for(int chn = 0; chn < channels; ++chn) { maxt = 0; // 以当前像素点为中心的k*k的矩阵中,取最小值 for (int i = row - p; i <= row + p; ++i) for (int j = col - p; j <= col + p; ++j) if(i >= 0 && i < max_rows && j >= 0 && j < max_cols) if (src_image.at<Vec3b>(i, j)[chn] > maxt) maxt = src_image.at<Vec3b>(i, j)[chn]; dst_image.at<Vec3b>(row, col)[chn] = maxt; // 像素值赋最大值 }//for }// else if }// for }// for } int main() { std::string img_path = "images/"; // 从路径中读取图片 Mat src_image = imread(img_path + "ai.jpg"); // 正确 if (src_image.empty()) { printf("Reading image error!\n\n"); system("pause"); } else { // 沿x轴和y轴的缩放 // resize(src_image, src_image, Size(), 0.5, 0.5, INTER_LINEAR); //显示图片 imshow("Original", src_image); // min,max 最值滤波 Mat dst_image_min, dst_image_max; dst_image_min.create(src_image.size(), src_image.type()); dst_image_max.create(src_image.size(), src_image.type()); MinFilter(src_image, dst_image_min); imshow("minImage", dst_image_min); // imwrite(img_path + "min.jpg", src_image); MaxFilter(src_image, dst_image_max); imshow("maxImage", dst_image_max); // imwrite(img_path + "max.jpg", src_image); waitKey(0); } return 0; }
原图:
最小值滤波,偏暗,
最大值滤波,偏亮。
Less interests,more interest!