zoukankan      html  css  js  c++  java
  • 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!
    
    ");
            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;
    }

     原图:

     最小值滤波,偏暗,

    最大值滤波,偏亮。

  • 相关阅读:
    [POI2011]Lightning Conductor
    [NOI2009]诗人小G

    公告&留言板
    联合省选 2020 题解
    年末时的一些思维碎屑
    RE:ゼロから始める AFO 生活
    退役前的做题记录6.0
    2019年湖南省大学生计算机程序设计竞赛 (HNCPC2019) 简要题解
    300iq Contest 1 简要题解
  • 原文地址:https://www.cnblogs.com/cralor/p/14054254.html
Copyright © 2011-2022 走看看