Sobel operator

Sobel operator is an important processing method in computer vision field.

It is mainly used to obtain the first step of digital image, and its common application and physical significance is edge detection.

Sobel operator is the weighted difference between the gray values of the upper, lower, left and right fields of each pixel in the image and reaches the extreme value at the edge so as to detect the edge. Technically, it is a discrete difference operator for approximating the gradient of an image brightness function. Using this operator at any point in the image will produce the corresponding gradient vector or its normal vector. Sobel operator not only has a good detection effect, but also has a smooth suppression effect on noise, but the edge is thicker and false edge may appear.

The operator contains two groups of 3×3 matrices, namely transverse and longitudinal, which can be obtained by convolving them with the image plane. If A represents the original image, Gx and Gy represent the images detected by transverse and longitudinal edges respectively, the formula is as follows:

The approximate horizontal and vertical gradients of each pixel of the image can be combined with the following formula to calculate the magnitude of the gradient.The gradient direction can then be calculated by the following formula.In the example above, if the Angle θ equals zero, it means that the image has a vertical edge that is darker on the left than on the right.

API

public static void Sobel(Mat src, Mat dst, int ddepth, int dx, int dy, int ksize, double scale, double delta, int borderType)
Copy the code
  • Parameter one: SRC, enter the image.
  • Parameter two: DST, the output image, with the same size and number of channels as the input image.
  • Parameter 3: ddepth: data type (depth) of the output image. The value range varies according to the data type of the input image. When a value of -1 is assigned, the data type of the output image is automatically selected.
  • Parameter 4: dx, difference order in X direction.
  • Parameter 5: dy, the difference order in the Y direction
  • Parameter 6: ksize, the size of the Sobel edge operator, must be 1, 3, 5 or 7
  • Parameter 7: scale, the scale factor for scaling derivative calculation results, the default coefficient is 1, no scaling
  • Parameter eight: delta, offset value, add offset value to the calculation result.
  • Parameter 9: borderType, pixel extrapolation method select logo. The default parameter is BORDER_DEFAULT, which means that there is no inverse padding of boundary values.

The third, fourth and fifth parameters in the function are the key parameters to control the effect of image edge detection. The relationship between these three parameters is that the difference order in any direction should be smaller than the size of the filter. In particular, when Ksize =1, the order in any direction should be less than 3. In general, when the maximum difference order is 1, the filter size is 3. When the maximum difference order is 2, the filter size is 5. When the maximum difference order is 3, the filter size is 7. When the filter size ksize=1, the filter size used in the program is no longer a square, but 3×1 or 1×3. The last three parameters are the image scaling factor, offset and the flag of the image extrapolation filling method. In most cases, you do not need to set, just use the default parameters.

operation

/** * Sobel operator - edge detection **@author yidong
 * @dateThe 2020-01-07 * /
class SobelEdgeDetectionActivity : AppCompatActivity() {


    private lateinit var mBinding: ActivityEdgeDetectionBinding
    private lateinit var mRgb: Mat

    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_edge_detection)
        val bgr = Utils.loadResource(this, R.drawable.lena)
        mRgb = Mat()
        Imgproc.cvtColor(bgr, mRgb, Imgproc.COLOR_BGR2RGB)
        showMat(mBinding.ivLena, mRgb)
    }

    private fun showMat(view: ImageView, source: Mat) {
        val bitmap = Bitmap.createBitmap(source.width(), source.height(), Bitmap.Config.ARGB_8888)
        bitmap.density = 360
        Utils.matToBitmap(source, bitmap)
        view.setImageBitmap(bitmap)
    }

    override fun onCreateOptionsMenu(menu: Menu?).: Boolean {
        menuInflater.inflate(R.menu.menu_sobel, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.sobel_edge_detection_x -> {
                edgeDetectionX()
            }
            R.id.sobel_edge_detection_y -> {
                edgeDetectionY()
            }
            R.id.sobel_edge_detection_x_y -> {
                edgeDetectionXAndY()
            }
        }
        return true
    }

    private fun edgeDetectionX(a) {
        title = "X-axis edge detection"
        val resultX = Mat()
        Imgproc.Sobel(mRgb, resultX, CvType.CV_16S, 2.0.1)
        Core.convertScaleAbs(resultX, resultX)
        showMat(mBinding.ivResult, resultX)
    }


    private fun edgeDetectionY(a) {
        title = "Y-axis edge detection"
        val resultY = Mat()
        Imgproc.Sobel(mRgb, resultY, CvType.CV_16S, 0.1.3)
        Core.convertScaleAbs(resultY, resultY)
        showMat(mBinding.ivResult, resultY)
    }

    private fun edgeDetectionXAndY(a) {
        title = "X and Y direction edge detection"
        val resultX = Mat()
        Imgproc.Sobel(mRgb, resultX, CvType.CV_16S, 2.0.1)
        Core.convertScaleAbs(resultX, resultX)
        showMat(mBinding.ivResult, resultX)
        val resultY = Mat()
        Imgproc.Sobel(mRgb, resultY, CvType.CV_16S, 0.1.3)
        Core.convertScaleAbs(resultY, resultY)
        showMat(mBinding.ivResult, resultY)

        val resultXY = Mat()
        Core.add(resultX, resultY, resultXY)
        showMat(mBinding.ivResult, resultXY)

        resultX.release()
        resultY.release()
        resultXY.release()
    }
}
Copy the code

The effect

The source code

Github.com/onlyloveyd/…