diff options
| author | adamhrv <adam@ahprojects.com> | 2018-11-19 12:46:02 +0100 |
|---|---|---|
| committer | adamhrv <adam@ahprojects.com> | 2018-11-19 12:46:02 +0100 |
| commit | 4a6e67760692b9426ccfdc529619677016a57e6a (patch) | |
| tree | 6d50bd77b69f4f3bead90ca50816ab26de82469d /megapixels/notebooks/utils | |
| parent | 8c52d20132be81121d1c789951c2571bfa667119 (diff) | |
move notebooks
Diffstat (limited to 'megapixels/notebooks/utils')
| -rw-r--r-- | megapixels/notebooks/utils/HaarSaliency.py | 77 | ||||
| -rw-r--r-- | megapixels/notebooks/utils/__init__.py | 0 | ||||
| -rw-r--r-- | megapixels/notebooks/utils/imx.py | 82 |
3 files changed, 159 insertions, 0 deletions
diff --git a/megapixels/notebooks/utils/HaarSaliency.py b/megapixels/notebooks/utils/HaarSaliency.py new file mode 100644 index 00000000..6a511efb --- /dev/null +++ b/megapixels/notebooks/utils/HaarSaliency.py @@ -0,0 +1,77 @@ +import os +from os.path import join +import cv2 +import numpy as np +import xml.etree.ElementTree +class HaarSaliency: + + # Input images should be between 320x240 and 640x480 + classifiers = [] + face_matrix = [] + flags = 0 + nstages = 0 + + def __init__(self, cascade, min_size=60, max_size=400, + face_neighbors=3, sal_neighbors=0, blur_kernel=(31,31), scale_factor=1.1, stage_start=1): + + self.face_neighbors = face_neighbors + self.sal_neighbors = sal_neighbors + self.scale_factor = scale_factor + self.blur_kernel = blur_kernel + self.min_size = (min_size, min_size) + self.max_size = (max_size, max_size) + self.stage_start = stage_start + + cdir, cname = os.path.split(cascade) + cname, ext = os.path.splitext(cname) + + root = xml.etree.ElementTree.parse(cascade) + #width = int(root.find('./cascade/width').text.strip()) + #height = int(root.find('./cascade/height').text.strip()) + self.nstages = int(root.find('./cascade/stageNum').text.strip()) + + # initialize classifiers + cascades = [join(cdir,cname,str(c)+'.xml') for c in range(stage_start,self.nstages+1) ] + self.classifiers = [cv2.CascadeClassifier(c) for c in cascades] + + def get_saliency(self,src): + + # conver to grayscale + src_gray = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY) + + # run face detector on all stage-classifiers + self.face_matrix = [self.detect_faces(src_gray,c) for c in self.classifiers] + + # create saliency map in grayscale + w,h = src.shape[1],src.shape[0] + saliency = np.zeros((h,w), dtype=np.float32).reshape(h,w) + + # draw face-roi as stage-weighted grayscale vals + # min_neighbors sets max value for grayscale --> white + for i,face_list in enumerate(self.face_matrix,1): + inc = round(255./float(self.face_neighbors)/float(self.nstages-self.stage_start)) * i + if face_list is not None: + for x1,y1,fw,fh in face_list: + saliency[y1:y1+fh,x1:x1+fw] += inc + + # normalize, clip, and recast as uint8 + smax = saliency.max() + if smax > 255: + saliency /= (smax/255) + saliency = np.clip(saliency,0,255) + saliency = np.array(saliency,dtype=np.uint8) + + # blur, colormap, and composite + saliency = cv2.GaussianBlur(saliency,self.blur_kernel,0) + dst = cv2.applyColorMap(saliency, cv2.COLORMAP_JET) + return dst + + def detect_faces(self,src,classifier): + + matches = classifier.detectMultiScale(src, self.scale_factor, + self.sal_neighbors, self.flags, self.min_size, self.max_size) + + if matches is None or len(matches) < 1: + return None + else: + return sorted(map(tuple,matches),reverse=True) # lg --> sm
\ No newline at end of file diff --git a/megapixels/notebooks/utils/__init__.py b/megapixels/notebooks/utils/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/megapixels/notebooks/utils/__init__.py diff --git a/megapixels/notebooks/utils/imx.py b/megapixels/notebooks/utils/imx.py new file mode 100644 index 00000000..0dbdcf7e --- /dev/null +++ b/megapixels/notebooks/utils/imx.py @@ -0,0 +1,82 @@ +import os +from os.path import join +import cv2 + +from PIL import Image, ImageDraw +import matplotlib.pyplot as plt + + +def ensure_pil(im): + """Ensure image is Pillow format""" + try: + im.verify() + return im + except: + return Image.fromarray(im.astype('uint8'), 'RGB') + +def ensure_np(im): + """Ensure image is numpy array""" + if type(im) == np.ndarray: + return im + return np.asarray(im, np.uint8) + +def ensure_dir(d): + """Create directories""" + if not os.path.exists(d): + os.makedirs(d) + +def filter_pixellate(src,num_cells): + """Downsample, then upsample image for pixellation""" + w,h = src.size + dst = src.resize((num_cells,num_cells), Image.NEAREST) + dst = dst.resize((w,h), Image.NEAREST) + return dst + +# Plot images inline using Matplotlib +def pltimg(im,title=None,mode='rgb',figsize=(8,12),dpi=160,output=None): + plt.figure(figsize=figsize) + plt.xticks([]),plt.yticks([]) + if title is not None: + plt.title(title) + if mode.lower() == 'bgr': + im = cv2.cvtColor(im,cv2.COLOR_BGR2RGB) + f = plt.gcf() + plt.imshow(im) + plt.show() + plt.draw() + if output is not None: + bbox_inches='tight' + ext=osp.splitext(output)[1].replace('.','') + f.savefig(output,dpi=dpi,format=ext) + print('Image saved to: {}'.format(output)) + + +# Define a function to detect faces using OpenCV's haarcascades +def detect_faces(classifier,src,scale_factor=1.1,overlaps=3, + min_size=70, max_size=700, + flags=0): + + min_size = (min_size, min_size) # minimum face size + max_size = (max_size, max_size) # maximum face size + + # Convert to grayscale + src_gray = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY) + + # Run detector + matches = classifier.detectMultiScale(src_gray, + scale_factor, + overlaps, + flags, + min_size, + max_size) + # By default, this returns x,y,w,w + # Modify to return x1,y1,x2,y2 + matches = [ (r[0],r[1],r[0]+r[2],r[1]+r[3]) for r in matches] + + return matches + +def detect_faces_dlib(im,pyramids=0): + rects = detector(im, pyramids) + faces = [ (r.left(),r.top(),r.right(),r.bottom()) for r in rects] #x1,y1,x2,y2 + return faces +
\ No newline at end of file |
