Source code for arcjetCV.utils.utils

import numpy as np
import cv2 as cv
import os
from sklearn.neighbors import LocalOutlierFactor


[docs] def splitfn(fn: str): """ Splits the given file path into directory, file name, and extension. :param fn: file path :return: directory path, file name, extension """ fn = os.path.abspath(fn) path, fn = os.path.split(fn) name, ext = os.path.splitext(fn) return path, name, ext
[docs] def smooth(x,window_len=11,window='hanning'): """ Smooths the data using a window with the requested size. :param x: the input signal :param window_len: the dimension of the smoothing window; should be an odd integer :param window: the type of window from 'flat', 'hanning', 'hamming', 'bartlett', 'blackman' flat window will produce a moving average smoothing. :return: the smoothed signal Example: ```python t = np.linspace(-2, 2, 0.1) x = np.sin(t) + np.random.randn(len(t)) * 0.1 y = smooth(x) ``` """ x = np.array(x) if x.ndim != 1: raise ValueError("smooth only accepts 1 dimension arrays.") if x.size < window_len: raise ValueError("Input vector needs to be bigger than window size.") if window_len<3: return x if not window in ['flat', 'hanning', 'hamming', 'bartlett', 'blackman']: raise ValueError("Window is one of 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'") s=np.r_[x[window_len-1:0:-1],x,x[-2:-window_len-1:-1]] if window == 'flat': #moving average w=np.ones(window_len,'d') else: w=eval('np.'+window+'(window_len)') y=np.convolve(w/w.sum(),s,mode='valid') return y[int(window_len/2)-1:-int(window_len/2)-1]
[docs] def clahe_normalize(bgr): """ Applies Contrast Limited Adaptive Histogram Equalization (CLAHE) normalization to the given BGR image. :param bgr: BGR image :return: normalized BGR image """ lab = cv.cvtColor(bgr, cv.COLOR_BGR2LAB) lab[:,:,0] = cv.createCLAHE(clipLimit=2.0, tileGridSize=(9, 9)).apply(lab[:,:,0]) bgr = cv.cvtColor(lab, cv.COLOR_LAB2BGR) return bgr
[docs] def annotateImage(orig,flags,top=True,left=True): """ Annotates the original image with flags indicating overexposure and underexposure. :param orig: original image :param flags: dictionary of flags indicating overexposure and underexposure :param top: boolean, whether to annotate on the top of the image :param left: boolean, whether to annotate on the left side of the image """ try: y,x,_ = np.shape(orig) if top: yp = int(y*.035) else: yp = int(y*.85) if left: xp = int(x*.035) else: xp = int(x*.85) offset=0 for key in ['OVEREXPOSED', 'UNDEREXPOSED']: if flags[key]: cv.putText( orig, #numpy array on which text is written "{0}: {1}".format(key,True), #text (xp,yp+offset), #position at which writing has to start cv.FONT_HERSHEY_SIMPLEX, #font family 1, #font size (0, 255, 255, 255), #font color 3) #font stroke offset += int(y*.035) except: print("Annotation error")
[docs] def getOutlierMask(metrics): """ Computes the outlier mask using Local Outlier Factor (LOF). :param metrics: metrics data :return: outlier mask """ X = np.nan_to_num(np.array(metrics).T) clf = LocalOutlierFactor(n_neighbors=9, contamination='auto') # use fit_predict to compute the predicted labels of the training samples # (when LOF is used for outlier detection, the estimator has no predict, # decision_function and score_samples methods). return clf.fit_predict(X)
[docs] def annotate_image_with_frame_number(image, frame_number): """ Annotates the given image with the frame number. :param image: image to annotate :param frame_number: frame number to annotate """ # Convert frame number to string frame_text = f"Frame: {frame_number}" # Get the dimensions of the image _, width, _ = image.shape # Set the font properties font = cv.FONT_HERSHEY_SIMPLEX font_scale = 0.8 font_thickness = 2 # Calculate the size of the frame text (text_width, text_height), _ = cv.getTextSize(frame_text, font, font_scale, font_thickness) # Calculate the position to place the frame text in the top right corner text_position = (width - text_width - 10, 30) # Draw the frame text on the image cv.putText(image, frame_text, text_position, font, font_scale, (0, 255, 0), font_thickness)