Пример #1
0
def calibrate():
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
    Nx_cor = 9
    Ny_cor = 6

    objp = np.zeros((Nx_cor * Ny_cor, 3), np.float32)
    objp[:, :2] = np.mgrid[0:Nx_cor, 0:Ny_cor].T.reshape(-1, 2)
    objpoints = []  # 3d points in real world space
    imgpoints = []  # 2d points in image plane.

    count = 0  # count 用来标志成功检测到的棋盘格画面数量
    while (True):

        ret, frame = cap.read()

        if cv2.waitKey(1) & 0xFF == ord(' '):

            # Our operations on the frame come here
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

            ret, corners = cv2.findChessboardCorners(gray, (Nx_cor, Ny_cor),
                                                     None)  # Find the corners
            # If found, add object points, image points
            if ret == True:
                corners = cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1),
                                           criteria)
                objpoints.append(objp)
                imgpoints.append(corners)
                cv2.drawChessboardCorners(frame, (Nx_cor, Ny_cor), corners,
                                          ret)
                count += 1

                if count > 20:
                    break

        # Display the resulting frame
        cv2.imshow('frame', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    global mtx, dist

    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints,
                                                       gray.shape[::-1], None,
                                                       None)
    print(mtx, dist)

    mean_error = 0
    for i in range(len(objpoints)):
        imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i],
                                          mtx, dist)
        error = cv2.norm(imgpoints[i], imgpoints2,
                         cv2.NORM_L2) / len(imgpoints2)
        mean_error += error

    print("total error: ", mean_error / len(objpoints))
    # # When everything done, release the capture

    np.savez('calibrate.npz', mtx=mtx, dist=dist[0:4])
Пример #2
0
def calibrateOne(img_path, cameraParam):
    criteria = (cv2.TERM_CRITERIA_MAX_ITER | cv2.TERM_CRITERIA_EPS, 30, 0.001)
    #设置寻找亚像素角点的参数,采用的停止准则是最大循环次数30和最大误差容限0.001
    #获取标定板角点的位置
    objp = np.zeros((4 * 7, 3), np.float32)
    objp[:, :2] = np.mgrid[0:7, 0:4].T.reshape(-1, 2)  #将世界坐标系建在标定板上

    obj_points = []  #3D points
    img_points = []  #2D points

    images = glob.glob(img_path)
    i = 0
    for fname in images:
        img = cv2.imread(fname)
        #print(fname)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        size = gray.shape[::-1]
        h, w = gray.shape[:2]
        ret, corners = cv2.findChessboardCorners(gray, (7, 4), None)
        if ret:
            obj_points.append(objp)

            corners2 = cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1),
                                        criteria)
            #在原角点的基础上寻找亚像素点
            #print(corners2)
            if [corners2]:
                img_points.append(corners2)
            else:
                img_points.append(corners)
            cv2.drawChessboardCorners(img, (7, 4), corners, ret)
            i += 1

    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points,
                                                       size, None, None,
                                                       criteria)
    #dist——>dist coffients(就是k、p的值)

    newcameramtx, roi = cv2.getOptimalNewCameraMatrix(
        mtx, dist, (w, h), 1, (w, h))  #显示更大范围的图片(正常重映射之后会删掉一部分图像)
    #将fx,fy(世界坐标系的焦距)投射到fu,fv(图像坐标系的焦距)上,立体矫正时会用
    #dst = cv2.undistort(img,mtx,dist,None,newcameramtx)
    #x,y,w,h = roi

    cameraParam['ret'] = ret
    cameraParam['mtx'] = mtx
    cameraParam['dist'] = dist
    cameraParam['rvecs'] = rvecs
    cameraParam['tvecs'] = tvecs
    cameraParam['img_points'] = img_points
    cameraParam['obj_points'] = obj_points
    cameraParam['size'] = size
    cameraParam['newmtx'] = newcameramtx
    print("Calibrate One Camera Success")
Пример #3
0
def find_corners(images, windows, chessboard):
    """Display chessboard corners on input images."""

    retvals = [[False] for __ in range(len(images))]
    corners = [[None] for __ in range(len(images))]

    for i, (image, window) in enumerate(zip(images, windows)):
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        retvals[i], corners[i] = cv2.findChessboardCorners(
            image, chessboard.dims)
        cv2.drawChessboardCorners(image, chessboard.dims, corners[i],
                                  retvals[i])
        cv2.imshow(window, image)

    return retvals, corners
Пример #4
0
    def _update_img_obj_points(self, index: int, original_image: np.ndarray,
                               gray_scale_img: np.ndarray, is_dev: bool):
        found_corners, corners = cv2.findChessboardCorners(
            gray_scale_img, self.pattern_size, None)
        calibrated_image = copy.copy(original_image)
        if found_corners is True:
            self._objpoints.append(self._objp)
            self._imgpoints.append(corners)
            cv2.drawChessboardCorners(calibrated_image, self.pattern_size,
                                      corners, found_corners)
            cv2.imwrite('camera_cal_output/calibrated-' + str(index) + '.jpg',
                        calibrated_image)

            if is_dev is True:
                _, (ax1, ax2) = plt.subplots(1, 2, figsize=(20, 10))
                ax1.set_title('Original Image')
                ax1.imshow(original_image)

                ax2.set_title('Image clibration')
                ax2.imshow(calibrated_image)
Пример #5
0
    def findcorners(self):
        plt.close('all')

        # termination criteria
        criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30,
                    0.001)
        # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
        objp = np.zeros((11 * 8, 3), np.float32)
        objp[:, :2] = np.mgrid[0:11, 0:8].T.reshape(-1, 2)
        # Arrays to store object points and image points from all the images.
        objpoints = []  # 3d point in real world space
        imgpoints = []  # 2d points in image plane.

        for i in range(1, 16):
            img_name = str(i) + '.bmp'
            fname = os.path.join('Datasets/Q2_Image', img_name)

            img = cv.imread(fname)
            gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
            # Find the chess board corners
            ret, corners = cv.findChessboardCorners(gray, (11, 8), None)
            # If found, add object points, image points (after refining them)
            if ret == True:
                objpoints.append(objp)
                corners2 = cv.cornerSubPix(gray, corners, (11, 11), (-1, -1),
                                           criteria)
                imgpoints.append(corners)
                # Draw and display the corners
                cv.drawChessboardCorners(img, (11, 8), corners2, ret)
                plt_img = img[:, :, ::-1]
                plt.figure(fname)
                plt.imshow(plt_img)

        ret, mtx, dist, rvecs, tvecs = cv.calibrateCamera(
            objpoints, imgpoints, gray.shape[::-1], None, None)

        np.savez('output.npz', mtx, dist, rvecs, tvecs)
        np.savez('img_obj_points.npz', imgpoints, objpoints)

        plt.show()
    h1, w1 = img.shape[0], img.shape[1]
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    u, v = img.shape[:2]
    # 找到棋盘格角点
    ret, corners = cv2.findChessboardCorners(gray, (w,h),None)
    # 如果找到足够点对,将其存储起来
    if ret == True:
        print("i:", i)
        i = i+1
        # 在原角点的基础上寻找亚像素角点
        cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
        #追加进入世界三维点和平面二维点中
        objpoints.append(objp)
        imgpoints.append(corners)
        # 将角点在图像上显示
        cv2.drawChessboardCorners(img, (w,h), corners, ret)
        cv2.namedWindow('findCorners', cv2.WINDOW_NORMAL)
        cv2.resizeWindow('findCorners', 640, 480)
        cv2.imshow('findCorners',img)
        cv2.waitKey(200)
cv2.destroyAllWindows()
#%% 标定
print('正在计算')
#标定
ret, mtx, dist, rvecs, tvecs = \
    cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)


print("ret:",ret  )
print("mtx:\n",mtx)      # 内参数矩阵
print("dist畸变值:\n",dist   )   # 畸变系数   distortion cofficients = (k_1,k_2,p_1,p_2,k_3)
Пример #7
0
        t = str(i)
        print(t)
        originL = cv2.imread(PATH_CALIBRATION_IMAGE_CAM1 + t + '.png')
        originR = cv2.imread(PATH_CALIBRATION_IMAGE_CAM2 + t + '.png')
        ChessImaL = cv2.imread(PATH_CALIBRATION_IMAGE_CAM1 + t + '.png',
                               0)  # Left side
        ChessImaR = cv2.imread(PATH_CALIBRATION_IMAGE_CAM2 + t + '.png',
                               0)  # Right side

        retR, cornersR = cv2.findChessboardCorners(
            ChessImaR, (ChessWidth, ChessHeight),
            None)  # Define the number of chees corners we are looking for
        retL, cornersL = cv2.findChessboardCorners(ChessImaL,
                                                   (ChessWidth, ChessHeight),
                                                   None)  # Left side
        cv2.drawChessboardCorners(originR, (ChessWidth, ChessHeight), cornersR,
                                  retR)
        cv2.drawChessboardCorners(originL, (ChessWidth, ChessHeight), cornersL,
                                  retL)

        while True:
            cv2.imshow('Corner', np.hstack((originL, originR)))
            if (cv2.waitKey(1) & 0xFF == ord('n')):
                print("Couple with " + t + " has been added")
                if (True == retR) & (True == retL):
                    objpoints.append(objp)
                    cv2.cornerSubPix(ChessImaR, cornersR, (11, 11), (-1, -1),
                                     criteria)
                    cv2.cornerSubPix(ChessImaL, cornersL, (11, 11), (-1, -1),
                                     criteria)
                    imgpointsR.append(cornersR)
                    imgpointsL.append(cornersL)
Пример #8
0
def calibration(images):

    # termination criteria
    criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)

    # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
    objp = np.zeros((7 * 10, 3), np.float32)
    objp[:, :2] = np.mgrid[0:7, 0:10].T.reshape(-1, 2)

    # Arrays to store object points and image points from all the images.
    objpoints = []  # 3d point in real world space
    imgpoints = []  # 2d points in image plane.

    for fname in images:

        img = cv.imread(fname)
        gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
        # Find the chess board corners
        ret, corners = cv.findChessboardCorners(gray, (7, 10), None)
        # If found, add object points, image points (after refining them)
        if ret == True:

            objpoints.append(objp)
            corners2 = cv.cornerSubPix(gray, corners, (11, 11), (-1, -1),
                                       criteria)
            imgpoints.append(corners)
            # Draw and display the corners
            cv.drawChessboardCorners(img, (7, 10), corners2, ret)
            img_resized = cv.resize(img, (1400, 700))
            cv.imshow('img', img_resized)
            cv.waitKey(10)

    cv.destroyAllWindows()

    ret, K, dist, rvecs, tvecs, std_int, std_ext, pVE = \
        cv.calibrateCameraExtended(objpoints, imgpoints, gray.shape[::-1], None, None)

    mean_error = []
    error_vecs = np.zeros(
        (70 * len(images),
         2))  # vertical stack of [x, y] errors for all points in all pictures
    for i in range(len(objpoints)):  # calculating errors
        imgpoints2, _ = cv.projectPoints(objpoints[i], rvecs[i], tvecs[i], K,
                                         dist)
        error = cv.norm(imgpoints[i], imgpoints2, cv.NORM_L2) / len(imgpoints2)
        mean_error.append(error)

        imgpoints2 = np.array(imgpoints2)
        imgpoints2 = imgpoints2[:, 0, :]
        imgpoints1 = np.array(imgpoints[i])
        imgpoints1 = imgpoints1[:, 0, :]
        error_vecs[i * 70:(i + 1) * 70, :] = imgpoints1 - imgpoints2

    fig = plt.figure(1)  # mean reprojection error plot
    img_nr = [f"{i+1}" for i in range(len(images))]
    plt.bar(img_nr, mean_error)
    plt.ylabel("mean reprojection error")
    plt.xlabel("image number")
    plt.savefig("Calibration_errors")
    plt.show()

    fig2 = plt.figure(2)
    plt.scatter(error_vecs[:, 0], error_vecs[:, 1])
    plt.ylabel("y error")
    plt.xlabel("x error")
    plt.savefig("Reprojection_scatter")
    plt.show()

    print('Standard errors')
    print('Focal length and principal point')
    print('--------------------------------')
    print('fx: %g +/- %g' % (K[0, 0], std_int[0]))
    print('fy: %g +/- %g' % (K[1, 1], std_int[1]))
    print('cx: %g +/- %g' % (K[0, 2], std_int[2]))
    print('cy: %g +/- %g' % (K[1, 2], std_int[3]))
    print('Distortion coefficients')
    print('--------------------------------')
    print('k1: %g +/- %g' % (dist[0, 0], std_int[4]))
    print('k2: %g +/- %g' % (dist[0, 1], std_int[5]))
    print('p1: %g +/- %g' % (dist[0, 2], std_int[6]))
    print('p2: %g +/- %g' % (dist[0, 3], std_int[7]))
    print('k3: %g +/- %g' % (dist[0, 4], std_int[8]))

    np.savetxt('cam_matrix.txt', K)
    np.savetxt('dist.txt', dist)
    np.savetxt('stdInt.txt', std_int)
    np.savetxt('stdExt.txt', std_ext)
Пример #9
0
    # 提取角点
    ret, corners = cv2.findChessboardCorners(gray, (8, 6), None)
    # print("ret = ", ret)
    # print(corners)
    if ret:
        obj_points.append(objp)
        # 找寻亚像素角点
        corners2 = cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1),
                                    criteria)  # 在原角点的基础上寻找亚像素角点
        # print(corners2)
        if [corners2]:
            img_points.append(corners2)
        else:
            img_points.append(corners)
        # 把角点画出来
        cv2.drawChessboardCorners(img, (8, 6), corners,
                                  ret)  # 记住,OpenCV的绘制函数一般无返回值
        # cv2.imwrite('c-'+str(0).zfill(4)+'.png', img) # 文件命名补齐函数zfill
        # 保存绘制角度后的图像
        # cv2.imwrite(image_name +".png", img)
# print(len(img_points))
# cv2.destroyAllWindows()

# 标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points,
                                                   size, None, None)
# print("ret:", ret)
# print("mtx:\n", mtx) # 内参数矩阵
# print("dist:\n", dist)  # 畸变系数   distortion cofficients = (k_1,k_2,p_1,p_2,k_3)
# print("rvecs:\n", rvecs)  # 旋转向量  # 外参数
# print("tvecs:\n", tvecs ) # 平移向量  # 外参数
# print("-----------------------------------------------------")
Пример #10
0
while (cap.isOpened()):
    ret, frame = cap.read()
    if ret == True:
        frame = skip_frame(cap)
        r_frame = cv2_helpers.get_resized(frame, 40)
        r_frame_bw = cv2_helpers.get_resized_and_bw(frame, 40)
        cv2.imshow("something", r_frame)
        found_corners, corners = cv2.findChessboardCorners(
            r_frame_bw, (nx, ny), None)
        if found_corners:
            frames_with_corners += 1
            objpoints.append(objp)
            corners2 = cv2.cornerSubPix(r_frame_bw, corners, (11, 11),
                                        (-1, -1), criteria)
            imgpoints.append(corners2)
            new_img = cv2.drawChessboardCorners(r_frame, (nx, ny), corners,
                                                ret)
            cv2.imshow("test", new_img)
            if frames_with_corners == 16:
                break

cap.release()
cv2.destroyAllWindows()

print("callibrating the given video...")
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints,
                                                   r_frame_bw.shape[::-1],
                                                   None, None)

print("ret: ", ret)
print("mtx: ", mtx)
print("dist: ", dist)
Пример #11
0
images = glob.glob('chessboards/*.png')

for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Find the chess board corners
    ret, corners = cv2.findChessboardCorners(gray, (7, 6), None)

    # If found, add object points, image points (after refining them)
    if ret:
        objpoints.append(objp)

        corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1),
                                    criteria)
        imgpoints.append(corners2)

        # Draw and display the corners
        img = cv2.drawChessboardCorners(img, (7, 7), corners2, ret)
        cv2.imshow('img', img)
        cv2.waitKey(500)

    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints,
                                                       gray.shape[::-1], None,
                                                       None)
    print(rvecs)
    print(tvecs)

cv2.destroyAllWindows()
Пример #12
0
def calibrate():
    #棋盘角点数col*row
    col = 13
    row = 6

    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

    objp = np.zeros((row * col, 3), np.float32)
    # 用于标定的棋盘每个方格边长为22mm
    objp[:, :2] = 22*np.mgrid[0:col, 0:row].T.reshape(-1, 2)

    objpoints = []  # 世界坐标系下的点坐标
    imgpoints = []  # 像素平面坐标系下的点坐标
    print("请选择标定用到的照片所在的文件夹", "\n")

    root = tkinter.Tk()
    root.withdraw()

    global path  # 用于标定的照片所在目录
    path = tkinter.filedialog.askdirectory(
        title="选择标定用到的照片所在的文件夹")  # 选择标定用到的照片所在的文件夹
    images = glob.glob(path+"/*.jpg")
    found = 0  # 记录用于标定的图像数目
    for k, fname in enumerate(images):
        img = cv2.imread(fname)

        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        ret, corners = cv2.findChessboardCorners(gray, (col, row), None)
        # 角点检测

        if ret is True:
            print("读取", fname)
            objpoints.append(objp)

            
            # 角点检测精度会影响标定的精度
            corners2 = cv2.cornerSubPix(
                gray, corners, (11, 11), (-1, -1), criteria)#亚像素角点位置
            # corners2=corners
            #_,corners2=cv2.find4QuadCornerSubpix(gray, corners, (11, 11))

            imgpoints.append(corners2)
            img = cv2.drawChessboardCorners(img, (col, row), corners2, ret)#标记角点
            found += 1
            if len(images) < 16:  # 图片过多时,不在UI中展示,避免弹窗过多
                cv2.namedWindow('press any key to continue', cv2.WINDOW_NORMAL)
                cv2.imshow('press any key to continue', img)
                cv2.waitKey(0)

            #image_name = path2 + "//corner"+str(found) + '.png'
            #cv2.imwrite(image_name, img)
            #存储已标出角点的照片
            
    global path2  # 存放结果的目录(含记录相机参数的文件,和畸变矫正后的照片,3-D box照片)
    path2 = tkinter.filedialog.askdirectory(
        title="选择结果存放的文件夹(应与用于标定的照片所在的文件夹不同)")  # 选择结果存放的文件夹

    print("Number of images used for calibration: ", found)

    # 相机标定
    ret2, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints,
                                                        gray.shape[::-1], None, None)

    print("reprojection error:", ret2)
    print("内参矩阵:", mtx)
    print("畸变系数:", dist)
    print("旋转向量:", rvecs)
    print("平移向量:", tvecs)

    images = glob.glob(path+"//*.jpg")
    for i, fname in enumerate(images):
        img = cv2.imread(fname)
        if img is None:
            continue
        h, w = img.shape[:2]
        newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1,
                                                            (w, h))
        dst = cv2.undistort(img, mtx, dist, None, newcameramtx)  # 矫正畸变

        x, y, w, h = roi
        dst = dst[y:y + h, x:x + w]#裁剪
        outpath = path2+"//tianyi_gao_undistorted" + str(i + 1) + ".jpg"
        cv2.imwrite(outpath, dst)
    print("新内参矩阵:", newcameramtx)
    
    data = {
        'camera_matrix': np.asarray(mtx).tolist(),
        'dist_coeff': np.asarray(dist).tolist(),
        'new_camera_matrix': np.asarray(newcameramtx).tolist(),
        'rvecs': np.asarray(rvecs).tolist(),
        'tvecs': np.asarray(tvecs).tolist(),
        'reprojection_error': np.asarray(ret2).tolist()
    }
    # 存储相机参数(yaml)
    with open(path2+"//calibration_parameters.yaml", "w") as f:
        yaml.dump(data, f)
    # 存储相机参数(txt)
    with open(path2+"//tianyi_gao_cam.txt", "w") as f2:
        name = list(data.keys())
        value = list(data.values())
        for i in range(len(name)):
            f2.write(name[i] + ":" + "\n" + str(value[i]) + "\n")

    print('Calibrate Done')
    cv2.destroyAllWindows()
    return mtx, dist, rvecs, tvecs, ret2, path2
Пример #13
0
    img = cv2.imread('/calib_images/imgS'+(str)(i)+'.png')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Find the chess board corners
    ret, corners = cv2.findChessboardCorners(gray, (9, 6), None)

    # If found, add object points, image points (after refining them)
    if ret == True:
        objpoints.append(objp)

        corners2 = cv2.cornerSubPix(
            gray, corners, (11, 11), (-1, -1), criteria)
        imgpoints.append(corners2)

        # Draw and display the corners
        img = cv2.drawChessboardCorners(img, (cbcol, cbrow), corners2, ret)
        cv2.imshow('img', img)
        cv2.waitKey(WAIT_TIME)

cv2.destroyAllWindows()
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(
    objpoints, imgpoints, gray.shape[::-1], None, None)

# ---------- Saving the calibration -----------------
cv_file = cv2.FileStorage("calib_images/test.yaml", cv2.FILE_STORAGE_WRITE)
cv_file.write("camera_matrix", mtx)
cv_file.write("dist_coeff", dist)

# note you *release* you don't close() a FileStorage object
cv_file.release()
Пример #14
0
for i in range(1, 2):
    img_name = str(i) + '.bmp'
    fname = os.path.join('Datasets/Q2_Image', img_name)

    img = cv.imread(fname)
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    # Find the chess board corners
    ret, corners = cv.findChessboardCorners(gray, (11, 8), None)
    # If found, add object points, image points (after refining them)
    if ret == True:
        objpoints.append(objp)
        corners2 = cv.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
        imgpoints.append(corners)
        # Draw and display the corners
        cv.drawChessboardCorners(img, (11, 8), corners2, ret)

        ret, mtx, dist, rvecs, tvecs = cv.calibrateCamera(
            objpoints, imgpoints, gray.shape[::-1], None, None)

        h, w = img.shape[:2]
        newcameramtx, roi = cv.getOptimalNewCameraMatrix(
            mtx, dist, (w, h), 1, (w, h))
        # print(roi)
        mapx, mapy = cv.initUndistortRectifyMap(mtx, dist, None, newcameramtx,
                                                (w, h), 5)
        dst = cv.remap(img, mapx, mapy, cv.INTER_LINEAR)

        x, y, w, h = roi
        dst = dst[y:y + h, x:x + w]