Bilateral filtering

Gaussian filtering takes distance as the weight, and the filtering template is designed as the filtering coefficient. It only considers the relationship between spatial positions of pixels, so the filtering results will lose the information of edges.

The defects of Gaussian filtering are shown in the figure below: the flat area is normally filtered and the image details remain unchanged, while the edge of mutation is blurred because only distance is used to determine the weight of filtering.

On the basis of gaussian, further optimization, superimposed the consideration of pixel value, so it also leads to the bilateral filter, a nonlinear filter, the filtering effect is more effective to preserve the edge.

In order to understand the two influencing factors of distance and pixel difference of bilateral filtering, the following two concepts are first explained to help understand.

Spatial distance: Euclidean distance between the current point and the center point of the filter template.

Grayscale distance: the absolute value of the grayscale difference between the current point and the center point of the filter template.

The kernel function of bilateral filtering is the synthesis result of spatial domain kernel and pixel range domain kernel:

1) In the flat area of the image, the pixel value changes very little, so the pixel difference is close to 0, and the corresponding weight of the pixel range is close to 1. In this case, the weight of the spatial domain plays a major role, which is equivalent to gaussian blur.

2) In the edge area of the image, the pixel value changes greatly, so the pixel difference value is large, and the weight of the corresponding pixel range domain becomes larger. Even if the weight of the distance space domain is small, the total weight coefficient of the pixel domain is also large, so as to protect the information of the edge.

The effect of bilateral filtering is shown in the figure below. On the edge of mutation, pixel difference weight is used, so the edge is well preserved.

The principle of bilateral filtering is shown in the figure below.

【 reference: www.cnblogs.com/pingwen/p/1…

API

public static void bilateralFilter(Mat src, Mat dst, int d, double sigmaColor, double sigmaSpace, int borderType) 
Copy the code
  • Parameter 1: SRC, the data type of the image to be bilaterally filtered must be CV_8U, CV_32F or CV_64F, and the number of channels must be single channel or three-channel.
  • Parameter two: DST, bilaterally filtered image with the same size and data type as input image SRC.
  • Parameter 3: d, the diameter of each pixel neighborhood in the filtering process. If this value is non-positive, it can be calculated by the fifth parameter sigmaSpace. When filter diameter greater than 5, the function of the speed will slow down, so if you need to use this function in the real-time system, proposed to filter radius set to 5, for offline processing contains a lot of image noise filtering, the radius of the filter can be set to 9, when the filter radius is a positive number, The filter diameter is calculated based on the standard deviation of the spatial filter
  • Parameter 4: sigmaColor, standard deviation of color space filter. The larger this parameter is, the more colors are mixed together in the pixel field, resulting in a larger semi-equal color region.
  • Parameter 5: sigmaSpace, the standard deviation of the filter in spatial coordinates. The larger this parameter is, the more distant pixels will influence each other, so that there are enough similar colors in a larger field to obtain the same color. When the third parameter d is greater than 0, the neighborhood range is determined by D, and when the third parameter is less than or equal to 0, the neighborhood range is proportional to the value of this parameter.
  • Parameter 6: borderType, pixel extrapolation select logo. The default parameter is BORDER_DEFAULT, which means that there is no inverse padding of boundary values.

operation

/** * dual filter * author: yidong * 2020/5/1 */
class BilateralFilterActivity : CardGalleryActivity() {

    override fun buildCards(a) {
        val bgr = Utils.loadResource(this, R.drawable.timg)
        val source = Mat()
        Imgproc.cvtColor(bgr, source, Imgproc.COLOR_BGR2RGB)
        bgr.release()
        addCardFromMat("Original", source, 240)
        bilateralFilter(source)
        source.release()
    }

    private fun bilateralFilter(source: Mat) {
        val dst9 = Mat()
        Imgproc.bilateralFilter(source, dst9, 9.10.0.10.0)
        addCardFromMat("Bilateral filter diameter 9X9 standard deviation 10", dst9, 240)
        dst9.release()

        val dst25 = Mat()
        Imgproc.bilateralFilter(source, dst25, 25.10.0.10.0)
        addCardFromMat("Bilateral filter diameter 25X25 standard deviation 10", dst25, 240)
        dst25.release()

        val shift9 = Mat()
        Imgproc.bilateralFilter(source, shift9, 25.100.0.100.0)
        addCardFromMat("Bilateral filter diameter 25X25 standard deviation 100", shift9, 240)
        shift9.release()

        val shift25 = Mat()
        Imgproc.bilateralFilter(source, shift25, 25.200.0.200.0)
        addCardFromMat("Bilateral filter diameter 25X25 standard deviation 200", shift25, 240)
        shift25.release()
    }
}
Copy the code

The effect

The results show that the filter diameter has an important influence on the filtering effect. The larger the filter diameter is, the more obvious the filtering effect is. At the same time, when the filter radius is the same, the larger the standard deviation, the more obvious the filtering effect. In addition, it can be seen from the results that bilateral filtering can indeed play a face-beautifying effect.

The source code

Github.com/onlyloveyd/…