Digital image processing (eight) KNN filter

Topic: Filter an image using a K-nearest neighbor smoothing filter.
The international standard test image Lena is used.

In the previous section, we introduced the mean filter. The mean filter will blur the image and reduce the edge features. In order to solve the problem of image blurring, a natural idea is to first determine whether the current pixel is on the boundary point during smoothing, and if it is, then smoothing is not performed; if not, smoothing is performed.
KNN algorithm principle: If the pixel to be processed is a non-noise point, by selecting a neighboring point with a pixel value similar to it, it can be ensured that the calculation of the pixel value in the same area is basically performed during smoothing, so that the image can be guaranteed sharpness (boundary preservation). If the pixel to be processed is a noise point, because the noise itself has the characteristics of an isolated point, it can be suppressed by smoothing with adjacent points.

The specific method is as follows:

  1. f ( x , y ) f(x,y) f(x,y ) is the current pixel to be processed, with it as the center, construct aN × NN\times NN×N template (NNN is an odd number, usually 3, 5, or 7);
  2. N × NN\times N in the templateN×Among N pixels, select K pixel values ​​andf ( x , y ) f(x,y)f(x,y ) similar pixels (generally whenN = 3 N=3N=3 , takeK = 5 K=5K=5 ; whenN = 5 N=5N=5 , takeK = 9 K=9K=9 ; whenN = 7 N=7N=7 , takeK = 25 K=25K=25 ), whichKKK pixels do not containf ( x , y ) f(x,y )f(x,y ) itself;
  3. KK _The mean (median) of K pixels replaces the original pixel value f ( x , y ) f(x,y)f(x,y )
    C++ code:
//定义结构体,保存相邻像素点的信息
struct subValue
{
    
    
    int value;
    cv::Point f;
};
//冒泡排序
vector<struct subValue> sortStruct(vector<struct subValue>a)
{
    
    
    struct subValue b;
    for (int i = 0; i < a.size() - 1; i++)
    {
    
    
        for (int j = 0; j < a.size() - 1 - i; j++)
        {
    
    
            if (a[j].value > a[j + 1].value)
            {
    
    
                b = a[j];
                a[j] = a[j + 1];
                a[j + 1] = b;
            }
        }
    }
    return a;
}
int main()
{
    
    
    cv::Mat image = cv::imread("knn.png");
    cv::Mat src(image.size(), CV_8UC1);
    cv::cvtColor(image, src, CV_BGR2GRAY);

    cv::Mat dst = src.clone();
    int N = 3, K = 5;

    for (int row = 1; row < src.rows - 1; ++row)
    {
    
    
        for (int col = 1; col < src.cols - 1; ++col)
        {
    
    
            double v = 0.0;
            vector<struct subValue>c;
            struct subValue b;
            for (int dy = -1; dy < N - 1; ++dy)
            {
    
    
                for (int dx = -1; dx < N - 1; ++dx)
                {
    
    
                    if (!(dx == 0 && dy == 0))
                    {
    
    
                        b.value = abs(src.at<uchar>(row + dy, col + dx) - src.at<uchar>(row, col));
                        b.f.x = dx;
                        b.f.y = dy;
                        c.push_back(b);
                    }
                }
            }
            //进行排序
            vector<struct subValue> sortValue = sortStruct(c);
            //取中值
           // v = src.at<uchar>(row + sortValue[2].f.y, col + sortValue[2].f.x);
           // dst.at<uchar>(row, col) = uchar(v);
           //取均值
            for (int i = 0; i < K;++i)
            {
    
    
                v += src.at<uchar>(row + sortValue[i].f.y, col + sortValue[i].f.x);
            }
            dst.at<uchar>(row, col) = uchar(v/K);
           
        }
    }
    cv::imshow("input", src);
    cv::imshow("output", dst);
    cv::waitKey(0);
    return 0;
}

Reference Book: Fundamentals of Digital Image Processing. Zhu Hong

おすすめ

転載: blog.csdn.net/qq_41596730/article/details/126999048