Instruction:
Write a Python 3 script to
convert to new camera intrinsics with parameters for resized image.

Response:
def resize(self, scale):
        """ Convert to new camera intrinsics with parameters for resized image.

        Parameters
        ----------
        scale : float
            the amount to rescale the intrinsics

        Returns
        -------
        :obj:`CameraIntrinsics`
            camera intrinsics for resized image
        """
        center_x = float(self.width-1) / 2
        center_y = float(self.height-1) / 2
        orig_cx_diff = self.cx - center_x
        orig_cy_diff = self.cy - center_y
        height = scale * self.height
        width = scale * self.width
        scaled_center_x = float(width-1) / 2
        scaled_center_y = float(height-1) / 2
        fx = scale * self.fx
        fy = scale * self.fy
        skew = scale * self.skew
        cx = scaled_center_x + scale * orig_cx_diff
        cy = scaled_center_y + scale * orig_cy_diff
        scaled_intrinsics = CameraIntrinsics(frame=self.frame,
                                              fx=fx, fy=fy, skew=skew, cx=cx, cy=cy,
                                              height=height, width=width)
        return scaled_intrinsics


Instruction:
Can you generate the documentation for the following Python 3 function
def project(self, point_cloud, round_px=True):
        if not isinstance(point_cloud, PointCloud) and not (isinstance(point_cloud, Point) and point_cloud.dim == 3):
            raise ValueError('Must provide PointCloud or 3D Point object for projection')
        if point_cloud.frame != self._frame:
            raise ValueError('Cannot project points in frame %s into camera with frame %s' %(point_cloud.frame, self._frame))

        points_proj = self._K.dot(point_cloud.data)
        if len(points_proj.shape) == 1:
            points_proj = points_proj[:, np.newaxis]
        point_depths = np.tile(points_proj[2,:], [3, 1])
        points_proj = np.divide(points_proj, point_depths)
        if round_px:
            points_proj = np.round(points_proj)

        if isinstance(point_cloud, Point):
            return Point(data=points_proj[:2,:].astype(np.int16), frame=self._frame)
        return ImageCoords(data=points_proj[:2,:].astype(np.int16), frame=self._frame)

Response: Projects a point cloud onto the camera image plane.


Instruction:
Explain what the following Python 3 code does
def deproject_to_image(self, depth_image):
        point_cloud = self.deproject(depth_image)
        point_cloud_im_data = point_cloud.data.T.reshape(depth_image.height, depth_image.width, 3)
        return PointCloudImage(data=point_cloud_im_data,
                               frame=self._frame)

Response: Deprojects a DepthImage into a PointCloudImage.


Instruction:
Create a Python 3 function for
loading a CameraIntrinsics object from a file.

Response:
def load(filename):
        """Load a CameraIntrinsics object from a file.

        Parameters
        ----------
        filename : :obj:`str`
            The .intr file to load the object from.

        Returns
        -------
        :obj:`CameraIntrinsics`
            The CameraIntrinsics object loaded from the file.

        Raises
        ------
        ValueError
            If filename does not have the .intr extension.
        """
        file_root, file_ext = os.path.splitext(filename)
        if file_ext.lower() != INTR_EXTENSION:
            raise ValueError('Extension %s not supported for CameraIntrinsics. Must be stored with extension %s' %(file_ext, INTR_EXTENSION))

        f = open(filename, 'r')
        ci = json.load(f)
        f.close()
        return CameraIntrinsics(frame=ci['_frame'],
                                fx=ci['_fx'],
                                fy=ci['_fy'],
                                cx=ci['_cx'],
                                cy=ci['_cy'],
                                skew=ci['_skew'],
                                height=ci['_height'],
                                width=ci['_width'])


Instruction:
Make a summary of the following Python 3 code
def finetune_classification_cnn(config):
    # read params
    dataset = config['dataset']
    x_names = config['x_names']
    y_name = config['y_name']
    model_dir = config['model_dir']
    debug = config['debug']

    num_classes = None
    if 'num_classes' in config.keys():
        num_classes = config['num_classes']

    batch_size = config['training']['batch_size']
    train_pct = config['training']['train_pct']
    model_save_period = config['training']['model_save_period']

    data_aug_config = config['data_augmentation']
    preproc_config = config['preprocessing']
    iterator_config = config['data_iteration']
    model_config = config['model']
    base_model_config = model_config['base']
    optimization_config = config['optimization']
    train_config = config['training']

    generator_image_shape = None
    if 'image_shape' in data_aug_config.keys():
        generator_image_shape = data_aug_config['image_shape']
    optimizer_name = optimization_config['optimizer']

    model_params = {}
    if 'params' in model_config.keys():
        model_params = model_config['params']

    base_model_params = {}
    if 'params' in base_model_config.keys():
        base_model_params = base_model_config['params']

    if debug:
        seed = 108
        random.seed(seed)
        np.random.seed(seed)

    # generate model dir
    if not os.path.exists(model_dir):
        os.mkdir(model_dir)
    model_id = utils.gen_experiment_id()
    model_dir = os.path.join(model_dir, 'model_%s' %(model_id))
    if not os.path.exists(model_dir):
        os.mkdir(model_dir)
    logging.info('Saving model to %s' %(model_dir))
    latest_model_filename = os.path.join(model_dir, 'weights_{epoch:05d}.h5')
    best_model_filename = os.path.join(model_dir, 'weights.h5')

    # save config
    training_config_filename = os.path.join(model_dir, 'training_config.yaml')
    config.save(training_config_filename)

    # open dataset
    dataset = TensorDataset.open(dataset)

    # split dataset
    indices_filename = os.path.join(model_dir, 'splits.npz')
    if os.path.exists(indices_filename):
        indices = np.load(indices_filename)['arr_0'].tolist()
        train_indices = indices['train']
        val_indices = indices['val']
    else:
        train_indices, val_indices = dataset.split(train_pct)
        indices = np.array({'train':train_indices,
                            'val':val_indices})
        np.savez_compressed(indices_filename, indices)
    num_train = train_indices.shape[0]
    num_val = val_indices.shape[0]
    val_steps = int(np.ceil(float(num_val) / batch_size))

    # init generator
    train_generator_filename = os.path.join(model_dir, 'train_preprocessor.pkl')
    val_generator_filename = os.path.join(model_dir, 'val_preprocessor.pkl')
    if os.path.exists(train_generator_filename):
        logging.info('Loading generators')
        train_generator = pkl.load(open(train_generator_filename, 'rb'))
        val_generator = pkl.load(open(val_generator_filename, 'rb'))
    else:
        logging.info('Fitting generator')
        train_generator = TensorDataGenerator(num_classes=num_classes,
                                              **data_aug_config)
        val_generator = TensorDataGenerator(featurewise_center=data_aug_config['featurewise_center'],
                                            featurewise_std_normalization=data_aug_config['featurewise_std_normalization'],
                                            image_shape=generator_image_shape,
                                            num_classes=num_classes)
        fit_start = time.time()
        train_generator.fit(dataset, x_names, y_name, indices=train_indices, **preproc_config)
        val_generator.mean = train_generator.mean
        val_generator.std = train_generator.std
        val_generator.min_output = train_generator.min_output
        val_generator.max_output = train_generator.max_output
        val_generator.num_classes = train_generator.num_classes
        fit_stop = time.time()
        logging.info('Generator fit took %.3f sec' %(fit_stop - fit_start))
        pkl.dump(train_generator, open(train_generator_filename, 'wb'))
        pkl.dump(val_generator, open(val_generator_filename, 'wb'))

    if num_classes is None:
        num_classes = int(train_generator.num_classes)

    # init iterator
    train_iterator = train_generator.flow_from_dataset(dataset, x_names, y_name,
                                                       indices=train_indices,
                                                       batch_size=batch_size,
                                                       **iterator_config)
    val_iterator = val_generator.flow_from_dataset(dataset, x_names, y_name,
                                                   indices=val_indices,
                                                   batch_size=batch_size,
                                                   **iterator_config)

    # setup model
    base_cnn = ClassificationCNN.open(base_model_config['model'],
                                      base_model_config['type'],
                                      input_name=x_names[0],
                                      **base_model_params)
    cnn = FinetunedClassificationCNN(base_cnn=base_cnn,
                                     name='dexresnet',
                                     num_classes=num_classes,
                                     output_name=y_name,
                                     im_preprocessor=val_generator,
                                     **model_params)

    # setup training
    cnn.freeze_base_cnn()
    if optimizer_name == 'sgd':
        optimizer = SGD(lr=optimization_config['lr'],
                        momentum=optimization_config['momentum'])
    elif optimizer_name == 'adam':
        optimizer = Adam(lr=optimization_config['lr'])
    else:
        raise ValueError('Optimizer %s not supported!' %(optimizer_name))
    model = cnn.model
    model.compile(optimizer=optimizer,
                  loss=optimization_config['loss'],
                  metrics=optimization_config['metrics'])

    # train
    steps_per_epoch = int(np.ceil(float(num_train) / batch_size))
    latest_model_ckpt = ModelCheckpoint(latest_model_filename, period=model_save_period)
    best_model_ckpt = ModelCheckpoint(best_model_filename,
                                      save_best_only=True,
                                      period=model_save_period)
    train_history_cb = TrainHistory(model_dir)
    callbacks = [latest_model_ckpt, best_model_ckpt, train_history_cb]
    history = model.fit_generator(train_iterator,
                                  steps_per_epoch=steps_per_epoch,
                                  epochs=train_config['epochs'],
                                  callbacks=callbacks,
                                  validation_data=val_iterator,
                                  validation_steps=val_steps,
                                  class_weight=train_config['class_weight'],
                                  use_multiprocessing=train_config['use_multiprocessing'])

    # save model
    cnn.save(model_dir)

    # save history
    history_filename = os.path.join(model_dir, 'history.pkl')
    pkl.dump(history.history, open(history_filename, 'wb'))

Response: Function that finetune classification CNN.


Instruction:
Can you create a Python 3 function that
loads a set of color images depth images and camera intrinsics from a Kinect sensor.

Response:
def load_images(cfg):
    """Helper function for loading a set of color images, depth images, and IR
    camera intrinsics.

    The config dictionary must have these keys:
        - prestored_data -- If 1, use the virtual sensor, else use a real sensor.
        - prestored_data_dir -- A path to the prestored data dir for a virtual sensor.
        - sensor/frame -- The frame of reference for the sensor.
        - sensor/device_num -- The device number for the real Kinect.
        - sensor/pipeline_mode -- The mode for the real Kinect's packet pipeline.
        - num_images -- The number of images to generate.

    Parameters
    ----------
    cfg : :obj:`dict`
        A config dictionary.

    Returns
    -------
    :obj:`tuple` of :obj:`list` of :obj:`ColorImage`, :obj:`list` of :obj:`DepthImage`, :obj:`CameraIntrinsics`
        A set of ColorImages and DepthImages, and the Kinect's CameraIntrinsics
        for its IR sensor.
    """
    if 'prestored_data' in cfg.keys() and cfg['prestored_data'] == 1:
        sensor = VirtualKinect2Sensor(path_to_images=cfg['prestored_data_dir'], frame=cfg['sensor']['frame'])
    else:
        sensor = Kinect2Sensor(device_num=cfg['sensor']['device_num'], frame=cfg['sensor']['frame'],
                               packet_pipeline_mode=cfg['sensor']['pipeline_mode'])
    sensor.start()
    ir_intrinsics = sensor.ir_intrinsics

    # get raw images
    colors = []
    depths = []

    for _ in range(cfg['num_images']):
        color, depth, _ = sensor.frames()
        colors.append(color)
        depths.append(depth)

    sensor.stop()

    return colors, depths, ir_intrinsics


Instruction:
Given the following Python 3 function, write the documentation
def color_intrinsics(self):
        if self._device is None:
            raise RuntimeError('Kinect2 device %s not runnning. Cannot return color intrinsics')
        camera_params = self._device.getColorCameraParams()
        return CameraIntrinsics(self._color_frame, camera_params.fx, camera_params.fy,
                                camera_params.cx, camera_params.cy)

Response: Return a list of camera intrinsics for the Kinect s color camera.


Instruction:
Here you have a function in Python 3, explain what it does
def ir_intrinsics(self):
        if self._device is None:
            raise RuntimeError('Kinect2 device %s not runnning. Cannot return IR intrinsics')
        camera_params = self._device.getIrCameraParams()
        return CameraIntrinsics(self._ir_frame, camera_params.fx, camera_params.fy,
                                camera_params.cx, camera_params.cy,
                                height=Kinect2Sensor.DEPTH_IM_HEIGHT,
                                width=Kinect2Sensor.DEPTH_IM_WIDTH)

Response: Return a list of camera intrinsics for the Kinect s IR camera.


Instruction:
Make a summary of the following Python 3 code
def start(self):
        # open packet pipeline
        if self._packet_pipeline_mode == Kinect2PacketPipelineMode.OPENGL:
            self._pipeline = lf2.OpenGLPacketPipeline()
        elif self._packet_pipeline_mode == Kinect2PacketPipelineMode.CPU:
            self._pipeline = lf2.CpuPacketPipeline()

        # setup logger
        self._logger = lf2.createConsoleLogger(lf2.LoggerLevel.Warning)
        lf2.setGlobalLogger(self._logger)

        # check devices
        self._fn_handle = lf2.Freenect2()
        self._num_devices = self._fn_handle.enumerateDevices()
        if self._num_devices == 0:
            raise IOError('Failed to start stream. No Kinect2 devices available!')
        if self._num_devices <= self._device_num:
            raise IOError('Failed to start stream. Device num %d unavailable!' %(self._device_num))

        # open device
        self._serial = self._fn_handle.getDeviceSerialNumber(self._device_num)
        self._device = self._fn_handle.openDevice(self._serial, pipeline=self._pipeline)

        # add device sync modes
        self._listener = lf2.SyncMultiFrameListener(
            lf2.FrameType.Color | lf2.FrameType.Ir | lf2.FrameType.Depth)
        self._device.setColorFrameListener(self._listener)
        self._device.setIrAndDepthFrameListener(self._listener)

        # start device
        self._device.start()

        # open registration
        self._registration = None
        if self._registration_mode == Kinect2RegistrationMode.COLOR_TO_DEPTH:
            logging.debug('Using color to depth registration')
            self._registration = lf2.Registration(self._device.getIrCameraParams(),
                                                  self._device.getColorCameraParams())
        self._running = True

Response: Starts the Kinect v2 sensor stream.


Instruction:
Given the following Python 3 function, write the documentation
def stop(self):
        # check that everything is running
        if not self._running or self._device is None:
            logging.warning('Kinect2 device %d not runnning. Aborting stop' %(self._device_num))
            return False

        # stop the device
        self._device.stop()
        self._device.close()
        self._device = None
        self._running = False
        return True

Response: Stops the Kinect2 sensor stream. Returns True if the device was already stopped False otherwise.


Instruction:
Implement a Python 3 function for
retrieving a new frame from the Kinect and convert it to a ColorImage DepthImage and IrImage.

Response:
def frames(self, skip_registration=False):
        """Retrieve a new frame from the Kinect and convert it to a ColorImage,
        a DepthImage, and an IrImage.

        Parameters
        ----------
        skip_registration : bool
            If True, the registration step is skipped.

        Returns
        -------
        :obj:`tuple` of :obj:`ColorImage`, :obj:`DepthImage`, :obj:`IrImage`, :obj:`numpy.ndarray`
            The ColorImage, DepthImage, and IrImage of the current frame.

        Raises
        ------
        RuntimeError
            If the Kinect stream is not running.
        """
        color_im, depth_im, ir_im, _ = self._frames_and_index_map(skip_registration=skip_registration)
        return color_im, depth_im, ir_im


Instruction:
Here you have a function in Python 3, explain what it does
def _frames_and_index_map(self, skip_registration=False):
        if not self._running:
            raise RuntimeError('Kinect2 device %s not runnning. Cannot read frames' %(self._device_num))

        # read frames
        frames = self._listener.waitForNewFrame()
        unregistered_color = frames['color']
        distorted_depth = frames['depth']
        ir = frames['ir']

        # apply color to depth registration
        color_frame = self._color_frame
        color = unregistered_color
        depth = distorted_depth
        color_depth_map = np.zeros([depth.height, depth.width]).astype(np.int32).ravel()
        if not skip_registration and self._registration_mode == Kinect2RegistrationMode.COLOR_TO_DEPTH:
            color_frame = self._ir_frame
            depth = lf2.Frame(depth.width, depth.height, 4, lf2.FrameType.Depth)
            color = lf2.Frame(depth.width, depth.height, 4, lf2.FrameType.Color)
            self._registration.apply(unregistered_color, distorted_depth, depth, color, color_depth_map=color_depth_map)

        # convert to array (copy needed to prevent reference of deleted data
        color_arr = copy.copy(color.asarray())
        color_arr[:,:,[0,2]] = color_arr[:,:,[2,0]] # convert BGR to RGB
        color_arr[:,:,0] = np.fliplr(color_arr[:,:,0])
        color_arr[:,:,1] = np.fliplr(color_arr[:,:,1])
        color_arr[:,:,2] = np.fliplr(color_arr[:,:,2])
        color_arr[:,:,3] = np.fliplr(color_arr[:,:,3])
        depth_arr = np.fliplr(copy.copy(depth.asarray()))
        ir_arr = np.fliplr(copy.copy(ir.asarray()))

        # convert meters
        if self._depth_mode == Kinect2DepthMode.METERS:
            depth_arr = depth_arr * MM_TO_METERS

        # Release and return
        self._listener.release(frames)
        return (ColorImage(color_arr[:,:,:3], color_frame),
                DepthImage(depth_arr, self._ir_frame),
                IrImage(ir_arr.astype(np.uint16), self._ir_frame),
                color_depth_map)

Response: Retrieve a new frame from the Kinect and return a ColorImage DepthImage IrImage and a map from depth pixels to color pixel indices.


Instruction:
Given the following Python 3 function, write the documentation
def _process_image_msg(self, msg):
        encoding = msg.encoding
        try:
            image = self._bridge.imgmsg_to_cv2(msg, encoding)
        except CvBridgeError as e:
            rospy.logerr(e)
        return image

Response: Process an image message and return a numpy array with the image data


Instruction:
Can you tell what is the following Python 3 function doing
def _color_image_callback(self, image_msg):
        color_arr = self._process_image_msg(image_msg)
        self._cur_color_im = ColorImage(color_arr[:,:,::-1], self._frame)

Response: Process color image message and store it in self. _cur_color_im


Instruction:
How would you code a function in Python 3 to
subscribe to depth image topic and keep it up to date

Response:
def _depth_image_callback(self, image_msg):
        """ subscribe to depth image topic and keep it up to date
        """
        encoding = image_msg.encoding
        try:
            depth_arr = self._bridge.imgmsg_to_cv2(image_msg, encoding)
            import pdb; pdb.set_trace()

        except CvBridgeError as e:
            rospy.logerr(e)
        depth = np.array(depth_arr*MM_TO_METERS, np.float32)
        self._cur_depth_im = DepthImage(depth, self._frame)


Instruction:
Given the following Python 3 function, write the documentation
def stop(self):
        # check that everything is running
        if not self._running:
            logging.warning('Kinect not running. Aborting stop')
            return False

        # stop subs
        self._image_sub.unregister()
        self._depth_sub.unregister()
        self._camera_info_sub.unregister

        self._running = False
        return True

Response: Stop the Kinect sensor


Instruction:
Can you write a function in Python 3 where it
retrieves a new frame from the Ensenso and convert it to a ColorImage DepthImage IrImage

Response:
def frames(self):
        """Retrieve a new frame from the Ensenso and convert it to a ColorImage,
        a DepthImage, IrImage is always none for this type

        Returns
        -------
        :obj:`tuple` of :obj:`ColorImage`, :obj:`DepthImage`, :obj:`IrImage`, :obj:`numpy.ndarray`
            The ColorImage, DepthImage, and IrImage of the current frame.

        Raises
        ------
        RuntimeError
            If the Kinect stream is not running.
        """
        # wait for a new image
        while self._cur_depth_im is None or self._cur_color_im is None:
            time.sleep(0.01)

        # read next image
        depth_im = self._cur_depth_im
        color_im = self._cur_color_im

        self._cur_color_im = None
        self._cur_depth_im = None

        #TODO add ir image
        return color_im, depth_im, None


Instruction:
Given the following Python 3 function, write the documentation
def frames(self):
        if not self._running:
            raise RuntimeError('VirtualKinect2 device pointing to %s not runnning. Cannot read frames' %(self._path_to_images))

        if self._im_index > self._num_images:
            raise RuntimeError('VirtualKinect2 device is out of images')

        # read images
        color_filename = os.path.join(self._path_to_images, 'color_%d.png' %(self._im_index))
        color_im = ColorImage.open(color_filename, frame=self._frame)
        depth_filename = os.path.join(self._path_to_images, 'depth_%d.npy' %(self._im_index))
        depth_im = DepthImage.open(depth_filename, frame=self._frame)
        ir_filename = os.path.join(self._path_to_images, 'ir_%d.npy' %(self._im_index))
        ir_im = None
        if os.path.exists(ir_filename):
            ir_im = IrImage.open(ir_filename, frame=self._frame)
        self._im_index += 1
        return color_im, depth_im, ir_im

Response: Retrieve the next frame from the image directory and convert it to a ColorImage DepthImage and IrImage.


Instruction:
How would you code a function in Python 3 to
create a Kinect2 sensor of the specified type.

Response:
def sensor(sensor_type, cfg):
        """ Creates a Kinect2 sensor of the specified type.

        Parameters
        ----------
        sensor_type : :obj:`str`
            the type of the sensor (real or virtual)
        cfg : :obj:`YamlConfig`
            dictionary of parameters for sensor initialization
        """
        sensor_type = sensor_type.lower()
        if sensor_type == 'real':
            s = Kinect2Sensor(packet_pipeline_mode=cfg['pipeline_mode'],
                              device_num=cfg['device_num'],
                              frame=cfg['frame'])
        elif sensor_type == 'virtual':
            s = VirtualKinect2Sensor(cfg['image_dir'],
                                     frame=cfg['frame'])
        elif sensor_type == 'bridged':
            s = KinectSensorBridged(quality=cfg['quality'], frame=cfg['frame'])
        else:
            raise ValueError('Kinect2 sensor type %s not supported' %(sensor_type))
        return s


Instruction:
Here you have a function in Python 3, explain what it does
def _connect(self, id_mask):
        # Get all devices attached as USB serial
        all_devices = glob.glob('/dev/ttyUSB*')

        # Identify which of the devices are LoadStar Serial Sensors
        sensors = []
        for device in all_devices:
            try:
                ser = serial.Serial(port=device,
                                    timeout=0.5,
                                    exclusive=True)
                ser.write('ID\r')
                ser.flush()
                time.sleep(0.05)
                resp = ser.read(13)
                ser.close()

                if len(resp) >= 10 and resp[:len(id_mask)] == id_mask:
                    sensors.append((device, resp.rstrip('\r\n')))
            except:
                continue
        sensors = sorted(sensors, key=lambda x : x[1])

        # Connect to each of the serial devices
        serials = []
        for device, key in sensors:
            ser = serial.Serial(port=device, timeout=0.5)
            serials.append(ser)
            rospy.loginfo('Connected to load cell {} at {}'.format(key, device))
        return serials

Response: Connects to all of the load cells serially.


Instruction:
Given the following Python 3 function, write the documentation
def _flush(self):
        for ser in self._serials:
            ser.flush()
            ser.flushInput()
            ser.flushOutput()
        time.sleep(0.02)

Response: Flushes all of the serial ports.


Instruction:
Write a Python 3 script for
zeroing out all load cells.

Response:
def _tare(self):
        """Zeros out (tare) all of the load cells.
        """
        for ser in self._serials:
            ser.write('TARE\r')
            ser.flush()
            ser.flushInput()
            ser.flushOutput()
        time.sleep(0.02)


Instruction:
Here you have a function in Python 3, explain what it does
def _read_weights(self):
        weights = []

        grams_per_pound = 453.592

        # Read from each of the sensors
        for ser in self._serials:
            ser.write('W\r')
            ser.flush()
        time.sleep(0.02)
        for ser in self._serials:
            try:
                output_str = ser.readline()
                weight = float(output_str) * grams_per_pound
                weights.append(weight)
            except:
                weights.append(0.0)

        # Log the output
        log_output = ''
        for w in weights:
            log_output +='{:.2f} '.format(w)
        rospy.loginfo(log_output)

        return weights

Response: Reads the weights from each of the load cells.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def run(self):
        if not self.camera.is_running:
            self.camera.start()
        while True:
            if not self.cmd_q.empty():
                cmd = self.cmd_q.get()
                if cmd[0] == 'stop':
                    self.out.close()
                    self.recording = False
                elif cmd[0] == 'start':
                    filename = cmd[1]
                    self.out = si.FFmpegWriter(filename)
                    self.recording = True
                    self.count = 0

            if self.recording:
                if self.count == 0:
                    image, _, _ = self.camera.frames()

                    if self.data_buf is None:
                        self.data_buf = np.zeros([1, image.height, image.width, image.channels])
                    self.data_buf[0,...] = image.raw_data
                    self.out.writeFrame(self.data_buf)

                self.count += 1
                if self.count == self.rate:
                    self.count = 0

Response: Continually write images to the filename specified by a command queue.


Instruction:
Make a summary of the following Python 3 code
def start(self):
        self._started = True
        self._camera = _Camera(self._actual_camera, self._cmd_q, self._res, self._codec, self._fps, self._rate)
        self._camera.start()

Response: Starts the camera recording process.


Instruction:
Create a Python 3 function for
starting recording to a given output video file.

Response:
def start_recording(self, output_file):
        """ Starts recording to a given output video file.

        Parameters
        ----------
        output_file : :obj:`str`
            filename to write video to
        """
        if not self._started:
            raise Exception("Must start the video recorder first by calling .start()!")
        if self._recording:
            raise Exception("Cannot record a video while one is already recording!")
        self._recording = True
        self._cmd_q.put(('start', output_file))


Instruction:
Can you create a Python 3 function that
stops writing video to file.

Response:
def stop_recording(self):
        """ Stops writing video to file. """
        if not self._recording:
            raise Exception("Cannot stop a video recording when it's not recording!")
        self._cmd_q.put(('stop',))
        self._recording = False


Instruction:
Create a Python 3 function to
stop the camera process.

Response:
def stop(self):
        """ Stop the camera process. """
        if not self._started:
            raise Exception("Cannot stop a video recorder before starting it!")
        self._started = False
        if self._actual_camera.is_running:
            self._actual_camera.stop()
        if self._camera is not None:
            try:
                self._camera.terminate()
            except:
                pass


Instruction:
Can you generate the documentation for the following Python 3 function
def _preprocess_data(self, data):
        original_type = data.dtype
        if len(data.shape) == 1:
            data = data[:, np.newaxis, np.newaxis]
        elif len(data.shape) == 2:
            data = data[:, :, np.newaxis]
        elif len(data.shape) == 0 or len(data.shape) > 3:
            raise ValueError(
                'Illegal data array passed to image. Must be 1, 2, or 3 dimensional numpy array')
        return data.astype(original_type)

Response: Converts a data array to the preferred 3D structure.


Instruction:
Explain what the following Python 3 code does
def rosmsg(self):
        from cv_bridge import CvBridge, CvBridgeError
        cv_bridge = CvBridge()
        try:
            return cv_bridge.cv2_to_imgmsg(self._data, encoding=self._encoding)
        except CvBridgeError as cv_bridge_exception:
            logging.error('%s' % (str(cv_bridge_exception)))

Response: Return the ROS Image object.


Instruction:
Can you generate the documentation for the following Python 3 function
def can_convert(x):
        if len(x.shape) < 2 or len(x.shape) > 3:
            return False
        dtype = x.dtype
        height = x.shape[0]
        width = x.shape[1]
        channels = 1
        if len(x.shape) == 3:
            channels = x.shape[2]
        if channels > 4:
            return False
        return True

Response: Returns True if x can be converted to an image False otherwise.


Instruction:
Write a Python 3 script for
converting an array of data to an Image based on the values in the array and the data format.

Response:
def from_array(x, frame='unspecified'):
        """ Converts an array of data to an Image based on the values in the array and the data format. """

        if not Image.can_convert(x):
            raise ValueError('Cannot convert array to an Image!')

        dtype = x.dtype
        height = x.shape[0]
        width = x.shape[1]
        channels = 1
        if len(x.shape) == 3:
            channels = x.shape[2]
        if dtype == np.uint8:
            if channels == 1:
                if np.any((x % BINARY_IM_MAX_VAL) > 0):
                    return GrayscaleImage(x, frame)
                return BinaryImage(x, frame)
            elif channels == 3:
                return ColorImage(x, frame)
            else:
                raise ValueError(
                    'No available image conversion for uint8 array with 2 channels')
        elif dtype == np.uint16:
            if channels != 1:
                raise ValueError(
                    'No available image conversion for uint16 array with 2 or 3 channels')
            return GrayscaleImage(x, frame)
        elif dtype == np.float32 or dtype == np.float64:
            if channels == 1:
                return DepthImage(x, frame)
            elif channels == 2:
                return GdImage(x, frame)
            elif channels == 3:
                logging.warning('Converting float array to uint8')
                return ColorImage(x.astype(np.uint8), frame)
            return RgbdImage(x, frame)
        else:
            raise ValueError(
                'Conversion for dtype %s not supported!' %
                (str(dtype)))


Instruction:
Can you tell what is the following Python 3 function doing
def transform(self, translation, theta, method='opencv'):
        theta = np.rad2deg(theta)
        trans_map = np.float32(
            [[1, 0, translation[1]], [0, 1, translation[0]]])
        rot_map = cv2.getRotationMatrix2D(
            (self.center[1], self.center[0]), theta, 1)
        trans_map_aff = np.r_[trans_map, [[0, 0, 1]]]
        rot_map_aff = np.r_[rot_map, [[0, 0, 1]]]
        full_map = rot_map_aff.dot(trans_map_aff)
        full_map = full_map[:2, :]
        if method == 'opencv':
            im_data_tf = cv2.warpAffine(
                self.data, full_map, (self.width, self.height), flags=cv2.INTER_NEAREST)
        else:
            im_data_tf = sni.affine_transform(self.data,
                                              matrix=full_map[:, :2],
                                              offset=full_map[:, 2],
                                              order=0)
        return type(self)(
            im_data_tf.astype(
                self.data.dtype),
            frame=self._frame)

Response: Creates a new image by translating and rotating the current image.


Instruction:
Create a Python 3 function for
creating a new image that is aligned to the given height and width.

Response:
def align(self, scale, center, angle, height, width):
        """ Create a thumbnail from the original image that
        is scaled by the given factor, centered on the center pixel, oriented along the grasp angle, and cropped to the desired height and width.

        Parameters
        ----------
        scale : float
            scale factor to apply
        center : 2D array
            array containing the row and column index of the pixel to center on
        angle : float
            angle to align the image to
        height : int
            height of the final image
        width : int
            width of the final image
        """
        # rescale
        scaled_im = self.resize(scale)

        # transform
        cx = scaled_im.center[1]
        cy = scaled_im.center[0]
        dx = cx - center[0] * scale
        dy = cy - center[1] * scale
        translation = np.array([dy, dx])
        tf_im = scaled_im.transform(translation, angle)

        # crop
        aligned_im = tf_im.crop(height, width)
        return aligned_im


Instruction:
Explain what the following Python 3 code does
def gradients(self):
        g = np.gradient(self.data.astype(np.float32))
        return g

Response: Return the gradient as a pair of numpy arrays.


Instruction:
How would you explain what the following Python 3 function does
def linear_to_ij(self, linear_inds):
        return np.c_[linear_inds / self.width, linear_inds % self.width]

Response: Converts linear indices to row and column coordinates.


Instruction:
Here you have a function in Python 3, explain what it does
def is_same_shape(self, other_im, check_channels=False):
        if self.height == other_im.height and self.width == other_im.width:
            if check_channels and self.channels != other_im.channels:
                return False
            return True
        return False

Response: Checks if two images have the same height and width and optionally channels.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def mask_by_ind(self, inds):
        new_data = np.zeros(self.shape)
        for ind in inds:
            new_data[ind[0], ind[1]] = self.data[ind[0], ind[1]]
        return type(self)(new_data.astype(self.data.dtype), self.frame)

Response:
Create a new image by zeroing out data at locations not in the
            given indices.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def mask_by_linear_ind(self, linear_inds):
        inds = self.linear_to_ij(linear_inds)
        return self.mask_by_ind(inds)

Response:
Create a new image by zeroing out data at locations not in the
            given indices.


Instruction:
Write a Python 3 script for
creating a median Image from a list of Images.

Response:
def median_images(images):
        """Create a median Image from a list of Images.

        Parameters
        ----------
        :obj:`list` of :obj:`Image`
            A list of Image objects.

        Returns
        -------
        :obj:`Image`
            A new Image of the same type whose data is the median of all of
            the images' data.
        """
        images_data = np.array([image.data for image in images])
        median_image_data = np.median(images_data, axis=0)

        an_image = images[0]
        return type(an_image)(
            median_image_data.astype(
                an_image.data.dtype),
            an_image.frame)


Instruction:
Can you implement a function in Python 3 that
creates a min Image from a list of Images.

Response:
def min_images(images):
        """Create a min Image from a list of Images.

        Parameters
        ----------
        :obj:`list` of :obj:`Image`
            A list of Image objects.

        Returns
        -------
        :obj:`Image`
            A new Image of the same type whose data is the min of all of
            the images' data.
        """
        images_data = np.array([image.data for image in images])
        images_data[images_data == 0] = np.inf
        min_image_data = np.min(images_data, axis=0)
        min_image_data[min_image_data == np.inf] = 0.0

        an_image = images[0]
        return type(an_image)(
            min_image_data.astype(
                an_image.data.dtype),
            an_image.frame)


Instruction:
Can you generate the documentation for the following Python 3 function
def apply(self, method, *args, **kwargs):
        data = method(self.data, *args, **kwargs)
        return type(self)(data.astype(self.type), self.frame)

Response: Create a new image by applying a function to the current image s data.


Instruction:
Explain what the following Python 3 code does
def crop(self, height, width, center_i=None, center_j=None):
        # compute crop center px
        height = int(np.round(height))
        width = int(np.round(width))
        if center_i is None:
            center_i = float(self.height) / 2
        if center_j is None:
            center_j = float(self.width) / 2

        # crop using PIL
        desired_start_row = int(np.floor(center_i - float(height) / 2))
        desired_end_row = int(np.floor(center_i + float(height) / 2))
        desired_start_col = int(np.floor(center_j - float(width) / 2))
        desired_end_col = int(np.floor(center_j + float(width) / 2))

        pil_im = PImage.fromarray(self.data)
        cropped_pil_im = pil_im.crop((desired_start_col,
                                      desired_start_row,
                                      desired_end_col,
                                      desired_end_row))
        crop_data = np.array(cropped_pil_im)

        if crop_data.shape[0] != height or crop_data.shape[1] != width:
            raise ValueError('Crop dims are incorrect')

        return type(self)(crop_data.astype(self.data.dtype), self._frame)

Response: Crop the image centered around center_i and center_j.


Instruction:
Write a Python 3 script to
zero out all of the image inside of a crop box.

Response:
def focus(self, height, width, center_i=None, center_j=None):
        """Zero out all of the image outside of a crop box.

        Parameters
        ----------
        height : int
            The height of the desired crop box.

        width : int
            The width of the desired crop box.

        center_i : int
            The center height point of the crop box. If not specified, the center
            of the image is used.

        center_j : int
            The center width point of the crop box. If not specified, the center
            of the image is used.

        Returns
        -------
        :obj:`Image`
            A new Image of the same type and size that is zeroed out except
            within the crop box.
        """
        if center_i is None:
            center_i = self.height / 2
        if center_j is None:
            center_j = self.width / 2

        start_row = int(max(0, center_i - height / 2))
        end_row = int(min(self.height - 1, center_i + height / 2))
        start_col = int(max(0, center_j - width / 2))
        end_col = int(min(self.width - 1, center_j + width / 2))

        focus_data = np.zeros(self._data.shape)
        focus_data[start_row:end_row + 1, start_col:end_col + \
            1] = self._data[start_row:end_row + 1, start_col:end_col + 1]
        return type(self)(focus_data.astype(self._data.dtype), self._frame)


Instruction:
Write a Python 3 script for
returning the center of the image of the same type and size that is re - centered at the mean location of the nonzero pixels.

Response:
def center_nonzero(self):
        """Recenters the image on the mean of the coordinates of nonzero pixels.

        Returns
        -------
        :obj:`Image`
            A new Image of the same type and size that is re-centered
            at the mean location of the non-zero pixels.
        """
        # get the center of the nonzero pixels
        nonzero_px = np.where(self._data != 0.0)
        nonzero_px = np.c_[nonzero_px[0], nonzero_px[1]]
        mean_px = np.mean(nonzero_px, axis=0)
        center_px = (np.array(self.shape) / 2.0)[:2]
        diff_px = center_px - mean_px

        # transform image
        nonzero_px_tf = nonzero_px + diff_px
        nonzero_px_tf[:, 0] = np.max(
            np.c_[np.zeros(nonzero_px_tf[:, 0].shape), nonzero_px_tf[:, 0]], axis=1)
        nonzero_px_tf[:, 0] = np.min(np.c_[(
            self.height - 1) * np.ones(nonzero_px_tf[:, 0].shape), nonzero_px_tf[:, 0]], axis=1)
        nonzero_px_tf[:, 1] = np.max(
            np.c_[np.zeros(nonzero_px_tf[:, 1].shape), nonzero_px_tf[:, 1]], axis=1)
        nonzero_px_tf[:, 1] = np.min(np.c_[(
            self.width - 1) * np.ones(nonzero_px_tf[:, 1].shape), nonzero_px_tf[:, 1]], axis=1)
        nonzero_px = nonzero_px.astype(np.uint16)
        nonzero_px_tf = nonzero_px_tf.astype(np.uint16)
        shifted_data = np.zeros(self.shape)
        shifted_data[nonzero_px_tf[:, 0], nonzero_px_tf[:, 1],
                     :] = self.data[nonzero_px[:, 0], nonzero_px[:, 1]].reshape(-1, self.channels)

        return type(self)(
            shifted_data.astype(
                self.data.dtype), frame=self._frame), diff_px


Instruction:
Given the following Python 3 function, write the documentation
def nonzero_pixels(self):
        nonzero_px = np.where(np.sum(self.raw_data, axis=2) > 0)
        nonzero_px = np.c_[nonzero_px[0], nonzero_px[1]]
        return nonzero_px

Response: Return an array of the nonzero pixels.


Instruction:
Implement a Python 3 function for
returning an array of the zero pixels.

Response:
def zero_pixels(self):
        """ Return an array of the zero pixels.

        Returns
        -------
        :obj:`numpy.ndarray`
             Nx2 array of the zero pixels
        """
        zero_px = np.where(np.sum(self.raw_data, axis=2) == 0)
        zero_px = np.c_[zero_px[0], zero_px[1]]
        return zero_px


Instruction:
Write a Python 3 function that can
return an array of the NaN pixels.

Response:
def nan_pixels(self):
        """ Return an array of the NaN pixels.

        Returns
        -------
        :obj:`numpy.ndarray`
             Nx2 array of the NaN pixels
        """
        nan_px = np.where(np.isnan(np.sum(self.raw_data, axis=2)))
        nan_px = np.c_[nan_px[0], nan_px[1]]
        return nan_px


Instruction:
Can you generate the documentation for the following Python 3 function
def finite_pixels(self):
        finite_px = np.where(np.isfinite(self.data))
        finite_px = np.c_[finite_px[0], finite_px[1]]
        return finite_px

Response: Return an array of the finite pixels.


Instruction:
Can you implement a function in Python 3 that
replaces all zeros in the image with a specified value.

Response:
def replace_zeros(self, val, zero_thresh=0.0):
        """ Replaces all zeros in the image with a specified value

        Returns
        -------
        image dtype
             value to replace zeros with
        """
        new_data = self.data.copy()
        new_data[new_data <= zero_thresh] = val
        return type(self)(new_data.astype(self.data.dtype), frame=self._frame)


Instruction:
Here you have a function in Python 3, explain what it does
def save(self, filename):
        filename = str(filename)
        file_root, file_ext = os.path.splitext(filename)
        if file_ext in COLOR_IMAGE_EXTS:
            im_data = self._image_data()
            if im_data.dtype.type == np.uint8:
                pil_image = PImage.fromarray(im_data.squeeze())
                pil_image.save(filename)
            else:
                try:
                    import png
                except:
                    raise ValueError('PyPNG not installed! Cannot save 16-bit images')
                png.fromarray(im_data, 'L').save(filename)
        elif file_ext == '.npy':
            np.save(filename, self._data)
        elif file_ext == '.npz':
            np.savez_compressed(filename, self._data)
        else:
            raise ValueError('Extension %s not supported' % (file_ext))

Response: Writes the image to a file.


Instruction:
Can you tell what is the following Python 3 function doing
def savefig(self, output_path, title, dpi=400, format='png', cmap=None):
        plt.figure()
        plt.imshow(self.data, cmap=cmap)
        plt.title(title)
        plt.axis('off')
        title_underscore = title.replace(' ', '_')
        plt.savefig(
            os.path.join(
                output_path,
                '{0}.{1}'.format(
                    title_underscore,
                    format)),
            dpi=dpi,
            format=format)

Response: Write the image to a file using matplotlib.


Instruction:
Create a Python 3 function to
load a data matrix from a given file.

Response:
def load_data(filename):
        """Loads a data matrix from a given file.

        Parameters
        ----------
        filename : :obj:`str`
            The file to load the data from. Must be one of .png, .jpg,
            .npy, or .npz.

        Returns
        -------
        :obj:`numpy.ndarray`
            The data array read from the file.
        """
        file_root, file_ext = os.path.splitext(filename)
        data = None
        if file_ext.lower() in COLOR_IMAGE_EXTS:
            data = cv2.cvtColor(cv2.imread(filename), cv2.COLOR_BGR2RGB)
        elif file_ext == '.npy':
            data = np.load(filename)
        elif file_ext == '.npz':
            data = np.load(filename)['arr_0']
        else:
            raise ValueError('Extension %s not supported' % (file_ext))
        return data


Instruction:
Can you implement a function in Python 3 that
checks that the given data is a uint8 array with one or three channels.

Response:
def _check_valid_data(self, data):
        """Checks that the given data is a uint8 array with one or three
        channels.

        Parameters
        ----------
        data : :obj:`numpy.ndarray`
            The data to check.

        Raises
        ------
        ValueError
            If the data is invalid.
        """
        if data.dtype.type is not np.uint8:
            raise ValueError(
                'Illegal data type. Color images only support uint8 arrays')

        if len(data.shape) != 3 or data.shape[2] != 3:
            raise ValueError(
                'Illegal data type. Color images only support three channels')


Instruction:
Can you generate a brief explanation for the following Python 3 code
def bgr2rgb(self):
        new_data = cv2.cvtColor(self.raw_data, cv2.COLOR_BGR2RGB)
        return ColorImage(new_data, frame=self.frame, encoding='rgb8')

Response: Converts data using cv2.


Instruction:
Given the following Python 3 function, write the documentation
def rgb2bgr(self):
        new_data = cv2.cvtColor(self.raw_data, cv2.COLOR_RGB2BGR)
        return ColorImage(new_data, frame=self.frame, encoding='bgr8')

Response: Converts data using cv2.


Instruction:
Write a Python 3 function that can
swap the two channels specified in the tuple.

Response:
def swap_channels(self, channel_swap):
        """ Swaps the two channels specified in the tuple.

        Parameters
        ----------
        channel_swap : :obj:`tuple` of int
            the two channels to swap

        Returns
        -------
        :obj:`ColorImage`
            color image with cols swapped
        """
        if len(channel_swap) != 2:
            raise ValueError('Illegal value for channel swap')
        ci = channel_swap[0]
        cj = channel_swap[1]
        if ci < 0 or ci > 2 or cj < 0 or cj > 2:
            raise ValueError('Channels must be between 0 and 1')
        new_data = self.data.copy()
        new_data[:, :, ci] = self.data[:, :, cj]
        new_data[:, :, cj] = self.data[:, :, ci]
        return ColorImage(new_data, frame=self._frame)


Instruction:
Create a Python 3 function for
finding the corners of an sx X sy chessboard in the image.

Response:
def find_chessboard(self, sx=6, sy=9):
        """Finds the corners of an sx X sy chessboard in the image.

        Parameters
        ----------
        sx : int
            Number of chessboard corners in x-direction.
        sy : int
            Number of chessboard corners in y-direction.

        Returns
        -------
        :obj:`list` of :obj:`numpy.ndarray`
            A list containing the 2D points of the corners of the detected
            chessboard, or None if no chessboard found.
        """
        # termination criteria
        criteria = (cv2.TERM_CRITERIA_EPS +
                    cv2.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((sx * sy, 3), np.float32)
        objp[:, :2] = np.mgrid[0:sx, 0:sy].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.

        # create images
        img = self.data.astype(np.uint8)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

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

        # If found, add object points, image points (after refining them)
        if ret:
            objpoints.append(objp)
            cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)
            imgpoints.append(corners)

            if corners is not None:
                return corners.squeeze()
        return None


Instruction:
How would you explain what the following Python 3 function does
def foreground_mask(
            self,
            tolerance,
            ignore_black=True,
            use_hsv=False,
            scale=8,
            bgmodel=None):
        """Creates a binary image mask for the foreground of an image against
        a uniformly colored background. The background is assumed to be the mode value of the histogram
        for each of the color channels.

        Parameters
        ----------
        tolerance : int
            A +/- level from the detected mean backgroud color. Pixels withing
            this range will be classified as background pixels and masked out.

        ignore_black : bool
            If True, the zero pixels will be ignored
            when computing the background model.

        use_hsv : bool
            If True, image will be converted to HSV for background model
            generation.

        scale : int
            Size of background histogram bins -- there will be BINARY_IM_MAX_VAL/size bins
            in the color histogram for each channel.

        bgmodel : :obj:`list` of int
            A list containing the red, green, and blue channel modes of the
            background. If this is None, a background model will be generated
            using the other parameters.

        Returns
        -------
        :obj:`BinaryImage`
            A binary image that masks out the background from the current
            ColorImage.
        """
        # get a background model
        if bgmodel is None:
            bgmodel = self.background_model(ignore_black=ignore_black,
                                            use_hsv=use_hsv,
                                            scale=scale)

        # get the bounds
        lower_bound = np.array(
            [bgmodel[i] - tolerance for i in range(self.channels)])
        upper_bound = np.array(
            [bgmodel[i] + tolerance for i in range(self.channels)])
        orig_zero_indices = np.where(np.sum(self._data, axis=2) == 0)

        # threshold
        binary_data = cv2.inRange(self.data, lower_bound, upper_bound)
        binary_data[:, :, ] = (BINARY_IM_MAX_VAL - binary_data[:, :, ])
        binary_data[orig_zero_indices[0], orig_zero_indices[1], ] = 0.0
        binary_im = BinaryImage(binary_data.astype(np.uint8), frame=self.frame)
        return binary_im

Response: Creates a binary image mask for the foreground of an image against the current color image.


Instruction:
How would you code a function in Python 3 to
create a background model for the given image.

Response:
def background_model(self, ignore_black=True, use_hsv=False, scale=8):
        """Creates a background model for the given image. The background
        color is given by the modes of each channel's histogram.

        Parameters
        ----------
        ignore_black : bool
            If True, the zero pixels will be ignored
            when computing the background model.

        use_hsv : bool
            If True, image will be converted to HSV for background model
            generation.

        scale : int
            Size of background histogram bins -- there will be BINARY_IM_MAX_VAL/size bins
            in the color histogram for each channel.

        Returns
        -------
            A list containing the red, green, and blue channel modes of the
            background.
        """
        # hsv color
        data = self.data
        if use_hsv:
            pil_im = PImage.fromarray(self._data)
            pil_im = pil_im.convert('HSV')
            data = np.asarray(pil_im)

        # find the black pixels
        nonblack_pixels = np.where(np.sum(self.data, axis=2) > 0)
        r_data = self.r_data
        g_data = self.g_data
        b_data = self.b_data
        if ignore_black:
            r_data = r_data[nonblack_pixels[0], nonblack_pixels[1]]
            g_data = g_data[nonblack_pixels[0], nonblack_pixels[1]]
            b_data = b_data[nonblack_pixels[0], nonblack_pixels[1]]

        # generate histograms for each channel
        bounds = (0, np.iinfo(np.uint8).max + 1)
        num_bins = bounds[1] / scale
        r_hist, _ = np.histogram(r_data, bins=num_bins, range=bounds)
        g_hist, _ = np.histogram(g_data, bins=num_bins, range=bounds)
        b_hist, _ = np.histogram(b_data, bins=num_bins, range=bounds)
        hists = (r_hist, g_hist, b_hist)

        # find the thesholds as the modes of the image
        modes = [0 for i in range(self.channels)]
        for i in range(self.channels):
            modes[i] = scale * np.argmax(hists[i])

        return modes


Instruction:
Create a Python 3 function to
draw a white box on the image.

Response:
def draw_box(self, box):
        """Draw a white box on the image.

        Parameters
        ----------
        :obj:`autolab_core.Box`
            A 2D box to draw in the image.

        Returns
        -------
        :obj:`ColorImage`
            A new image that is the same as the current one, but with
            the white box drawn in.
        """
        box_data = self._data.copy()
        min_i = box.min_pt[1]
        min_j = box.min_pt[0]
        max_i = box.max_pt[1]
        max_j = box.max_pt[0]

        # draw the vertical lines
        for j in range(min_j, max_j):
            box_data[min_i, j, :] = BINARY_IM_MAX_VAL * np.ones(self.channels)
            box_data[max_i, j, :] = BINARY_IM_MAX_VAL * np.ones(self.channels)

        # draw the horizontal lines
        for i in range(min_i, max_i):
            box_data[i, min_j, :] = BINARY_IM_MAX_VAL * np.ones(self.channels)
            box_data[i, max_j, :] = BINARY_IM_MAX_VAL * np.ones(self.channels)

        return ColorImage(box_data, self._frame)


Instruction:
Can you tell what is the following Python 3 function doing
def nonzero_hsv_data(self):
        hsv_data = cv2.cvtColor(self.data, cv2.COLOR_BGR2HSV)
        nonzero_px = self.nonzero_pixels()
        return hsv_data[nonzero_px[:, 0], nonzero_px[:, 1], ...]

Response: Computes non zero hsv values for the image.


Instruction:
Create a Python 3 function to
segment a color image using KMeans based on spatial and color distances.

Response:
def segment_kmeans(self, rgb_weight, num_clusters, hue_weight=0.0):
        """
        Segment a color image using KMeans based on spatial and color distances.
        Black pixels will automatically be assigned to their own 'background' cluster.

        Parameters
        ----------
        rgb_weight : float
            weighting of RGB distance relative to spatial and hue distance
        num_clusters : int
            number of clusters to use
        hue_weight : float
            weighting of hue from hsv relative to spatial and RGB distance

        Returns
        -------
        :obj:`SegmentationImage`
            image containing the segment labels
        """
        # form features array
        label_offset = 1
        nonzero_px = np.where(self.data != 0.0)
        nonzero_px = np.c_[nonzero_px[0], nonzero_px[1]]

        # get hsv data if specified
        color_vals = rgb_weight * \
            self._data[nonzero_px[:, 0], nonzero_px[:, 1], :]
        if hue_weight > 0.0:
            hsv_data = cv2.cvtColor(self.data, cv2.COLOR_BGR2HSV)
            color_vals = np.c_[color_vals, hue_weight *
                               hsv_data[nonzero_px[:, 0], nonzero_px[:, 1], :1]]
        features = np.c_[nonzero_px, color_vals.astype(np.float32)]

        # perform KMeans clustering
        kmeans = sc.KMeans(n_clusters=num_clusters)
        labels = kmeans.fit_predict(features)

        # create output label array
        label_im = np.zeros([self.height, self.width]).astype(np.uint8)
        label_im[nonzero_px[:, 0], nonzero_px[:, 1]] = labels + label_offset
        return SegmentationImage(label_im, frame=self.frame)


Instruction:
Here you have a function in Python 3, explain what it does
def inpaint(self, win_size=3, rescale_factor=1.0):
        # get original shape
        orig_shape = (self.height, self.width)

        # resize the image
        resized_data = self.resize(rescale_factor, interp='nearest').data

        # inpaint smaller image
        mask = 1 * (np.sum(resized_data, axis=2) == 0)
        inpainted_data = cv2.inpaint(resized_data, mask.astype(np.uint8),
                                     win_size, cv2.INPAINT_TELEA)
        inpainted_im = ColorImage(inpainted_data, frame=self.frame)

        # fill in zero pixels with inpainted and resized image
        filled_data = inpainted_im.resize(
            orig_shape, interp='bilinear').data
        new_data = self.data
        new_data[self.data == 0] = filled_data[self.data == 0]
        return ColorImage(new_data, frame=self.frame)

Response: Fills in the zero pixels in the image with the inpainted image.


Instruction:
Write a Python 3 function that can
convert the color image to grayscale using OpenCV.

Response:
def to_grayscale(self):
        """Converts the color image to grayscale using OpenCV.

        Returns
        -------
        :obj:`GrayscaleImage`
            Grayscale image corresponding to original color image.
        """
        gray_data = cv2.cvtColor(self.data, cv2.COLOR_RGB2GRAY)
        return GrayscaleImage(gray_data, frame=self.frame)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def open(filename, frame='unspecified'):
        data = Image.load_data(filename).astype(np.uint8)
        return ColorImage(data, frame)

Response: Creates a ColorImage from a file.


Instruction:
Make a summary of the following Python 3 code
def _check_valid_data(self, data):
        if data.dtype.type is not np.float32 and \
                data.dtype.type is not np.float64:
            raise ValueError(
                'Illegal data type. Depth images only support float arrays')

        if len(data.shape) == 3 and data.shape[2] != 1:
            raise ValueError(
                'Illegal data type. Depth images only support single channel')

Response: Checks that the given data is a float array with one channel.


Instruction:
Write a Python 3 script to
return the data in image format with scaling and conversion to uint8 types.

Response:
def _image_data(self, normalize=False,
                    min_depth=MIN_DEPTH,
                    max_depth=MAX_DEPTH,
                    twobyte=False):
        """Returns the data in image format, with scaling and conversion to uint8 types.

        Parameters
        ----------
        normalize : bool
            whether or not to normalize by the min and max depth of the image
        min_depth : float
            minimum depth value for the normalization
        max_depth : float
            maximum depth value for the normalization
        twobyte: bool
            whether or not to use 16-bit encoding

        Returns
        -------
        :obj:`numpy.ndarray` of uint8
            A 3D matrix representing the image. The first dimension is rows, the
            second is columns, and the third is a set of 3 RGB values, each of
            which is simply the depth entry scaled to between 0 and BINARY_IM_MAX_VAL.
        """
        max_val = BINARY_IM_MAX_VAL
        if twobyte:
            max_val = np.iinfo(np.uint16).max

        if normalize:
            min_depth = np.min(self._data)
            max_depth = np.max(self._data)
            depth_data = (self._data - min_depth) / (max_depth - min_depth)
            depth_data = float(max_val) * depth_data.squeeze()
        else:
            zero_px = np.where(self._data == 0)
            zero_px = np.c_[zero_px[0], zero_px[1], zero_px[2]]
            depth_data = ((self._data - min_depth) * \
                          (float(max_val) / (max_depth - min_depth))).squeeze()
            depth_data[zero_px[:,0], zero_px[:,1]] = 0
        im_data = np.zeros([self.height, self.width, 3])
        im_data[:, :, 0] = depth_data
        im_data[:, :, 1] = depth_data
        im_data[:, :, 2] = depth_data
        if twobyte:
            return im_data.astype(np.uint16)
        return im_data.astype(np.uint8)


Instruction:
Can you generate the documentation for the following Python 3 function
def threshold(self, front_thresh=0.0, rear_thresh=100.0):
        data = np.copy(self._data)
        data[data < front_thresh] = 0.0
        data[data > rear_thresh] = 0.0
        return DepthImage(data, self._frame)

Response: Creates a new DepthImage by setting all depths less than front_thresh and greater than rear_thresh to 0. 0.


Instruction:
Given the following Python 3 function, write the documentation
def threshold_gradients(self, grad_thresh):
        data = np.copy(self._data)
        gx, gy = self.gradients()
        gradients = np.zeros([gx.shape[0], gx.shape[1], 2])
        gradients[:, :, 0] = gx
        gradients[:, :, 1] = gy
        gradient_mags = np.linalg.norm(gradients, axis=2)
        ind = np.where(gradient_mags > grad_thresh)
        data[ind[0], ind[1]] = 0.0
        return DepthImage(data, self._frame)

Response: Creates a new DepthImage by zeroing out all depths with magnitude greater than grad_thresh.


Instruction:
Given the following Python 3 function, write the documentation
def threshold_gradients_pctile(self, thresh_pctile, min_mag=0.0):
        data = np.copy(self._data)
        gx, gy = self.gradients()
        gradients = np.zeros([gx.shape[0], gx.shape[1], 2])
        gradients[:, :, 0] = gx
        gradients[:, :, 1] = gy
        gradient_mags = np.linalg.norm(gradients, axis=2)
        grad_thresh = np.percentile(gradient_mags, thresh_pctile)
        ind = np.where(
            (gradient_mags > grad_thresh) & (
                gradient_mags > min_mag))
        data[ind[0], ind[1]] = 0.0
        return DepthImage(data, self._frame)

Response: Creates a new DepthImage by zeroing out all depths with magnitude greater than some percentile of all gradients.


Instruction:
How would you explain what the following Python 3 function does
def inpaint(self, rescale_factor=1.0):
        # get original shape
        orig_shape = (self.height, self.width)

        # form inpaint kernel
        inpaint_kernel = np.array([[1, 1, 1], [1, 0, 1], [1, 1, 1]])

        # resize the image
        resized_data = self.resize(rescale_factor, interp='nearest').data

        # inpaint the smaller image
        cur_data = resized_data.copy()
        zeros = (cur_data == 0)
        while np.any(zeros):
            neighbors = ssg.convolve2d((cur_data != 0), inpaint_kernel,
                                       mode='same', boundary='symm')
            avg_depth = ssg.convolve2d(cur_data, inpaint_kernel,
                                       mode='same', boundary='symm')
            avg_depth[neighbors > 0] = avg_depth[neighbors > 0] / \
                neighbors[neighbors > 0]
            avg_depth[neighbors == 0] = 0
            avg_depth[resized_data > 0] = resized_data[resized_data > 0]
            cur_data = avg_depth
            zeros = (cur_data == 0)

        # fill in zero pixels with inpainted and resized image
        inpainted_im = DepthImage(cur_data, frame=self.frame)
        filled_data = inpainted_im.resize(
            orig_shape, interp='bilinear').data
        new_data = np.copy(self.data)
        new_data[self.data == 0] = filled_data[self.data == 0]
        return DepthImage(new_data, frame=self.frame)

Response: In - place inpainting of the image.


Instruction:
Given the following Python 3 function, write the documentation
def invalid_pixel_mask(self):
        # init mask buffer
        mask = np.zeros([self.height, self.width, 1]).astype(np.uint8)

        # update invalid pixels
        zero_pixels = self.zero_pixels()
        nan_pixels = self.nan_pixels()
        mask[zero_pixels[:, 0], zero_pixels[:, 1]] = BINARY_IM_MAX_VAL
        mask[nan_pixels[:, 0], nan_pixels[:, 1]] = BINARY_IM_MAX_VAL
        return BinaryImage(mask, frame=self.frame)

Response: Returns a binary mask for the NaN - and zero - valued pixels.


Instruction:
Make a summary of the following Python 3 code
def pixels_farther_than(self, depth_im, filter_equal_depth=False):
        # take closest pixel
        if filter_equal_depth:
            farther_px = np.where((self.data > depth_im.data) & (np.isfinite(depth_im.data)))
        else:
            farther_px = np.where((self.data >= depth_im.data) & (np.isfinite(depth_im.data)))
        farther_px = np.c_[farther_px[0], farther_px[1]]
        return farther_px

Response: Returns the pixels that are farther away than those in the corresponding depth image.


Instruction:
Can you tell what is the following Python 3 function doing
def combine_with(self, depth_im):
        new_data = self.data.copy()
        # replace zero pixels
        new_data[new_data == 0] = depth_im.data[new_data == 0]
        # take closest pixel
        new_data[(new_data > depth_im.data) & (depth_im.data > 0)] = depth_im.data[(
            new_data > depth_im.data) & (depth_im.data > 0)]
        return DepthImage(new_data, frame=self.frame)

Response: Returns a new DepthImage object with the values of this DepthImage and the same depth image.


Instruction:
Create a Python 3 function for
creating a BinaryImage from the depth image.

Response:
def to_binary(self, threshold=0.0):
        """Creates a BinaryImage from the depth image. Points where the depth
        is greater than threshold are converted to ones, and all other points
        are zeros.

        Parameters
        ----------
        threshold : float
            The depth threshold.

        Returns
        -------
        :obj:`BinaryImage`
            A BinaryImage where all 1 points had a depth greater than threshold
            in the DepthImage.
        """
        data = BINARY_IM_MAX_VAL * (self._data > threshold)
        return BinaryImage(data.astype(np.uint8), self._frame)


Instruction:
Can you write a function in Python 3 where it
converts the image to a color image.

Response:
def to_color(self, normalize=False):
        """ Convert to a color image.

        Parameters
        ----------
        normalize : bool
             whether or not to normalize by the maximum depth

        Returns
        -------
        :obj:`ColorImage`
            color image corresponding to the depth image
        """
        im_data = self._image_data(normalize=normalize)
        return ColorImage(im_data, frame=self._frame)


Instruction:
Can you generate the documentation for the following Python 3 function
def to_float(self):
        return DepthImage(self.data.astype(np.float32), frame=self.frame)

Response: Converts to 32 - bit float data.


Instruction:
Implement a function in Python 3 to
compute a PointNormalCloud from the depth image.

Response:
def point_normal_cloud(self, camera_intr):
        """Computes a PointNormalCloud from the depth image.

        Parameters
        ----------
        camera_intr : :obj:`CameraIntrinsics`
            The camera parameters on which this depth image was taken.

        Returns
        -------
        :obj:`autolab_core.PointNormalCloud`
            A PointNormalCloud created from the depth image.
        """
        point_cloud_im = camera_intr.deproject_to_image(self)
        normal_cloud_im = point_cloud_im.normal_cloud_im()
        point_cloud = point_cloud_im.to_point_cloud()
        normal_cloud = normal_cloud_im.to_normal_cloud()
        return PointNormalCloud(
            point_cloud.data,
            normal_cloud.data,
            frame=self._frame)


Instruction:
Explain what the following Python 3 code does
def open(filename, frame='unspecified'):
        file_root, file_ext = os.path.splitext(filename)
        data = Image.load_data(filename)
        if file_ext.lower() in COLOR_IMAGE_EXTS:
            data = (data * (MAX_DEPTH / BINARY_IM_MAX_VAL)).astype(np.float32)
        return DepthImage(data, frame)

Response: Creates a DepthImage from a file.


Instruction:
Implement a function in Python 3 to
return the data in image format with scaling and conversion to uint8 types.

Response:
def _image_data(self):
        """Returns the data in image format, with scaling and conversion to uint8 types.

        Returns
        -------
        :obj:`numpy.ndarray` of uint8
            A 3D matrix representing the image. The first dimension is rows, the
            second is columns, and the third is simply the IR entry scaled to between 0 and BINARY_IM_MAX_VAL.
        """
        return (self._data * (float(BINARY_IM_MAX_VAL) / MAX_IR)).astype(np.uint8)


Instruction:
Can you tell what is the following Python 3 function doing
def resize(self, size, interp='bilinear'):
        resized_data = sm.imresize(self._data, size, interp=interp)
        return IrImage(resized_data, self._frame)

Response:
Resize the image.

        Parameters
        ----------
        size : int, float, or tuple
            * int   - Percentage of current size.
            * float - Fraction of current size.
            * tuple - Size of the output image.

        interp : :obj:`str`, optional
            Interpolation to use for re-sizing ('nearest', 'lanczos', 'bilinear',
            'bicubic', or 'cubic')

        Returns
        -------
        :obj:`IrImage`
            The resized image.


Instruction:
How would you implement a function in Python 3 that
creates an IrImage from a file.

Response:
def open(filename, frame='unspecified'):
        """Creates an IrImage from a file.

        Parameters
        ----------
        filename : :obj:`str`
            The file to load the data from. Must be one of .png, .jpg,
            .npy, or .npz.

        frame : :obj:`str`
            A string representing the frame of reference in which the new image
            lies.

        Returns
        -------
        :obj:`IrImage`
            The new IR image.
        """
        data = Image.load_data(filename)
        data = (data * (MAX_IR / BINARY_IM_MAX_VAL)).astype(np.uint16)
        return IrImage(data, frame)


Instruction:
Can you generate the documentation for the following Python 3 function
def resize(self, size, interp='bilinear'):
        resized_data = sm.imresize(self.data, size, interp=interp)
        return GrayscaleImage(resized_data, self._frame)

Response:
Resize the image.

        Parameters
        ----------
        size : int, float, or tuple
            * int   - Percentage of current size.
            * float - Fraction of current size.
            * tuple - Size of the output image.

        interp : :obj:`str`, optional
            Interpolation to use for re-sizing ('nearest', 'lanczos', 'bilinear',
            'bicubic', or 'cubic')

        Returns
        -------
        :obj:`GrayscaleImage`
            The resized image.


Instruction:
Given the following Python 3 function, write the documentation
def to_color(self):
        color_data = np.repeat(self.data[:,:,np.newaxis], 3, axis=2)
        return ColorImage(color_data, self._frame)

Response: Convert the grayscale image to a ColorImage.


Instruction:
Can you generate the documentation for the following Python 3 function
def open(filename, frame='unspecified'):
        data = Image.load_data(filename)
        return GrayscaleImage(data, frame)

Response: Creates a GrayscaleImage from a file.


Instruction:
Can you implement a function in Python 3 that
takes OR operation with this binary image and other binary image.

Response:
def pixelwise_or(self, binary_im):
        """ Takes OR operation with other binary image.

        Parameters
        ----------
        binary_im : :obj:`BinaryImage`
            binary image for and operation

        Returns
        -------
        :obj:`BinaryImage`
            OR of this binary image and other image
        """
        data = np.copy(self._data)
        ind = np.where(binary_im.data > 0)
        data[ind[0], ind[1], ...] = BINARY_IM_MAX_VAL
        return BinaryImage(data, self._frame)


Instruction:
Can you create a Python 3 function that
inverts image ( all nonzeros become zeros and vice verse ) returns a new binary image with the inverse of the image.

Response:
def inverse(self):
        """ Inverts image (all nonzeros become zeros and vice verse)
        Returns
        -------
        :obj:`BinaryImage`
            inverse of this binary image
        """
        data = np.zeros(self.shape).astype(np.uint8)
        ind = np.where(self.data == 0)
        data[ind[0], ind[1], ...] = BINARY_IM_MAX_VAL
        return BinaryImage(data, self._frame)


Instruction:
Create a Python 3 function to
remove all white connected components from the binary image.

Response:
def prune_contours(self, area_thresh=1000.0, dist_thresh=20,
                       preserve_topology=True):
        """Removes all white connected components with area less than area_thresh.
        Parameters
        ----------
        area_thresh : float
            The minimum area for which a white connected component will not be
            zeroed out.
        dist_thresh : int
            If a connected component is within dist_thresh of the top of the
            image, it will not be pruned out, regardless of its area.
        Returns
        -------
        :obj:`BinaryImage`
            The new pruned binary image.
        """
        # get all contours (connected components) from the binary image
        contours, hierarchy = cv2.findContours(
            self.data.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
        num_contours = len(contours)
        middle_pixel = np.array(self.shape)[:2] / 2
        middle_pixel = middle_pixel.reshape(1, 2)
        center_contour = None
        pruned_contours = []

        # find which contours need to be pruned
        for i in range(num_contours):
            area = cv2.contourArea(contours[i])
            if area > area_thresh:
                # check close to origin
                fill = np.zeros([self.height, self.width, 3])
                cv2.fillPoly(
                    fill,
                    pts=[
                        contours[i]],
                    color=(
                        BINARY_IM_MAX_VAL,
                        BINARY_IM_MAX_VAL,
                        BINARY_IM_MAX_VAL))
                nonzero_px = np.where(fill > 0)
                nonzero_px = np.c_[nonzero_px[0], nonzero_px[1]]
                dists = ssd.cdist(middle_pixel, nonzero_px)
                min_dist = np.min(dists)
                pruned_contours.append((contours[i], min_dist))

        if len(pruned_contours) == 0:
            return None

        pruned_contours.sort(key=lambda x: x[1])

        # keep all contours within some distance of the top
        num_contours = len(pruned_contours)
        keep_indices = [0]
        source_coords = pruned_contours[0][0].squeeze().astype(np.float32)
        for i in range(1, num_contours):
            target_coords = pruned_contours[i][0].squeeze().astype(np.float32)
            dists = ssd.cdist(source_coords, target_coords)
            min_dist = np.min(dists)
            if min_dist < dist_thresh:
                keep_indices.append(i)

        # keep the top num_areas pruned contours
        keep_indices = np.unique(keep_indices)
        pruned_contours = [pruned_contours[i][0] for i in keep_indices]

        # mask out bad areas in the image
        pruned_data = np.zeros([self.height, self.width, 3])
        for contour in pruned_contours:
            cv2.fillPoly(
                pruned_data,
                pts=[contour],
                color=(
                    BINARY_IM_MAX_VAL,
                    BINARY_IM_MAX_VAL,
                    BINARY_IM_MAX_VAL))
        pruned_data = pruned_data[:, :, 0]  # convert back to one channel

        # preserve topology of original image
        if preserve_topology:
            orig_zeros = np.where(self.data == 0)
            pruned_data[orig_zeros[0], orig_zeros[1]] = 0
        return BinaryImage(pruned_data.astype(np.uint8), self._frame)


Instruction:
How would you implement a function in Python 3 that
returns a list of Contour objects that are connected to the binary image containing the contour at the specified area.

Response:
def find_contours(self, min_area=0.0, max_area=np.inf):
        """Returns a list of connected components with an area between
        min_area and max_area.
        Parameters
        ----------
        min_area : float
            The minimum area for a contour
        max_area : float
            The maximum area for a contour
        Returns
        -------
        :obj:`list` of :obj:`Contour`
            A list of resuting contours
        """
        # get all contours (connected components) from the binary image
        _, contours, hierarchy = cv2.findContours(
            self.data.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
        num_contours = len(contours)
        kept_contours = []

        # find which contours need to be pruned
        for i in range(num_contours):
            area = cv2.contourArea(contours[i])
            logging.debug('Contour %d area: %.3f' % (len(kept_contours), area))
            if area > min_area and area < max_area:
                boundary_px = contours[i].squeeze()
                boundary_px_ij_swapped = np.zeros(boundary_px.shape)
                boundary_px_ij_swapped[:, 0] = boundary_px[:, 1]
                boundary_px_ij_swapped[:, 1] = boundary_px[:, 0]
                kept_contours.append(
                    Contour(
                        boundary_px_ij_swapped,
                        area=area,
                        frame=self._frame))

        return kept_contours


Instruction:
Can you create a Python 3 function that
generates a binary image with only the given contour filled in.

Response:
def contour_mask(self, contour):
        """ Generates a binary image with only the given contour filled in. """
        # fill in new data
        new_data = np.zeros(self.data.shape)
        num_boundary = contour.boundary_pixels.shape[0]
        boundary_px_ij_swapped = np.zeros([num_boundary, 1, 2])
        boundary_px_ij_swapped[:, 0, 0] = contour.boundary_pixels[:, 1]
        boundary_px_ij_swapped[:, 0, 1] = contour.boundary_pixels[:, 0]
        cv2.fillPoly(
            new_data, pts=[
                boundary_px_ij_swapped.astype(
                    np.int32)], color=(
                BINARY_IM_MAX_VAL, BINARY_IM_MAX_VAL, BINARY_IM_MAX_VAL))
        orig_zeros = np.where(self.data == 0)
        new_data[orig_zeros[0], orig_zeros[1]] = 0
        return BinaryImage(new_data.astype(np.uint8), frame=self._frame)


Instruction:
Here you have a function in Python 3, explain what it does
def boundary_map(self):
        # compute contours
        contours = self.find_contours()

        # fill in nonzero pixels
        new_data = np.zeros(self.data.shape)
        for contour in contours:
            new_data[contour.boundary_pixels[:, 0].astype(np.uint8),
                     contour.boundary_pixels[:, 1].astype(np.uint8)] = np.iinfo(np.uint8).max
        return BinaryImage(new_data.astype(np.uint8), frame=self.frame)

Response: Computes the boundary pixels in the image and sets them to nonzero values.


Instruction:
How would you implement a function in Python 3 that
finds the closest set of pixels from start to pixel_set.

Response:
def closest_pixel_to_set(self, start, pixel_set, direction, w=13, t=0.5):
        """Starting at pixel, moves start by direction * t until there is a
        pixel from pixel_set within a radius w of start. Then, returns start.

        Parameters
        ----------
        start : :obj:`numpy.ndarray` of float
            The initial pixel location at which to start.

        pixel_set : set of 2-tuples of float
            The set of pixels to check set intersection with

        direction : :obj:`numpy.ndarray` of float
            The 2D direction vector in which to move pixel.

        w : int
            A circular diameter in which to check for pixels.
            As soon as the current pixel has some non-zero pixel with a diameter
            w of it, this function returns the current pixel location.

        t : float
            The step size with which to move pixel along direction.

        Returns
        -------
        :obj:`numpy.ndarray` of float
            The first pixel location along the direction vector at which there
            exists some intersection with pixel_set within a radius w.
        """

        # create circular structure for checking clearance
        y, x = np.meshgrid(np.arange(w) - w / 2, np.arange(w) - w / 2)
        cur_px_y = np.ravel(y + start[0]).astype(np.uint16)
        cur_px_x = np.ravel(x + start[1]).astype(np.uint16)

        # create comparison set, check set overlap
        cur_px = set(zip(cur_px_y, cur_px_x))
        includes = True
        if np.all(
            cur_px_y >= 0) and np.all(
            cur_px_y < self.height) and np.all(
            cur_px_x >= 0) and np.all(
                cur_px_x < self.width):
            includes = not cur_px.isdisjoint(pixel_set)
        else:
            return None

        # Continue until out of bounds or sets overlap
        while not includes:
            start = start + t * direction
            cur_px_y = np.ravel(y + start[0]).astype(np.uint16)
            cur_px_x = np.ravel(x + start[1]).astype(np.uint16)
            cur_px = set(zip(cur_px_y, cur_px_x))
            if np.all(
                cur_px_y >= 0) and np.all(
                cur_px_y < self.height) and np.all(
                cur_px_x >= 0) and np.all(
                    cur_px_x < self.width):
                includes = not cur_px.isdisjoint(pixel_set)
            else:
                return None

        return start


Instruction:
Can you implement a function in Python 3 that
finds the closest all zero pixels in a 2D direction vector.

Response:
def closest_allzero_pixel(self, pixel, direction, w=13, t=0.5):
        """Starting at pixel, moves pixel by direction * t until all
        zero pixels within a radius w of pixel. Then, returns pixel.

        Parameters
        ----------
        pixel : :obj:`numpy.ndarray` of float
            The initial pixel location at which to start.

        direction : :obj:`numpy.ndarray` of float
            The 2D direction vector in which to move pixel.

        w : int
            A circular diameter in which to check for zero pixels.
            As soon as the current pixel has all zero pixels with a diameter
            w of it, this function returns the current pixel location.

        t : float
            The step size with which to move pixel along direction.

        Returns
        -------
        :obj:`numpy.ndarray` of float
            The first pixel location along the direction vector at which there
            exists all zero pixels within a radius w.
        """
        # create circular structure for checking clearance
        y, x = np.meshgrid(np.arange(w) - w / 2, np.arange(w) - w / 2)

        cur_px_y = np.ravel(y + pixel[0]).astype(np.uint16)
        cur_px_x = np.ravel(x + pixel[1]).astype(np.uint16)

        # Check if all pixels in radius are in bounds and zero-valued
        empty = False
        if np.all(
            cur_px_y >= 0) and np.all(
            cur_px_y < self.height) and np.all(
            cur_px_x >= 0) and np.all(
                cur_px_x < self.width):
            empty = np.all(self[cur_px_y, cur_px_x] <= self._threshold)
        else:
            return None

        # If some nonzero pixels, continue incrementing along direction
        # and checking for empty space
        while not empty:
            pixel = pixel + t * direction
            cur_px_y = np.ravel(y + pixel[0]).astype(np.uint16)
            cur_px_x = np.ravel(x + pixel[1]).astype(np.uint16)
            if np.all(
                cur_px_y >= 0) and np.all(
                cur_px_y < self.height) and np.all(
                cur_px_x >= 0) and np.all(
                    cur_px_x < self.width):
                empty = np.all(self[cur_px_y, cur_px_x] <= self._threshold)
            else:
                return None

        return pixel


Instruction:
Implement a function in Python 3 to
add a frame to the image.

Response:
def add_frame(
            self,
            left_boundary,
            right_boundary,
            upper_boundary,
            lower_boundary):
        """ Adds a frame to the image, e.g. turns the boundaries white

        Parameters
        ----------
        left_boundary : int
            the leftmost boundary of the frame
        right_boundary : int
            the rightmost boundary of the frame (must be greater than left_boundary)
        upper_boundary : int
            the upper boundary of the frame
        lower_boundary : int
            the lower boundary of the frame (must be greater than upper_boundary)

        Returns
        -------
        :obj:`BinaryImage`
            binary image with white (BINARY_IM_MAX_VAL) on the boundaries
        """
        # check valid boundary pixels
        left_boundary = max(0, left_boundary)
        right_boundary = min(self.width - 1, right_boundary)
        upper_boundary = max(0, upper_boundary)
        lower_boundary = min(self.height - 1, lower_boundary)

        if right_boundary < left_boundary:
            raise ValueError(
                'Left boundary must be smaller than the right boundary')
        if upper_boundary > lower_boundary:
            raise ValueError(
                'Upper boundary must be smaller than the lower boundary')

        # fill in border pixels
        bordered_data = self.data.copy()
        bordered_data[:upper_boundary, :] = BINARY_IM_MAX_VAL
        bordered_data[lower_boundary:, :] = BINARY_IM_MAX_VAL
        bordered_data[:, :left_boundary] = BINARY_IM_MAX_VAL
        bordered_data[:, right_boundary:] = BINARY_IM_MAX_VAL
        return BinaryImage(bordered_data, frame=self._frame)


Instruction:
How would you implement a function in Python 3 that
finds the black pixel with the largest distance from the white pixels.

Response:
def most_free_pixel(self):
        """ Find the black pixel with the largest distance from the white pixels.

        Returns
        -------
        :obj:`numpy.ndarray`
            2-vector containing the most free pixel
        """
        dist_tf = self.to_distance_im()
        max_px = np.where(dist_tf == np.max(dist_tf))
        free_pixel = np.array([max_px[0][0], max_px[1][0]])
        return free_pixel


Instruction:
Here you have a function in Python 3, explain what it does
def diff_with_target(self, binary_im):
        red = np.array([BINARY_IM_MAX_VAL, 0, 0])
        yellow = np.array([BINARY_IM_MAX_VAL, BINARY_IM_MAX_VAL, 0])
        green = np.array([0, BINARY_IM_MAX_VAL, 0])
        overlap_data = np.zeros([self.height, self.width, 3])
        unfilled_px = np.where((self.data == 0) & (binary_im.data > 0))
        overlap_data[unfilled_px[0], unfilled_px[1], :] = red
        filled_px = np.where((self.data > 0) & (binary_im.data > 0))
        overlap_data[filled_px[0], filled_px[1], :] = green
        spurious_px = np.where((self.data > 0) & (binary_im.data == 0))
        overlap_data[spurious_px[0], spurious_px[1], :] = yellow
        return ColorImage(overlap_data.astype(np.uint8), frame=self.frame)

Response: Creates a color image that visualizes the overlap between two images.


Instruction:
How would you explain what the following Python 3 function does
def num_adjacent(self, i, j):
        # check values
        if i < 1 or i > self.height - 2 or j < 1 and j > self.width - 2:
            raise ValueError('Pixels out of bounds')

        # count the number of blacks
        count = 0
        diffs = [[-1, 0], [1, 0], [0, -1], [0, 1]]
        for d in diffs:
            if self.data[i + d[0]][j + d[1]] > self._threshold:
                count += 1
        return count

Response: Counts the number of adjacent nonzero pixels to a given pixel.


Instruction:
Make a summary of the following Python 3 code
def to_sdf(self):
        # compute medial axis transform
        skel, sdf_in = morph.medial_axis(self.data, return_distance=True)
        useless_skel, sdf_out = morph.medial_axis(
            np.iinfo(np.uint8).max - self.data, return_distance=True)

        # convert to true sdf
        sdf = sdf_out - sdf_in
        return sdf

Response: Converts the 2D image to a 2D signed distance field.


Instruction:
Explain what the following Python 3 code does
def to_color(self):
        color_data = np.zeros([self.height, self.width, 3])
        color_data[:, :, 0] = self.data
        color_data[:, :, 1] = self.data
        color_data[:, :, 2] = self.data
        return ColorImage(color_data.astype(np.uint8), self._frame)

Response: Creates a ColorImage from the binary image.


Instruction:
Here you have a function in Python 3, explain what it does
def open(filename, frame='unspecified'):
        data = Image.load_data(filename)
        if len(data.shape) > 2 and data.shape[2] > 1:
            data = data[:, :, 0]
        return BinaryImage(data, frame)

Response: Creates a BinaryImage from a file.


Instruction:
Make a summary of the following Python 3 code
def _check_valid_data(self, data):
        if data.dtype.type is not np.float32 and \
           data.dtype.type is not np.float64:
            raise ValueError(
                'Illegal data type. RGB-D images only support float arrays')

        if len(data.shape) != 3 and data.shape[2] != 4:
            raise ValueError(
                'Illegal data type. RGB-D images only support four channel')

        color_data = data[:, :, :3]
        if np.any((color_data < 0) | (color_data > BINARY_IM_MAX_VAL)):
            raise ValueError(
                'Color channels must be in the range (0, BINARY_IM_MAX_VAL)')

Response: Checks that the given data is a float array with four channels.


Instruction:
Write a Python 3 function for
creating an RGB - D image from a separate color and depth image.

Response:
def from_color_and_depth(color_im, depth_im):
        """ Creates an RGB-D image from a separate color and depth image. """
        # check shape
        if color_im.height != depth_im.height or color_im.width != depth_im.width:
            raise ValueError('Color and depth images must have the same shape')

        # check frame
        if color_im.frame != depth_im.frame:
            raise ValueError('Color and depth images must have the same frame')

        # form composite data
        rgbd_data = np.zeros([color_im.height, color_im.width, 4])
        rgbd_data[:, :, :3] = color_im.data.astype(np.float64)
        rgbd_data[:, :, 3] = depth_im.data
        return RgbdImage(rgbd_data, frame=color_im.frame)


Instruction:
Can you tell what is the following Python 3 function doing
def color(self):
        return ColorImage(self.raw_data[:, :, :3].astype(
            np.uint8), frame=self.frame)

Response: Returns the color image.


Instruction:
Given the following Python 3 function, write the documentation
def mask_binary(self, binary_im):
        color = self.color.mask_binary(binary_im)
        depth = self.depth.mask_binary(binary_im)
        return RgbdImage.from_color_and_depth(color, depth)

Response: Create a new image by zeroing out the pixels of the given binary image.


Instruction:
How would you implement a function in Python 3 that
crops the image centered around center_i and center_j.

Response:
def crop(self, height, width, center_i=None, center_j=None):
        """Crop the image centered around center_i, center_j.

        Parameters
        ----------
        height : int
            The height of the desired image.

        width : int
            The width of the desired image.

        center_i : int
            The center height point at which to crop. If not specified, the center
            of the image is used.

        center_j : int
            The center width point at which to crop. If not specified, the center
            of the image is used.

        Returns
        -------
        :obj:`Image`
            A cropped Image of the same type.
        """
        # crop channels separately
        color_im_cropped = self.color.crop(height, width,
                                           center_i=center_i,
                                           center_j=center_j)
        depth_im_cropped = self.depth.crop(height, width,
                                           center_i=center_i,
                                           center_j=center_j)

        # return combination of cropped data
        return RgbdImage.from_color_and_depth(
            color_im_cropped, depth_im_cropped)


Instruction:
Can you tell what is the following Python 3 function doing
def transform(self, translation, theta, method='opencv'):
        # transform channels separately
        color_im_tf = self.color.transform(translation, theta, method=method)
        depth_im_tf = self.depth.transform(translation, theta, method=method)

        # return combination of cropped data
        return RgbdImage.from_color_and_depth(color_im_tf, depth_im_tf)

Response: Create a new image by translating and rotating the current image.


Instruction:
Can you create a Python 3 function that
converts to a grayscale and depth image.

Response:
def to_grayscale_depth(self):
        """ Converts to a grayscale and depth (G-D) image. """
        gray = self.color.to_grayscale()
        return GdImage.from_grayscale_and_depth(gray, self.depth)


Instruction:
How would you implement a function in Python 3 that
returns a new rgbd image with the values of a different rgbd image.

Response:
def combine_with(self, rgbd_im):
        """
        Replaces all zeros in the source rgbd image with the values of a different rgbd image

        Parameters
        ----------
        rgbd_im : :obj:`RgbdImage`
            rgbd image to combine with

        Returns
        -------
        :obj:`RgbdImage`
            the combined rgbd image
        """
        new_data = self.data.copy()
        depth_data = self.depth.data
        other_depth_data = rgbd_im.depth.data
        depth_zero_px = self.depth.zero_pixels()
        depth_replace_px = np.where(
            (other_depth_data != 0) & (
                other_depth_data < depth_data))
        depth_replace_px = np.c_[depth_replace_px[0], depth_replace_px[1]]

        # replace zero pixels
        new_data[depth_zero_px[:, 0], depth_zero_px[:, 1],
                 :] = rgbd_im.data[depth_zero_px[:, 0], depth_zero_px[:, 1], :]

        # take closest pixel
        new_data[depth_replace_px[:, 0], depth_replace_px[:, 1],
                 :] = rgbd_im.data[depth_replace_px[:, 0], depth_replace_px[:, 1], :]

        return RgbdImage(new_data, frame=self.frame)