This is the 22nd day of my participation in Gwen Challenge

Image interpolation

What is interpolation?

Interpolation is an important method for the approximation of discrete functions, which can be used to estimate the approximation of functions at other points by means of the values of functions at finite points.

What is image interpolation?

The process of producing a higher resolution image from a lower resolution image (amplification) to recover lost information in the image.

API

public static void resize(Mat src, Mat dst, Size dsize, double fx, double fy, int interpolation) 
Copy the code
  • Parameter 1: SRC, input the source image.

  • Parameter two: DST, output the target image.

  • Parameter 3: dsize, output target size. If this parameter is set to zero, the value is calculated using the following fx and fy parameters:


    dsize   =   Size(round(fx*src.cols),   round(fy*src.rows)) \texttt{dsize = Size(round(fx*src.cols), round(fy*src.rows))}
  • Parameter 4: FX, scale factor of X-axis. If this parameter is set to zero, its value is calculated by dsize:


    (double)dsize.width/src.cols \texttt{(double)dsize.width/src.cols}
  • Parameter 5: Fy, scale factor of Y-axis. If this parameter is set to zero, its value is calculated by dsize:


    (double)dsize.height/src.rows \texttt{(double)dsize.height/src.rows}
  • Parameter 6: Interpolation, interpolation algorithm flag bit.

    public static final int
            INTER_NEAREST = 0.// Nearest neighbor interpolation
            INTER_LINEAR = 1.// Bilinear interpolation
            INTER_CUBIC = 2.// Bicubic interpolation
            INTER_AREA = 3.// Resampling using pixel region relationships
            INTER_LANCZOS4 = 4.// Lanczos interpolation for 8x8 pixel neighborhoods
            INTER_LINEAR_EXACT = 5.// Bit-accurate bilinear interpolation
            INTER_NEAREST_EXACT = 6.// Bit-accurate nearest neighbor interpolation. This will yield the same results as the nearest neighbor methods in PIL, Scikit-Image or Matlab
    Copy the code

The interpolation method

INTER_NEAREST interpolation

Nearest neighbor interpolation method, find the neighbor with the closest distance (existing pixels, black dots), assign the same value.

Bilinear interpolation

Bilinear interpolation, also known as bilinear interpolation. In mathematics, bilinear interpolation is a linear interpolation extension of the interpolation function with two variables, and its core idea is to perform linear interpolation in two directions respectively.

Bicubic interpolation (INTER_CUBIC)

Bicubic interpolation is a more complex interpolation method that creates smoother edges than bilinear interpolation. In this method, the value of the function f at the point (x, y) can be obtained by a weighted average of the nearest sixteen sampling points in a rectangular grid, where two polynomial interpolation cubic functions are required, one in each direction.

As above, point P is the position of the target image B at (X,Y) corresponding to the source image A, assuming that the coordinate of P is (I + U,j+ V), where I and j represent the integer part and U and v represent the decimal part respectively. Find the position of the nearest 16 pixels to p, represented here by a(m,n)(m,n=0,1,2,3). The purpose of double cube interpolation is to find a relationship, or coefficient, to find out the influence factor of the 16 pixels on the pixel value at P, so as to obtain the pixel value of the corresponding point of the target image according to this influence factor, so as to achieve the purpose of image scaling. BiCubic basis function based BiCubic interpolation uses the following functions:

The weight coefficient is calculated by the distance between the 16 nearest points and point P. Then the pixel value of the corresponding position of the target image is obtained by multiplying the weight of the column and column and summing up the pixel value of each point.

Area interpolation (INTER_AREA)

Regional interpolation is divided into three cases, image magnification is similar to bilinear interpolation, and image shrinking (X-axis and Y-axis shrinking at the same time) is divided into two cases, in which ripple can be avoided. Therefore, in order to avoid the ripple phenomenon, the region interpolation method is recommended when the image is shrunk.

Lanczos Interpolation (INTER_LANCZOS4)

Lanthos interpolation, calculated from adjacent 8*8 pixels, is similar to bilinear. The operation mode is similar to bicubic interpolation, calculating distance, calculating weight, calculating column and column product, summing.

operation

/** ** 标 志 * author: yidong * 2020/12/27 */
class ResizeActivity : AppCompatActivity() {

    private val mList = mutableListOf<ImageTextObject>()
    private val mAdapter by lazy { ImageTextAdapter(this, mList) }
    private val mBinding: ActivityResizeBinding by lazy {
        ActivityResizeBinding.inflate(layoutInflater)
    }
    private val mFlags = mapOf(
        Imgproc.INTER_NEAREST to "INTER_NEAREST",
        Imgproc.INTER_LINEAR to "INTER_LINEAR",
        Imgproc.INTER_CUBIC to "INTER_CUBIC",
        Imgproc.INTER_AREA to "INTER_AREA",
        Imgproc.INTER_LANCZOS4 to "INTER_LANCZOS4"
    )

    private val rgb: Mat by lazy {
        val bgr = getBgrFromResId(R.drawable.tiny_lena)
        bgr.toRgb()
    }

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(mBinding.root)
        mBinding.container.adapter = mAdapter
        wrapCoroutine({ before() }, { doResize() }, { after() })
    }

    override fun onDestroy(a) {
        super.onDestroy()
        rgb.release()
    }

    private fun doResize(a) {
        val w = rgb.rows()
        val h = rgb.cols()

        for (i in mFlags) {
            val dst = Mat()
            Imgproc.resize(
                rgb,
                dst,
                Size((w * 100).toDouble(), (h * 100).toDouble()),
                0.0.0.0,
                i.key
            )
            mList.add(ImageTextObject(dst, mFlags.getOrElse(i.key) { ""}}}))private fun before(a) {
        mBinding.isLoading = true
    }

    private fun after(a) {
        mBinding.isLoading = false
        mAdapter.notifyDataSetChanged()
    }
}
Copy the code

The effect

The source code

Github.com/onlyloveyd/…