import%20marimo%0A%0A__generated_with%20%3D%20%220.24.0%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20from%20pathlib%20import%20Path%0A%0A%20%20%20%20import%20cv2%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20requests%0A%0A%20%20%20%20notebook_dir%20%3D%20Path(__file__).resolve().parent%20if%20%22__file__%22%20in%20globals()%20else%20Path.cwd()%0A%20%20%20%20repo_root%20%3D%20notebook_dir.parents%5B1%5D%0A%20%20%20%20data_dir%20%3D%20repo_root%20%2F%20%22data%22%20%2F%20%22cv%22%20%2F%20%22opencv_calibration%22%0A%20%20%20%20data_dir.mkdir(parents%3DTrue%2C%20exist_ok%3DTrue)%0A%0A%20%20%20%20opencv_ref%20%3D%20%224.11.0%22%0A%20%20%20%20image_names%20%3D%20%5Bf%22left%7Bindex%3A02d%7D.jpg%22%20for%20index%20in%20range(1%2C%2015)%20if%20index%20!%3D%2010%5D%0A%20%20%20%20base_url%20%3D%20f%22https%3A%2F%2Fraw.githubusercontent.com%2Fopencv%2Fopencv%2F%7Bopencv_ref%7D%2Fsamples%2Fdata%22%0A%20%20%20%20return%20base_url%2C%20cv2%2C%20data_dir%2C%20image_names%2C%20mo%2C%20np%2C%20plt%2C%20requests%0A%0A%0A%40app.cell%0Adef%20_(data_dir%2C%20requests)%3A%0A%20%20%20%20def%20ensure_download(file_name%3A%20str%2C%20url%3A%20str)%3A%0A%20%20%20%20%20%20%20%20destination%20%3D%20data_dir%20%2F%20file_name%0A%20%20%20%20%20%20%20%20if%20destination.exists()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20destination%0A%20%20%20%20%20%20%20%20response%20%3D%20requests.get(url%2C%20timeout%3D30)%0A%20%20%20%20%20%20%20%20response.raise_for_status()%0A%20%20%20%20%20%20%20%20destination.write_bytes(response.content)%0A%20%20%20%20%20%20%20%20return%20destination%0A%0A%20%20%20%20return%20(ensure_download%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20OpenCV%20%E3%82%AB%E3%83%A1%E3%83%A9%E3%82%AD%E3%83%A3%E3%83%AA%E3%83%96%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%0A%0A%20%20%20%20OpenCV%20%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E7%94%BB%E5%83%8F%E3%82%92%E5%9B%BA%E5%AE%9A%20URL%20%E3%81%8B%E3%82%89%E5%8F%96%E5%BE%97%E3%81%97%E3%81%A6%20%60data%2F%60%20%E3%81%AB%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%81%97%E3%80%81%0A%20%20%20%20%E3%83%81%E3%82%A7%E3%82%B9%E3%83%9C%E3%83%BC%E3%83%89%E6%A4%9C%E5%87%BA%E3%81%8B%E3%82%89%E6%AD%AA%E3%81%BF%E8%A3%9C%E6%AD%A3%E3%81%BE%E3%81%A7%E3%82%92%20marimo%20%E4%B8%8A%E3%81%A7%E5%86%8D%E7%8F%BE%E3%81%99%E3%82%8B%E3%80%82%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(base_url%2C%20ensure_download%2C%20image_names)%3A%0A%20%20%20%20calibration_images%20%3D%20%5B%0A%20%20%20%20%20%20%20%20ensure_download(image_name%2C%20f%22%7Bbase_url%7D%2F%7Bimage_name%7D%22)%0A%20%20%20%20%20%20%20%20for%20image_name%20in%20image_names%0A%20%20%20%20%5D%0A%20%20%20%20return%20(calibration_images%2C)%0A%0A%0A%40app.cell%0Adef%20_(np)%3A%0A%20%20%20%20object_points_template%20%3D%20np.zeros((6%20*%207%2C%203)%2C%20np.float32)%0A%20%20%20%20object_points_template%5B%3A%2C%20%3A2%5D%20%3D%20np.mgrid%5B0%3A7%2C%200%3A6%5D.T.reshape(-1%2C%202)%0A%20%20%20%20return%20(object_points_template%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20%E3%83%81%E3%82%A7%E3%82%B9%E3%83%9C%E3%83%BC%E3%83%89%E3%82%B3%E3%83%BC%E3%83%8A%E3%83%BC%E6%A4%9C%E5%87%BA%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(calibration_images%2C%20cv2%2C%20object_points_template%2C%20plt)%3A%0A%20%20%20%20corner_refinement%20%3D%20(%0A%20%20%20%20%20%20%20%20cv2.TERM_CRITERIA_EPS%20%2B%20cv2.TERM_CRITERIA_MAX_ITER%2C%0A%20%20%20%20%20%20%20%2030%2C%0A%20%20%20%20%20%20%20%200.001%2C%0A%20%20%20%20)%0A%20%20%20%20image_points%20%3D%20%5B%5D%0A%20%20%20%20object_points%20%3D%20%5B%5D%0A%20%20%20%20annotated_images%20%3D%20%5B%5D%0A%20%20%20%20annotated_names%20%3D%20%5B%5D%0A%20%20%20%20image_size%20%3D%20None%0A%0A%20%20%20%20for%20image_path%20in%20calibration_images%3A%0A%20%20%20%20%20%20%20%20image_bgr%20%3D%20cv2.imread(str(image_path))%0A%20%20%20%20%20%20%20%20if%20image_bgr%20is%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20raise%20RuntimeError(f%22Failed%20to%20load%20calibration%20image%3A%20%7Bimage_path%7D%22)%0A%20%20%20%20%20%20%20%20image_gray%20%3D%20cv2.cvtColor(image_bgr%2C%20cv2.COLOR_BGR2GRAY)%0A%20%20%20%20%20%20%20%20found%2C%20corners%20%3D%20cv2.findChessboardCorners(image_gray%2C%20(7%2C%206)%2C%20None)%0A%20%20%20%20%20%20%20%20if%20not%20found%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20continue%0A%20%20%20%20%20%20%20%20refined_corners%20%3D%20cv2.cornerSubPix(image_gray%2C%20corners%2C%20(11%2C%2011)%2C%20(-1%2C%20-1)%2C%20corner_refinement)%0A%20%20%20%20%20%20%20%20object_points.append(object_points_template.copy())%0A%20%20%20%20%20%20%20%20image_points.append(refined_corners)%0A%20%20%20%20%20%20%20%20image_size%20%3D%20image_gray.shape%5B%3A%3A-1%5D%0A%20%20%20%20%20%20%20%20annotated_bgr%20%3D%20cv2.drawChessboardCorners(image_bgr.copy()%2C%20(7%2C%206)%2C%20refined_corners%2C%20found)%0A%20%20%20%20%20%20%20%20annotated_images.append(cv2.cvtColor(annotated_bgr%2C%20cv2.COLOR_BGR2RGB))%0A%20%20%20%20%20%20%20%20annotated_names.append(image_path.name)%0A%0A%20%20%20%20if%20not%20image_points%20or%20image_size%20is%20None%3A%0A%20%20%20%20%20%20%20%20raise%20RuntimeError(%22Chessboard%20corners%20were%20not%20detected%20in%20the%20calibration%20set.%22)%0A%0A%20%20%20%20cols%20%3D%203%0A%20%20%20%20rows%20%3D%20(len(annotated_images)%20%2B%20cols%20-%201)%20%2F%2F%20cols%0A%20%20%20%20figure_detect%2C%20axes_detect%20%3D%20plt.subplots(rows%2C%20cols%2C%20figsize%3D(12%2C%204%20*%20rows))%0A%20%20%20%20axes_flat%20%3D%20axes_detect.ravel()%20if%20hasattr(axes_detect%2C%20%22ravel%22)%20else%20%5Baxes_detect%5D%0A%20%20%20%20for%20_gallery_axis%2C%20image_rgb%2C%20image_name%20in%20zip(axes_flat%2C%20annotated_images%2C%20annotated_names%2C%20strict%3DFalse)%3A%0A%20%20%20%20%20%20%20%20_gallery_axis.imshow(image_rgb)%0A%20%20%20%20%20%20%20%20_gallery_axis.set_title(image_name)%0A%20%20%20%20%20%20%20%20_gallery_axis.axis(%22off%22)%0A%20%20%20%20for%20_unused_gallery_axis%20in%20axes_flat%5Blen(annotated_images)%3A%5D%3A%0A%20%20%20%20%20%20%20%20_unused_gallery_axis.axis(%22off%22)%0A%20%20%20%20figure_detect.tight_layout()%0A%20%20%20%20figure_detect%0A%20%20%20%20return%20image_points%2C%20image_size%2C%20object_points%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20%E3%82%AB%E3%83%A1%E3%83%A9%E8%A1%8C%E5%88%97%E3%81%AE%E6%8E%A8%E5%AE%9A%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(cv2%2C%20image_points%2C%20image_size%2C%20object_points)%3A%0A%20%20%20%20_%2C%20camera_matrix%2C%20distortion_coeffs%2C%20rotation_vectors%2C%20translation_vectors%20%3D%20cv2.calibrateCamera(%0A%20%20%20%20%20%20%20%20object_points%2C%0A%20%20%20%20%20%20%20%20image_points%2C%0A%20%20%20%20%20%20%20%20image_size%2C%0A%20%20%20%20%20%20%20%20None%2C%0A%20%20%20%20%20%20%20%20None%2C%0A%20%20%20%20)%0A%20%20%20%20print(camera_matrix)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20camera_matrix%2C%0A%20%20%20%20%20%20%20%20distortion_coeffs%2C%0A%20%20%20%20%20%20%20%20rotation_vectors%2C%0A%20%20%20%20%20%20%20%20translation_vectors%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_(calibration_images%2C%20camera_matrix%2C%20cv2%2C%20distortion_coeffs)%3A%0A%20%20%20%20sample_image%20%3D%20cv2.imread(str(calibration_images%5B-1%5D))%0A%20%20%20%20if%20sample_image%20is%20None%3A%0A%20%20%20%20%20%20%20%20raise%20RuntimeError(f%22Failed%20to%20load%20sample%20image%3A%20%7Bcalibration_images%5B-1%5D%7D%22)%0A%20%20%20%20image_height%2C%20image_width%20%3D%20sample_image.shape%5B%3A2%5D%0A%20%20%20%20optimal_camera_matrix%2C%20roi%20%3D%20cv2.getOptimalNewCameraMatrix(%0A%20%20%20%20%20%20%20%20camera_matrix%2C%0A%20%20%20%20%20%20%20%20distortion_coeffs%2C%0A%20%20%20%20%20%20%20%20(image_width%2C%20image_height)%2C%0A%20%20%20%20%20%20%20%201%2C%0A%20%20%20%20%20%20%20%20(image_width%2C%20image_height)%2C%0A%20%20%20%20)%0A%20%20%20%20print(optimal_camera_matrix)%0A%20%20%20%20return%20optimal_camera_matrix%2C%20roi%2C%20sample_image%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20%E6%AD%AA%E3%81%BF%E8%A3%9C%E6%AD%A3%E3%81%AE%E6%AF%94%E8%BC%83%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20camera_matrix%2C%0A%20%20%20%20cv2%2C%0A%20%20%20%20distortion_coeffs%2C%0A%20%20%20%20optimal_camera_matrix%2C%0A%20%20%20%20plt%2C%0A%20%20%20%20roi%2C%0A%20%20%20%20sample_image%2C%0A)%3A%0A%20%20%20%20undistorted_direct%20%3D%20cv2.undistort(sample_image%2C%20camera_matrix%2C%20distortion_coeffs%2C%20None%2C%20optimal_camera_matrix)%0A%20%20%20%20roi_x%2C%20roi_y%2C%20roi_w%2C%20roi_h%20%3D%20roi%0A%20%20%20%20undistorted_direct%20%3D%20undistorted_direct%5Broi_y%3Aroi_y%20%2B%20roi_h%2C%20roi_x%3Aroi_x%20%2B%20roi_w%5D%0A%0A%20%20%20%20map_x%2C%20map_y%20%3D%20cv2.initUndistortRectifyMap(%0A%20%20%20%20%20%20%20%20camera_matrix%2C%0A%20%20%20%20%20%20%20%20distortion_coeffs%2C%0A%20%20%20%20%20%20%20%20None%2C%0A%20%20%20%20%20%20%20%20optimal_camera_matrix%2C%0A%20%20%20%20%20%20%20%20(sample_image.shape%5B1%5D%2C%20sample_image.shape%5B0%5D)%2C%0A%20%20%20%20%20%20%20%20cv2.CV_32FC1%2C%0A%20%20%20%20)%0A%20%20%20%20undistorted_remap%20%3D%20cv2.remap(sample_image%2C%20map_x%2C%20map_y%2C%20cv2.INTER_LINEAR)%0A%20%20%20%20undistorted_remap%20%3D%20undistorted_remap%5Broi_y%3Aroi_y%20%2B%20roi_h%2C%20roi_x%3Aroi_x%20%2B%20roi_w%5D%0A%0A%20%20%20%20figure_undistort%2C%20axes_undistort%20%3D%20plt.subplots(1%2C%203%2C%20figsize%3D(15%2C%204))%0A%20%20%20%20axes_undistort%5B0%5D.imshow(cv2.cvtColor(sample_image%2C%20cv2.COLOR_BGR2RGB))%0A%20%20%20%20axes_undistort%5B0%5D.set_title(%22original%22)%0A%20%20%20%20axes_undistort%5B1%5D.imshow(cv2.cvtColor(undistorted_direct%2C%20cv2.COLOR_BGR2RGB))%0A%20%20%20%20axes_undistort%5B1%5D.set_title(%22cv2.undistort%22)%0A%20%20%20%20axes_undistort%5B2%5D.imshow(cv2.cvtColor(undistorted_remap%2C%20cv2.COLOR_BGR2RGB))%0A%20%20%20%20axes_undistort%5B2%5D.set_title(%22cv2.remap%22)%0A%20%20%20%20for%20_undistort_axis%20in%20axes_undistort%3A%0A%20%20%20%20%20%20%20%20_undistort_axis.axis(%22off%22)%0A%20%20%20%20figure_undistort.tight_layout()%0A%20%20%20%20figure_undistort%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20%E3%82%AD%E3%83%A3%E3%83%AA%E3%83%96%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E8%AA%A4%E5%B7%AE%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20camera_matrix%2C%0A%20%20%20%20cv2%2C%0A%20%20%20%20distortion_coeffs%2C%0A%20%20%20%20image_points%2C%0A%20%20%20%20object_points%2C%0A%20%20%20%20rotation_vectors%2C%0A%20%20%20%20translation_vectors%2C%0A)%3A%0A%20%20%20%20mean_error%20%3D%200.0%0A%20%20%20%20for%20index%20in%20range(len(object_points))%3A%0A%20%20%20%20%20%20%20%20reprojected%2C%20_%20%3D%20cv2.projectPoints(%0A%20%20%20%20%20%20%20%20%20%20%20%20object_points%5Bindex%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20rotation_vectors%5Bindex%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20translation_vectors%5Bindex%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20camera_matrix%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20distortion_coeffs%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20error%20%3D%20cv2.norm(image_points%5Bindex%5D%2C%20reprojected%2C%20cv2.NORM_L2)%20%2F%20len(reprojected)%0A%20%20%20%20%20%20%20%20mean_error%20%2B%3D%20error%0A%20%20%20%20print(f%22total%20error%3A%20%7Bmean_error%20%2F%20len(object_points)%3A.6f%7D%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
4edf503cfa356232d4c4768fcc5870bf