1// UndistortImage Distortion Correction
 2func UndistortImage(imgData []byte, imgSize image.Point, cameraMatrix gocv.Mat, distCoeffs gocv.Mat, newCameraMatrix gocv.Mat) ([]byte, error) {
 3	mapx := gocv.NewMatWithSize(imgSize.X, imgSize.Y, gocv.MatTypeCV32F)
 4	defer mapx.Close()
 5	mapy := gocv.NewMatWithSize(imgSize.X, imgSize.Y, gocv.MatTypeCV32F)
 6	defer mapy.Close()
 7	r := gocv.Eye(3, 3, gocv.MatTypeCV32F)
 8	defer r.Close()
 9
10	// Initialize the correction map
11	gocv.InitUndistortRectifyMap(cameraMatrix, distCoeffs, r, newCameraMatrix, imgSize, int(gocv.MatTypeCV32F), mapx, mapy)
12	// Save the corrected image
13	src, err := gocv.IMDecode(imgData, gocv.IMReadGrayScale)
14	if err != nil {
15		return nil, err
16	}
17	defer src.Close()
18	dst := gocv.NewMat()
19	defer dst.Close()
20	gocv.Remap(src, &dst, &mapx, &mapy, gocv.InterpolationLinear, gocv.BorderConstant, color.RGBA{0, 0, 0, 0})
21
22	// Convert Mat to []byte
23	imgBuf, err := gocv.IMEncode(".bmp", dst)
24	if err != nil {
25		return nil, i18n.WrapError(err, "Alg.Tag.EncodeImgFailed")
26	}
27	defer imgBuf.Close()
28	// After imgBuf is closed, external use of this return value will cause an error, so a copy is needed
29	b := make([]byte, imgBuf.Len())
30	copy(b, imgBuf.GetBytes())
31
32	return b, nil
33}