<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def frames(self):
 """Retrieve the next frame from the tensor dataset 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 stream is not running or if all images in the directory have been used. """

        if not self._running:
            raise RuntimeError('Device pointing to %s not runnning. Cannot read frames' %(self._path_to_images))

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

        # read images
        datapoint = self._dataset.datapoint(self._im_index,
                                            TensorDatasetVirtualSensor.IMAGE_FIELDS)
        color_im = ColorImage(datapoint[TensorDatasetVirtualSensor.COLOR_IM_FIELD],
                              frame=self._frame)
        depth_im = DepthImage(datapoint[TensorDatasetVirtualSensor.DEPTH_IM_FIELD],
                              frame=self._frame)
        if self._image_rescale_factor != 1.0:
            color_im = color_im.resize(self._image_rescale_factor)
            depth_im = depth_im.resize(self._image_rescale_factor, interp='nearest')
        self._im_index = (self._im_index + 1) % self._num_images
        return color_im, depth_im, None