def correlate(img,
              weights,
              output=None,
              mode='reflect',
              cval=0.0,
              origin=0,
              backend=None,
              delta=0,
              threads=None):
    """Multidimensional correlation.

    Parameters
    ---------
    see scipy.ndimage.correlate

    Additional Parameters
    --------------------
    backend : {None, 'ndimage', 'opencv'}, optional
        If None, defaults to OpenCV for 2D images when possible.  If OpenCV is
        not available or input.ndim != 2, ndimage is always used.
    delta : float, optional
        Add this value to the filtered output.
    threads : int or None, optional
        The number of threads the OpenCV backend will use.  If None, the number
        of threads is not set internally (the value returned by
        cv2.getNumThreads() is used).  ``threads=-1`` can be used to specify
        that all available threads should be used.

    See Also
    --------
    cv2.filter2D
    """
    backend = _get_backend(img.ndim, backend)
    if mode == 'wrap' and backend == 'opencv':
        warnings.warn("mode='wrap' is unsupported by the underlying OpenCV "
                      "function... falling back to ndimage")
        backend = 'ndimage'

    if backend == 'opencv':
        if threads is not None:
            if threads < 1 and threads != -1:
                raise ValueError(
                    "Invalid number of threads: {}".format(threads))
            threads_orig = cv2.getNumThreads()
            cv2.setNumThreads(threads)
        try:
            opencv_mode = _get_opencv_mode(mode, cval)
            anchor = _get_opencv_anchor(origin, weights.shape)

            if np.isscalar(origin):
                origin = (origin, origin)
            if origin[0] != origin[1]:
                # TODO: fix: does not match ndimage if origin[0] != origin[1]
                raise NotImplementedError(
                    "origin[0] != origin[1] is not supported in opencv mode")

            kernel = weights

            # TODO: why is this coordinate swap necessary for correlate, but not
            #       for convolve?
            anchor = (anchor[1], anchor[0])

            result = cv2.filter2D(img,
                                  dst=output,
                                  ddepth=-1,
                                  kernel=kernel,
                                  anchor=anchor,
                                  delta=delta,
                                  borderType=opencv_mode)
        finally:
            if threads is not None:
                cv2.setNumThreads(threads_orig)
    elif backend == 'ndimage':
        result = ndi.correlate(img,
                               weights,
                               output=output,
                               mode=mode,
                               cval=cval,
                               origin=origin)
        if delta != 0:
            result += delta
    return result
def gaussian_filter(img,
                    sigma,
                    order=0,
                    output=None,
                    mode='reflect',
                    cval=0.0,
                    truncate=4.0,
                    backend=None,
                    threads=None):
    """Multidimensional Gaussian filter.

    Parameters
    ---------
    see scipy.ndimage.gaussian_filter

    Additional Parameters
    --------------------
    backend : {None, 'ndimage', 'opencv'}, optional
        If None, defaults to OpenCV for 2D images when possible.  If OpenCV is
        not available or input.ndim != 2, ndimage is always used.
    threads : int or None, optional
        The number of threads the OpenCV backend will use.  If None, the number
        of threads is not set internally (the value returned by
        cv2.getNumThreads() is used).  ``threads=-1`` can be used to specify
        that all available threads should be used.

    Notes
    -----
    cv2.GaussianBlur implemented for CV_8U, CV_16U, CV_16S, CV_32F, CV_64F and
    for any number of channels.

    See Also
    --------
    cv2.GaussianBlur
    """
    backend = _get_backend(img.ndim, backend)
    if backend == 'opencv':
        if mode == 'wrap':
            warnings.warn(
                "mode == 'wrap' is unsupported by the underlying OpenCV "
                "function... falling back to ndimage")
            backend = 'ndimage'
        if order != 0:
            warnings.warn("order != 0 is unsupported by the underlying OpenCV "
                          "function... falling back to ndimage")
            backend = 'ndimage'

    if backend == 'opencv':
        if threads is not None:
            if threads < 1 and threads != -1:
                raise ValueError(
                    "Invalid number of threads: {}".format(threads))
            threads_orig = cv2.getNumThreads()
            cv2.setNumThreads(threads)
        try:
            opencv_mode = _get_opencv_mode(mode, cval)
            if np.isscalar(sigma):
                sigma = (sigma, sigma)
            if np.isscalar(truncate):
                truncate = (truncate, truncate)

            # determine ksize from sigma & truncate
            # the equation used is from scipy.ndimage.gaussian_filter1d
            wx = (2 * int(truncate[1] * sigma[1] + 0.5) + 1)
            wy = (2 * int(truncate[0] * sigma[0] + 0.5) + 1)

            result = cv2.GaussianBlur(img,
                                      dst=output,
                                      ksize=(wx, wy),
                                      sigmaX=sigma[1],
                                      sigmaY=sigma[0],
                                      borderType=opencv_mode)
        finally:
            if threads is not None:
                cv2.setNumThreads(threads_orig)
    elif backend == 'ndimage':
        result = ndi.gaussian_filter(img,
                                     sigma,
                                     order=order,
                                     output=output,
                                     mode=mode,
                                     cval=cval,
                                     truncate=truncate)
    return result
def convolve(img,
             weights,
             output=None,
             mode='reflect',
             cval=0.0,
             origin=0,
             backend=None,
             delta=0,
             threads=None):
    """Multidimensional convolution.

    Parameters
    ---------
    see scipy.ndimage.convolve

    Additional Parameters
    --------------------
    backend : {None, 'ndimage', 'opencv'}, optional
        If None, defaults to OpenCV for 2D images when possible.  If OpenCV is
        not available or input.ndim != 2, ndimage is always used.
    delta : float, optional
        Add this value to the filtered output.
    threads : int or None, optional
        The number of threads the OpenCV backend will use.  If None, the number
        of threads is not set internally (the value returned by
        cv2.getNumThreads() is used).  ``threads=-1`` can be used to specify
        that all available threads should be used.

    Notes
    -----
    cv2.filter2D supports
        CV_8U input to CV_16S, CV_32F or CV_64F output
        CV_16U or CV_16S input to CV_32F or CV_64F output
        CV_32F input to CV_32F or CV_64F output
        CV_64F input to CV_64F output
        User-defined ddepth is not yet suppported in this wrapper, so the
        output will have the autoselected output depth given by ``ddepth=-1``.

    See Also
    --------
    cv2.filter2D
    """
    backend = _get_backend(img.ndim, backend)
    if mode == 'wrap' and backend == 'opencv':
        warnings.warn("mode='wrap' is unsupported by the underlying OpenCV "
                      "function... falling back to ndimage")
        backend = 'ndimage'

    if backend == 'opencv':
        if threads is not None:
            if threads < 1 and threads != -1:
                raise ValueError(
                    "Invalid number of threads: {}".format(threads))
            threads_orig = cv2.getNumThreads()
            cv2.setNumThreads(threads)
        try:
            opencv_mode = _get_opencv_mode(mode, cval)
            anchor = _get_opencv_anchor(origin, weights.shape)

            if np.isscalar(origin):
                origin = (origin, origin)
            if origin[0] != origin[1]:
                # TODO: fix: does not match ndimage if origin[0] != origin[1]
                raise NotImplementedError(
                    "origin[0] != origin[1] is not supported in opencv mode")
            """
            It is necessary to adjust the kernel and anchor for the fact that
            filter2D actually performs correlation, not convolution.

            To get a true convolution, we must flip the kernel and adjust the
            anchor point as described in the OpenCV documentation of filter2D.
            """
            kernel = weights[::-1, ::-1]
            anchor = (kernel.shape[1] - anchor[1] - 1,
                      kernel.shape[0] - anchor[0] - 1)

            result = cv2.filter2D(img,
                                  dst=output,
                                  ddepth=-1,
                                  kernel=kernel,
                                  anchor=anchor,
                                  delta=delta,
                                  borderType=opencv_mode)
        finally:
            if threads is not None:
                cv2.setNumThreads(threads_orig)
    elif backend == 'ndimage':
        result = ndi.convolve(img,
                              weights,
                              output=output,
                              mode=mode,
                              cval=cval,
                              origin=origin)
        if delta != 0:
            result += delta
    return result
def median_filter(img,
                  size=3,
                  footprint=None,
                  output=None,
                  mode='reflect',
                  cval=0.0,
                  origin=0,
                  backend=None,
                  threads=None):
    """Multi-dimensional median filter.

    Parameters
    ---------
    see scipy.ndimage.median_filter

    Additional Parameters
    --------------------
    backend : {None, 'ndimage', 'opencv'}, optional
        If None, defaults to OpenCV for 2D images when possible.  If OpenCV is
        not available or input.ndim != 2, ndimage is always used.
    threads : int or None, optional
        The number of threads the OpenCV backend will use.  If None, the number
        of threads is not set internally (the value returned by
        cv2.getNumThreads() is used).  ``threads=-1`` can be used to specify
        that all available threads should be used.


    Notes
    -----
    The OpenCV backend only supports odd-integer ``size`` and does not support
    ``footprint``.  When ``size`` is 3 or 5, filtering for uint8, uint16 and
    float32 is available.  For other sizes, only uint8 filtering can be
    performed.

    See Also
    --------
    cv2.medianBlur  (opeates on uint8, uint16 or float32)

    """
    backend = _get_backend(img.ndim, backend)
    if backend == 'opencv':
        dtype_in = img.dtype
        if footprint is not None:
            if (np.all(footprint == 1)
                    and (footprint.shape[0] == footprint.shape[1])):
                size = footprint.shape[0]
                footprint = None
            else:
                warnings.warn(
                    "footprint is unsupported by the underlying OpenCV "
                    "function... falling back to ndimage")
                backend = 'ndimage'
        if not np.isscalar(size):
            if size[0] == size[1]:
                size = size[0]
            else:
                warnings.warn(
                    "non-square size is unsupported by the underlying "
                    "OpenCV function... falling back to ndimage")
                backend = 'ndimage'

        # check for odd kernel size
        if size % 2 == 0:
            raise ValueError("OpenCV medianBlur requires odd size")

        # check for or convert to compatible dtype
        if size == 3 or size == 5:
            # uint16 and float32 only available for kernel sizes of 3 and 5
            if dtype_in in [np.uint8, np.uint16, np.float32]:
                dtype = dtype_in
            else:
                warnings.warn(
                    "OpenCV median filtering will be performed using float32 "
                    "dtype")
                dtype = np.float32
        else:
            if dtype_in in [
                    np.uint8,
            ]:
                dtype = dtype_in
            else:
                raise ValueError(
                    ("OpenCV median filter with size={} can only be performed "
                     "for uint8 dtype").format(size))
        img = np.asarray(img, dtype=dtype)

        opencv_mode = _get_opencv_mode(mode, cval)
        if opencv_mode != cv2.BORDER_REFLECT:
            warnings.warn(
                "only mode == 'reflect' is supported by the underlying "
                "OpenCV function... falling back to ndimage")
            backend = 'ndimage'
        if not np.all(np.asarray(origin) == 0):
            warnings.warn("non-zero origin is unsupported by the underlying "
                          "OpenCV function... falling back to ndimage")
            backend = 'ndimage'
    if backend == 'opencv':
        if threads is not None:
            if threads < 1 and threads != -1:
                raise ValueError(
                    "Invalid number of threads: {}".format(threads))
            threads_orig = cv2.getNumThreads()
            cv2.setNumThreads(threads)
        try:
            result = cv2.medianBlur(img, ksize=size, dst=output)
        finally:
            if threads is not None:
                cv2.setNumThreads(threads_orig)
    elif backend == 'ndimage':
        result = ndi.median_filter(img,
                                   size=size,
                                   footprint=footprint,
                                   output=output,
                                   mode=mode,
                                   cval=cval,
                                   origin=origin)
    return result
def uniform_filter(img,
                   size=3,
                   output=None,
                   mode='reflect',
                   cval=0.0,
                   origin=0,
                   backend=None,
                   normalize=True,
                   threads=None,
                   squared=False):
    """Multi-dimensional uniform filter.

    Parameters
    ---------
    see scipy.ndimage.uniform_filter

    Additional Parameters
    --------------------
    backend : {None, 'ndimage', 'opencv'}, optional
        If None, defaults to OpenCV for 2D images when possible.  If OpenCV is
        not available or input.ndim != 2, ndimage is always used.
    normalize : bool, optional
        Controls whether or not the uniform filter coefficients are normalized
        so that they sum to one.
    threads : int or None, optional
        The number of threads the OpenCV backend will use.  If None, the number
        of threads is not set internally (the value returned by
        cv2.getNumThreads() is used).  ``threads=-1`` can be used to specify
        that all available threads should be used.
    squared : bool, optional
        If True, this returns uniform_filter(img**2, ...).

    Notes
    -----
    cv2.boxFilter  when `squared == False`
    cv2.sqrBoxFilter when `squared == True`
    cv2.blur correspnds to `normalize == True` and `squared == False`

    Underlying OpenCV functions are defined for dtypes CV_8U, CV_16U, CV_16S,
    CV_32F or CV_64F.

    See Also
    --------
    cv2.boxFilter, cv2.sqrBoxFilter

    """
    backend = _get_backend(img.ndim, backend)
    if mode == 'wrap' and backend == 'opencv':
        warnings.warn("mode='wrap' is unsupported by the underlying OpenCV "
                      "function... falling back to ndimage")
        backend = 'ndimage'

    if backend == 'opencv':
        if threads is not None:
            if threads < 1 and threads != -1:
                raise ValueError(
                    "Invalid number of threads: {}".format(threads))
            threads_orig = cv2.getNumThreads()
            cv2.setNumThreads(threads)
        try:
            opencv_mode = _get_opencv_mode(mode, cval)
            if np.isscalar(size):
                size = (size, size)
            else:
                if len(size) != 2:
                    raise ValueError(
                        "size doesn't match number of image dimensions")
                size = (size[1], size[0])

            if squared:
                func = cv2.sqrBoxFilter
                kwargs = dict(_dst=output)
            else:
                func = cv2.boxFilter
                kwargs = dict(dst=output)

            result = func(img,
                          ddepth=-1,
                          ksize=size,
                          anchor=_get_opencv_anchor(origin, size),
                          normalize=normalize,
                          borderType=opencv_mode,
                          **kwargs)
        finally:
            if threads is not None:
                cv2.setNumThreads(threads_orig)
    elif backend == 'ndimage':
        if squared:
            img = img * img
        result = ndi.uniform_filter(img,
                                    size=size,
                                    output=output,
                                    mode=mode,
                                    cval=cval,
                                    origin=origin)
        if not normalize:
            # multiply output by the kernel size
            if np.isscalar(size):
                result *= size**img.ndim
            else:
                result *= np.prod(size)
    return result
Esempio n. 6
0
        def gen_batch(batch_size, num_workers=0):
            sample_list = copy(sample_list_)
            random.shuffle(sample_list)

            #-------------------------------------------------------------------
            # Set up the parallel generator
            #-------------------------------------------------------------------
            if num_workers > 0:
                #---------------------------------------------------------------
                # Set up the queues
                #---------------------------------------------------------------
                img_template = np.zeros((batch_size, self.preset.image_size.h,
                                         self.preset.image_size.w, 3),
                                        dtype=np.float32)
                label_template = np.zeros((batch_size, self.preset.num_anchors,
                                           self.num_classes + 5),
                                          dtype=np.float32)
                max_size = num_workers * 5
                n_batches = int(math.ceil(len(sample_list_) / batch_size))
                sample_queue = mp.Queue(n_batches)
                batch_queue = DataQueue(img_template, label_template, max_size)

                #---------------------------------------------------------------
                # Set up the workers. Make sure we can fork safely even if
                # OpenCV has been compiled with CUDA and multi-threading
                # support.
                #---------------------------------------------------------------
                workers = []
                os.environ['CUDA_VISIBLE_DEVICES'] = ""
                cv2_num_threads = cv2.getNumThreads()
                cv2.setNumThreads(1)
                for i in range(num_workers):
                    args = (sample_queue, batch_queue)
                    w = mp.Process(target=batch_producer, args=args)
                    workers.append(w)
                    w.start()
                del os.environ['CUDA_VISIBLE_DEVICES']
                cv2.setNumThreads(cv2_num_threads)

                #---------------------------------------------------------------
                # Fill the sample queue with data
                #---------------------------------------------------------------
                for offset in range(0, len(sample_list), batch_size):
                    samples = sample_list[offset:offset + batch_size]
                    sample_queue.put(samples)

                #---------------------------------------------------------------
                # Return the data
                #---------------------------------------------------------------
                for offset in range(0, len(sample_list), batch_size):
                    images, labels, gt_boxes = batch_queue.get()
                    num_items = len(gt_boxes)
                    yield images[:num_items], labels[:num_items], gt_boxes

                #---------------------------------------------------------------
                # Join the workers
                #---------------------------------------------------------------
                for w in workers:
                    w.join()

            #-------------------------------------------------------------------
            # Return a serial generator
            #-------------------------------------------------------------------
            else:
                for offset in range(0, len(sample_list), batch_size):
                    samples = sample_list[offset:offset + batch_size]
                    images, labels, gt_boxes = process_samples(samples)
                    yield images, labels, gt_boxes
Esempio n. 7
0
            else:
                break
        else:
            break

    # Return to the main program
    return

# --------------------------------------------- Main -----------------------------------------------

if __name__ == "__main__":
    print_message()
    print("Starting vision")

    print("Number of CPU's: {}".format(cv2.getNumberOfCPUs()))
    print("Number of threads: {}".format(cv2.getNumThreads()))

    print("Creating capture object")
    # Creating a webcam object.
    CAP = cv2.VideoCapture("rkcamsrc io-mode=4 isp-mode=2A tuning-xml-path=/etc/cam_iq/IMX219.xml ! video/x-raw, \
        format=NV12,width=640,height=480 ! videoconvert ! appsink")

    # Set the capture resolution, works best with 4:3 aspect ratio.
    # CAP.set(cv2.CAP_PROP_FRAME_WIDTH, 1440)
    # CAP.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
    # Set the exposure of the camera
    # CAP.set(cv2.CAP_PROP_EXPOSURE, -2)
    # Set the framerate on the webcam.
    # CAP.set(cv2.CAP_PROP_FPS, 30)

    print("Creating result window")