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
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
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")