Box dimensioner issue
Well, it is not really an issue but I would like to modify the code to get and save the image I get when clicking a button. I have already designed the button interface but I do not know how to take and save a screenshot of the camera.
Thanks for everything.
-
Hi Javi0798 I would speculate that you could create a function that is called when a button-click event occurs, and save the color image with the OpenCV imwrite instruction. Assuming that you will be using Python if you are adapting the box_dimensioner_multicam.py example, the link below has an example of Python code for saving the color image with imwrite.
-
I have tried, but what I receive is a simple screenshot of the chessboard and not of the measures of the box that is what I want. Here is the code.
# Import RealSense, OpenCV and NumPy import pyrealsense2 as rs import cv2 import numpy as np from PySide2.QtWidgets import QApplication, QMainWindow, QComboBox, QWidget, QDialog from PySide2.QtUiTools import QUiLoader from PySide2.QtCore import QAbstractAnimation, QFile from lxml import etree as et # Import helper functions and classes written to wrap the RealSense, OpenCV and Kabsch Calibration usage from collections import defaultdict from realsense_device_manager import DeviceManager from calibration_kabsch import PoseEstimation from helper_functions import get_boundary_corners_2D from measurement_task import calculate_boundingbox_points, calculate_cumulative_pointcloud, visualise_measurements import sys from ui_configuracion import Ui_Dialog_Config from ui_capturar import Ui_Dialog_Capturar from ui_guardar import Ui_Dialog_Guardar class Configuracion(QDialog): def __init__(self): super(Configuracion, self).__init__() self.ui=Ui_Dialog_Config() self.ui.setupUi(self) self.ui.lineEdit.setText("7") self.ui.lineEdit_2.setText("7") self.ui.lineEdit_3.setText("0.0353") self.ui.pushButton.clicked.connect(self.ejecutar_demo) self.ui.pushButton.clicked.connect(self.quit_app) def quit_app(self): self.hide() def ejecutar_demo(self): self.chessboard_width=int(self.ui.lineEdit.text()) self.chessboard_height=int(self.ui.lineEdit_2.text()) self.square_size=float(self.ui.lineEdit_3.text()) self.quit_app() self.run_demo(self.chessboard_width, self.chessboard_height, self.square_size) def run_demo (self, ch_width, ch_height, sq_size): # Define some constants L515_resolution_width = 1024 # pixels L515_resolution_height = 768 # pixels L515_frame_rate = 30 resolution_width = 1280 # pixels resolution_height = 720 # pixels frame_rate = 15 # fps dispose_frames_for_stablisation = 30 # frames try: # Enable the streams from all the intel realsense devices L515_rs_config = rs.config() L515_rs_config.enable_stream(rs.stream.depth, L515_resolution_width, L515_resolution_height, rs.format.z16, L515_frame_rate) L515_rs_config.enable_stream(rs.stream.infrared, 0, L515_resolution_width, L515_resolution_height, rs.format.y8, L515_frame_rate) L515_rs_config.enable_stream(rs.stream.color, resolution_width, resolution_height, rs.format.bgr8, frame_rate) rs_config = rs.config() rs_config.enable_stream(rs.stream.depth, resolution_width, resolution_height, rs.format.z16, frame_rate) rs_config.enable_stream(rs.stream.infrared, 1, resolution_width, resolution_height, rs.format.y8, frame_rate) rs_config.enable_stream(rs.stream.color, resolution_width, resolution_height, rs.format.bgr8, frame_rate) # Use the device manager class to enable the devices and get the frames device_manager = DeviceManager(rs.context(), rs_config, L515_rs_config) device_manager.enable_all_devices() # Allow some frames for the auto-exposure controller to stablise for frames in range(dispose_frames_for_stablisation): frames = device_manager.poll_frames() assert( len(device_manager._available_devices) > 0 ) """ 1: Calibration Calibrate all the available devices to the world co-ordinates. For this purpose, a chessboard printout for use with opencv based calibration process is needed. """ # Get the intrinsics of the realsense device intrinsics_devices = device_manager.get_device_intrinsics(frames) # Set the chessboard parameters for calibration chessboard_params = [ch_height, ch_width, sq_size] # Estimate the pose of the chessboard in the world coordinate using the Kabsch Method calibrated_device_count = 0 while calibrated_device_count < len(device_manager._available_devices): frames = device_manager.poll_frames() pose_estimator = PoseEstimation(frames, intrinsics_devices, chessboard_params) transformation_result_kabsch = pose_estimator.perform_pose_estimation() object_point = pose_estimator.get_chessboard_corners_in3d() calibrated_device_count = 0 for device_info in device_manager._available_devices: device = device_info[0] if not transformation_result_kabsch[device][0]: print("Place the chessboard on the plane where the object needs to be detected..") else: calibrated_device_count += 1 # Save the transformation object for all devices in an array to use for measurements transformation_devices={} chessboard_points_cumulative_3d = np.array([-1,-1,-1]).transpose() for device_info in device_manager._available_devices: device = device_info[0] transformation_devices[device] = transformation_result_kabsch[device][1].inverse() points3D = object_point[device][2][:,object_point[device][3]] points3D = transformation_devices[device].apply_transformation(points3D) chessboard_points_cumulative_3d = np.column_stack( (chessboard_points_cumulative_3d,points3D) ) # Extract the bounds between which the object's dimensions are needed # It is necessary for this demo that the object's length and breath is smaller than that of the chessboard chessboard_points_cumulative_3d = np.delete(chessboard_points_cumulative_3d, 0, 1) roi_2D = get_boundary_corners_2D(chessboard_points_cumulative_3d) print("Calibration completed... \nPlace the box in the field of view of the devices...") """ 2: Measurement and display Measure the dimension of the object using depth maps from multiple RealSense devices The information from Phase 1 will be used here """ # Enable the emitter of the devices device_manager.enable_emitter(True) # Load the JSON settings file in order to enable High Accuracy preset for the realsense device_manager.load_settings_json("/HighResHighAccuracyPreset.json") # Get the extrinsics of the device to be used later extrinsics_devices = device_manager.get_depth_to_color_extrinsics(frames) # Get the calibration info as a dictionary to help with display of the measurements onto the color image instead of infra red image calibration_info_devices = defaultdict(list) for calibration_info in (transformation_devices, intrinsics_devices, extrinsics_devices): for key, value in calibration_info.items(): calibration_info_devices[key].append(value) # Continue acquisition until terminated with Ctrl+C by the user pipeline = rs.pipeline() config = rs.config() config.enable_stream(rs.stream.color, 1280, 720, rs.format.bgr8, 30) profile = pipeline.start(config) #self.frames_devices = device_manager.poll_frames() self.frames = pipeline.wait_for_frames() align_to = rs.stream.color align = rs.align(align_to) aligned_frames = align.process(self.frames) color_frame = aligned_frames.get_color_frame() self.color_image = np.asanyarray(color_frame.get_data()) dialog_capturar=capturar() dialog_capturar.ui.pushButton.clicked.connect(self.f1) dialog_capturar.ui.pushButton.clicked.connect(self.quit_app) dialog_capturar.show() while 1: # Get the frames from all the devices frames_devices = device_manager.poll_frames() # Calculate the pointcloud using the depth frames from all the devices point_cloud = calculate_cumulative_pointcloud(frames_devices, calibration_info_devices, roi_2D) # Get the bounding box for the pointcloud in image coordinates of the color imager bounding_box_points_color_image, self.length, self.width, self.height = calculate_boundingbox_points(point_cloud, calibration_info_devices ) # Draw the bounding box points on the color image and visualise the results visualise_measurements(frames_devices, bounding_box_points_color_image, self.length, self.width, self.height) except KeyboardInterrupt: print("The program was interupted by the user. Closing the program...") finally: device_manager.disable_streams() cv2.destroyAllWindows() def f1(self): dialog_guardar = guardar(self.length, self.width, self.height, self.color_image) dialog_guardar.exec() class capturar(QDialog): def __init__(self): super(capturar, self).__init__() self.ui=Ui_Dialog_Capturar() self.ui.setupUi(self) class guardar(QDialog): def __init__(self, length, width, height, frames_devices): super(guardar, self).__init__() self.ui=Ui_Dialog_Guardar() self.ui.setupUi(self) longitud=int(length*10000) anchura=int(width*1000) altura=int(height*1000) self.ui.lineEdit.setText(str(longitud)) self.ui.lineEdit_2.setText(str(anchura)) self.ui.lineEdit_3.setText(str(altura)) cv2.imwrite('C:/carpetas/out.jpg', frames_devices) -
I thought that there was a possibility that this might occur, since the overlaid coordinate writing is applied to the color image within a loop at the part of the box_dimensioner_multicam script linked to below.
This implies that the imwrite instruction might need to be placed directly after this line. The problem is setting up a mechanism so that it only triggers when a button input is made.
Perhaps it could be tested by putting the imwrite code inside the keyboard interrupt code block.
On the other hand, the text overlay gives me the impression that it is overlaying the text on top of the window displaying the color image rather than incorporating it into the image data itself, hence why it is not included in an exported image file.
-
Rather than saving the image from the camera, an alternate approach may be to use general Python code to capture the contents of a specific window (and not capture the entire screen). The link below is a tutorial that uses a Python module called pygetwindow to do so.
https://www.thepythoncode.com/article/record-a-specific-window-in-python
Please sign in to leave a comment.
Comments
4 comments