This is the 24th day of my participation in Gwen Challenge

Shi-tomasi corner detection

In Harris corner point detection, Harris corner point evaluation coefficient R is expressed as:


R = d e t ( M ) k ( t r a c e ( M ) ) 2 R=det(M)-k(trace(M))^2

d e t ( M ) = Lambda. 1 Lambda. 2 Det (M) = lambda _1 lambda _2

t r a c e ( M ) = Lambda. 1 + Lambda. 2 Trace (M) = lambda _1 + lambda _2

Among them d e t ( M ) = Lambda. 1 Lambda. 2 Is the determinant of the matrix, t r a c e ( M ) = Lambda. 1 + Lambda. 2 It’s the trace of the matrix Where det(M)=λ_1λ_2 is the determinant and trace(M)=λ_1+λ_2 is the trace of the matrix

λ1 and λ2 are eigenvalues of the matrix M, and k is an empirical constant in the range (0.04, 0.06). Since the stability of Harris corner detection algorithm is related to k value, and K is an empirical value, it is difficult to set the optimal value, and the stability of corner point is related to the smaller eigenvalue of matrix M, so the smaller eigenvalue is directly used as the evaluation coefficient. Therefore, in shi-Tomasi algorithm, evaluation coefficient R is expressed as:


R = m i n ( Lambda. 1 . Lambda. 2 ) R = min (lambda _1, lambda _2)

If the R value of a pixel is greater than the threshold, the pixel is an Angle point. Plot it into a space λ1 ~ λ2 and you get the following:

API

public static void goodFeaturesToTrack(Mat image, MatOfPoint corners, int maxCorners, double qualityLevel, double minDistance, Mat mask, int blockSize, boolean useHarrisDetector, double k)
Copy the code
  • Parameter 1: image, input source image. The type must be single-channel 8U or 32F.
  • Parameter 2: corners, the output of detected corners.
  • Parameter 3: maxCorners returns the maximum number of corners. If the number of corners actually detected is greater than the maximum number returned, the strongest maxCorners is returned. If this parameter is set to 0, there is no restriction.
  • Parameter 4: qualityLevel, which represents the lowest acceptable level of image corner points. For example, if the evaluation coefficient of the strongest corner is 1500 and this parameter is 0.01, all the evaluation coefficients lower than 15 will be excluded. If they are not corner points, that is, 15 is the threshold of detection corner points.
  • Parameter 5: minDistance, the minimum Euclidean distance between corners.
  • Parameter 6: Mask, mask matrix, represents the detection corner area. If the parameter is not empty, it must be a single-channel 8U image of the same size as the source image.
  • Parameter 7: blockSize, calculate the size of gradient covariance matrix.
  • Parameter 8: useHarrisDetector: Specifies whether to useHarris corner detection. The default value is false and the Shi-Tomasi algorithm is used.
  • Parameter 9: k, weight coefficient in Harris corner detection process.

operation

/** * shi-tomas * author: yidong * 2021/1/7 */
class ShiTomasiActivity : AppCompatActivity() {

    private val gray by lazy {
        getBgrFromResId(R.drawable.lena).toGray()
    }
    private val rgb by lazy {
        getBgrFromResId(R.drawable.lena).toRgb()
    }
    private val mBinding: ActivityShiTomasBinding by lazy {
        ActivityShiTomasBinding.inflate(layoutInflater)
    }

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContentView(mBinding.root)
        mBinding.ivLena.showMat(gray)
        wrapCoroutine({ showLoading() }, { doShiTomas() }, { hideLoading() })
    }

    private fun doShiTomas(a) {
        val corners = MatOfPoint()
        val maxCorners = 100;
        val qualityLevel = 0.1
        val minDistance = 0.04
        
        Imgproc.goodFeaturesToTrack(
            gray,
            corners,
            maxCorners,
            qualityLevel,
            minDistance,
            Mat(),
            3.false
        )
        val points = corners.toList()
        val result = rgb.clone()
        GlobalScope.launch(Dispatchers.Main) {
            for (point in points) {
                Imgproc.circle(result, point, 10, Scalar(0.0.255.0.0.0), 2, Imgproc.LINE_8)
            }
            mBinding.ivResult.showMat(result)
        }
    }

    private fun showLoading(a) {
        mBinding.isLoading = true
    }

    private fun hideLoading(a) {
        mBinding.isLoading = false
    }

    override fun onDestroy(a) {
        super.onDestroy()
        gray.release()
        rgb.release()
    }
}
Copy the code

The effect

The source code

Github.com/onlyloveyd/…