summaryrefslogtreecommitdiff
path: root/megapixels/notebooks/utils
diff options
context:
space:
mode:
Diffstat (limited to 'megapixels/notebooks/utils')
-rw-r--r--megapixels/notebooks/utils/HaarSaliency.py77
-rw-r--r--megapixels/notebooks/utils/__init__.py0
-rw-r--r--megapixels/notebooks/utils/imx.py82
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