取鄰域內最值。
#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; }
原圖:
最小值濾波,偏暗,
最大值濾波,偏亮。