Image perspective transformation

Perspective Transformation refers to a Transformation that makes the shadow plane (Perspective plane) rotate a certain Angle around the trace line (Perspective axis) according to the Perspective rotation law under the condition that the center, image point and target point are collinear, destroys the original projected ray beam, and still keeps the projected geometric figure on the shadow plane unchanged. Perspective transformation is based on the law of object imaging projection transformation, that is, the object is re-projected to a new imaging plane. Perspective transformation is often used in the research of robot visual navigation. Because of the oblique Angle between the camera field and the ground, the object image is distorted, so perspective transformation is usually used to correct the object image.

The principle of

1
2
3
4

There are eight unknowns in the equation system of perspective transformation, so the solution needs to find four groups of mapping points, and four points just determine a three-dimensional space.


API

Take the transformation matrix

public static Mat getPerspectiveTransform(Mat src, Mat dst, int solveMethod)

Copy the code
  • Parameter 1: SRC, four pixel coordinates in the original image
  • Parameter two: DST, four pixel coordinates in the target image
  • Parameter 3: solveMethod, select the symbol of the method to calculate perspective transformation matrix. By default, select the Gaussian elimination method DECOMP_LU of the best spindle element
enum DecompTypes {

DECOMP_LU = 0.

DECOMP_SVD = 1.

DECOMP_EIG = 2.

DECOMP_CHOLESKY = 3.

DECOMP_QR = 4.

DECOMP_NORMAL = 16

};

Copy the code
Sign a value role
DECOMP_LU 0 Gaussian elimination method for optimum principal axis elements
DECOMP_SVD 1 Singular value decomposition (SVD) method
DECOMP_EIG 2 Eigenvalue decomposition method
DECOMP_CHOLESKY 3 Cholesky decomposition method
DECOMP_QR 4 QR decomposition method
DECOMP_NORMAL 16 To use the normal equation formula, you can use it in conjunction with the previous symbol

Perspective transformation

public static void warpPerspective(Mat src, Mat dst, Mat M, Size dsize, int flags, int borderMode, Scalar borderValue) 

Copy the code
  • Parameter 1: SRC, original image

  • Parameter 2: DST, output image after perspective transformation, same data type as SRC, but same size as Dsize

  • Parameter 3: M, 3*3 transformation matrix

  • Parameter 4: Dsize, output image size

  • Parameter 5: flags, interpolation method flags

    // C++: enum InterpolationFlags

    public static final int

    INTER_NEAREST = 0.

    INTER_LINEAR = 1.

    INTER_CUBIC = 2.

    INTER_AREA = 3.

    INTER_LANCZOS4 = 4.

    INTER_LINEAR_EXACT = 5.

    INTER_MAX = 7.

    WARP_FILL_OUTLIERS = 8.

    WARP_INVERSE_MAP = 16;

    Copy the code
  • Parameter 6: borderMode, the flag of the pixel boundary extrapolation method. BORDER_CONSTANT or BORDER_REPLICATE

  • Parameter seven: borderValue, the number used to fill the border, 0 by default

operation

The following code realizes that the image taken by the camera whose line of sight is not perpendicular to the road plane is transformed into an image taken by the camera whose line of sight is perpendicular to the road plane through perspective transformation.

class PerspectiveTransformationActivity : AppCompatActivity() {



private lateinit var mBinding: ActivityPerspectiveTransformationBinding

private lateinit var mRgb: Mat

override fun onCreate(savedInstanceState: Bundle?). {

super.onCreate(savedInstanceState)

mBinding =

DataBindingUtil.setContentView(this, R.layout.activity_perspective_transformation)



val bgr = Utils.loadResource(this, R.drawable.road)

mRgb = Mat()

Imgproc.cvtColor(bgr, mRgb, Imgproc.COLOR_BGR2RGB)

showMat(mBinding.ivRoad, mRgb)



doPerspectiveTransform()

}



private fun showMat(view: ImageView, source: Mat) {

val bitmap = Bitmap.createBitmap(source.width(), source.height(), Bitmap.Config.ARGB_8888)

Utils.matToBitmap(source, bitmap)

view.setImageBitmap(bitmap)

}



private fun getPerspectiveTransform(a): Mat {

val srcPoints = ArrayList<Point>()

val p1 = Point(325.0000.374.0000)

srcPoints.add(p1)

val p2 = Point(597.0000.374.0000)

srcPoints.add(p2)

val p3 = Point(960.0000.505.0000)

srcPoints.add(p3)

val p0 = Point(0.0000.505.0000)

srcPoints.add(p0)

val srcMat = Converters.vector_Point2f_to_Mat(srcPoints)



val resultWidth = 500.0

val resultHeight = 500.0

val dstPoints = ArrayList<Point>()

val p5 = Point(0.0.0.0)

dstPoints.add(p5)

val p6 = Point(resultWidth, 0.0)

dstPoints.add(p6)

val p7 = Point(resultWidth, resultHeight)

dstPoints.add(p7)

val p4 = Point(0.0, resultHeight)

dstPoints.add(p4)

val dstMat = Converters.vector_Point2f_to_Mat(dstPoints)

return Imgproc.getPerspectiveTransform(srcMat, dstMat)

}



private fun doPerspectiveTransform(a) {

val transform = getPerspectiveTransform()

val dst = Mat()

Imgproc.warpPerspective(

mRgb,

dst,

transform,

Size(500.0.500.0),

Imgproc.INTER_NEAREST

)

showMat(mBinding.ivResult, dst)

}



override fun onDestroy(a) {

mRgb.release()

super.onDestroy()

}

}

Copy the code

The effect

Perspective transformation

The source code

Github.com/onlyloveyd/…


This article is formatted using MDNICE