OpenCvSharp function: Filter2D linear filtering, SepFilter2D separable linear filtering

Filter2D linear filtering

Function description: It can apply any linear filter to the image. Support local operation. For border pixel values, please refer to CopyMakeBorder .
This function actually computes correlation, not convolution:

dst( x , y ) = ∑ 0 ≤ x ′ < kernel.cols 0 ≤ y ′ < kernel.rows kernel( x ′ , y ′ ) ∗ src ( x + x ′ − anchor.x , y + y ′ − anchor .y ) \texttt{dst} (x,y) = \sum _{ \substack{0\leq x' < \texttt{kernel.cols}\\{0\leq y' < \texttt{kernel.rows} }}} \texttt{kernel} (x',y')* \texttt{src} (x+x'- \texttt{anchor.x} ,y+y'- \texttt{anchor.y} )dst(x,y)=0x<kernel.cols0y<kernel.rowskernel(x,y)src(x+xanchor.x,y+yanchor.y)

That is, the kernel is not mirrored around the anchor. If you need to do convolution, you can use the Flip function to flip the kernel and set the anchor point to (kernel.cols - anchro.x - 1,kernel.rows - anchor.y -1). When the kernel size is greater than or equal to (11x11), it is based on the DFT (Discrete Fourier Transform) algorithm, and the direct algorithm is used when the kernel is small.
//函数原型
void Filter2D(InputArray src,
	OutputArray dst,
	MatType ddepth,
	InputArray kernel,
	Point? anchor = null,
	double delta = 0.0,
	BorderTypes borderType = BorderTypes.Reflect101)`
parameter illustrate                            
InputArray src input image
OutputArray dst Output image. The size and number of channels are the same as the input image
MatType ddepth The desired output depth, see the Depth combinations table for details.
InputArray kernel Convolution kernel (correlation kernel): single-channel floating point matrix. If you want to use different kernels for different channels, you can first separate the image with Split and process it separately.
Point? anchor The anchor point of the core, the default value is null or (-1,-1), indicating the center point of the core
double delta Add this value to the calculation result, which can be understood as brightening (positive number) or darkening (negative number)
BorderTypes borderType Method to obtain pixel values ​​outside the border, Wrap is not supported

Depth combinations

Input depth (Src.Depth() Output depth (-1 means the same as the input depth)                   
CV_8U -1/CV_16S/CV_32F/CV_64F
CV_16U/CV_16S -1/CV_32F/CV_64F
CV_32F -1/CV_32F
CV_64F -1/CV_64F

SepFilter2D separable linear filtering

Function description: Perform separable linear filtering on the image. First, use the one-dimensional kernel KernelX to perform filtering calculation on each row, then use the one-dimensional kernel KernelY to perform filtering calculation on each column, and then add the result to Delta to generate the final image.

//函数原型
void SepFilter2D(InputArray src,
	OutputArray dst,
	MatType ddepth,
	InputArray kernelX,
	InputArray kernelY,
	Point? anchor = null,
	double delta = 0.0,
	BorderTypes borderType = BorderTypes.Reflect101)
parameter illustrate                            
InputArray src input image
OutputArray dst Output image. The size and number of channels are the same as the input image
MatType ddepth The desired output depth, see the Depth combinations table for details.
InputArray kernelX Row filter kernel (must be one-dimensional, cols or rows equals 1)
InputArray kernelY Column filter kernel (must be one-dimensional, cols or rows equals 1)
Point? anchor The anchor point of the core, the default value is null or (-1,-1), indicating the center point of the core
double delta Add this value to the calculation result, which can be understood as brightening (positive number) or darkening (negative number)
BorderTypes borderType Method to obtain pixel values ​​outside the border, Wrap is not supported

Purpose

Use the kernel of the specified size to perform Filter2D and SepFilter2D linear filtering on the selected image
. When the kernel is 3x3, the calculation formula is as follows

K = 1 3 ⋅ 3 [ 1 1 1 1 1 1 1 1 ] K = \dfrac{1}{3 \cdot 3} \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ &1&1\end{bmatrix}K=331 111111111

The program can drag the scroll bar to specify the core size and Delta value.

Image example

Filter2D example
SepFilter2D example

code example

Mat src;
string winName = "Filter2D Demo Esc:退出";

double delta = 0;
public void Run()
{
    
    
    //如果未选择图像,则用默认的Lena
    if (!Utils.SelectFile(out string fileName)) fileName = ImagePath.Lena;
    src = Cv2.ImRead(fileName, ImreadModes.Color);
    if (src.Empty()) throw new Exception($"图像打开有误:{
      
      fileName}");
    Cv2.NamedWindow(winName, WindowFlags.Normal);
    Cv2.CreateTrackbar("Size 2n+1", winName, 30, SizeOnChanged);
    Cv2.CreateTrackbar("Delta n-100", winName, 200, DeltaOnChanged);
    Cv2.SetTrackbarPos("Delta n-100", winName, 100);
    while(true)
    {
    
    
        //Esc退出
        if ((Cv2.WaitKey(50) == 27)) break;
    }
    Cv2.DestroyAllWindows();
}

private void OnChanged()
{
    
    
    Mat kernel = Mat.Ones(new Size(kernelSize, kernelSize), MatType.CV_32F) / (float)(kernelSize * kernelSize);
    using var filter2DResult = new Mat();
    Cv2.Filter2D(src, filter2DResult, -1, kernel, null, delta, BorderTypes.Default);
   
    Utils.PutText(filter2DResult, $"Size={
      
      kernelSize},delta={
      
      delta.ToString("0.0")}");
    Cv2.ImShow(winName, filter2DResult);

    using var sepFilter2DResult = new Mat();

    Mat kernelX = Mat.Ones(new Size(kernelSize, 1), MatType.CV_32F) / (float)kernelSize;
    Mat kernelY = Mat.Ones(new Size(1, kernelSize), MatType.CV_32F) / (float)kernelSize;
    //kernelX与kernelY必须是一维(cols或rows其中一个必须为1)
    Cv2.SepFilter2D(src, sepFilter2DResult, -1, kernelX, kernelY, null, delta, BorderTypes.Default);
    // 只要核的cols或rows为1,也可以这样调用,具体根据实际情况定义kernelX与kernelY
    //Cv2.SepFilter2D(src, dst2, -1, kernelY, kernelX, null, delta, BorderTypes.Default);

    Utils.PutText(sepFilter2DResult, $"Size={
      
      kernelSize},delta={
      
      delta.ToString("0.0")}");
    Cv2.NamedWindow("SepFilter2D", WindowFlags.Normal);
    Cv2.ImShow("SepFilter2D", sepFilter2DResult);
}

int kernelSize = 1;
/// <summary>
/// 改变核大小
/// </summary>
/// <param name="pos"></param>
/// <param name="userData"></param>
private void SizeOnChanged(int pos, IntPtr userData)
{
    
    
    kernelSize = pos * 2 + 1;
    OnChanged();
}
/// <summary>
/// 改变Delta值
/// </summary>
/// <param name="pos"></param>
/// <param name="userData"></param>
private void DeltaOnChanged(int pos, IntPtr userData)
{
    
    
    delta = pos -100;
    OnChanged();
}

OpenCvSharp function examples (directory)
refer to
https://docs.opencv.org/4.7.0/d4/dbd/tutorial_filter_2d.html

Guess you like

Origin blog.csdn.net/TyroneKing/article/details/130180091