Source code for pliers.extractors.image

'''
Extractors that operate primarily or exclusively on Image stimuli.
'''

from functools import partial

import numpy as np
import pandas as pd

from pliers.stimuli.image import ImageStim
from pliers.extractors.base import Extractor, ExtractorResult
from pliers.utils import attempt_to_import, verify_dependencies, listify
from pliers.support.due import due, Url, Doi

cv2 = attempt_to_import('cv2')
face_recognition = attempt_to_import('face_recognition')


class ImageExtractor(Extractor):

    ''' Base Image Extractor class; all subclasses can only be applied to
    images. '''
    _input_type = ImageStim


[docs]class BrightnessExtractor(ImageExtractor): ''' Gets the average luminosity of the pixels in the image ''' VERSION = '1.0' def _extract(self, stim): data = stim.data brightness = np.amax(data, 2).mean() / 255.0 return ExtractorResult(np.array([[brightness]]), stim, self, features=['brightness'])
[docs]class SharpnessExtractor(ImageExtractor): ''' Gets the degree of blur/sharpness of the image ''' VERSION = '1.0' def _extract(self, stim): verify_dependencies(['cv2']) # Taken from # http://stackoverflow.com/questions/7765810/is-there-a-way-to-detect-if-an-image-is-blurry?lq=1 data = stim.data gray_image = cv2.cvtColor(data, cv2.COLOR_BGR2GRAY) sharpness = np.max( cv2.convertScaleAbs(cv2.Laplacian(gray_image, 3))) / 255.0 return ExtractorResult(np.array([[sharpness]]), stim, self, features=['sharpness'])
[docs]class VibranceExtractor(ImageExtractor): ''' Gets the variance of color channels of the image ''' VERSION = '1.0' def _extract(self, stim): data = stim.data vibrance = np.var(data, 2).mean() return ExtractorResult(np.array([[vibrance]]), stim, self, features=['vibrance'])
[docs]class SaliencyExtractor(ImageExtractor): ''' Determines the saliency of the image using Itti & Koch (1998) algorithm implemented in pySaliencyMap ''' @due.dcite(Doi("10.1109/34.730558"), description="Image saliency estimation", path='pliers.extractors.image.SilencyExtractor', tags=["implementation"]) def _extract(self, stim): from pliers.external.pysaliency import pySaliencyMap # pySaliencyMap from https://github.com/akisato-/pySaliencyMap # Initialize variables h, w, c = stim.data.shape sm = pySaliencyMap.pySaliencyMap(h, w) # Compute saliency maps and store full maps as derivatives stim.derivatives = dict() stim.derivatives['saliency_map'] = sm.SMGetSM(stim.data) stim.derivatives['binarized_map'] = sm.SMGetBinarizedSM( stim.data) # thresholding done using Otsu # Compute summary statistics output = {} output['max_saliency'] = np.max(stim.derivatives['saliency_map']) output['max_y'], output['max_x'] = [list(i)[0] for i in np.where( stim.derivatives['saliency_map'] == output['max_saliency'])] output['frac_high_saliency'] = np.sum( stim.derivatives['binarized_map']/255.0)/(h * w) return ExtractorResult(np.array([list(output.values())]), stim, self, features=list(output.keys()))
class FaceRecognitionFeatureExtractor(ImageExtractor): _log_attributes = ('face_recognition_kwargs',) def __init__(self, **face_recognition_kwargs): verify_dependencies(['face_recognition']) self.face_recognition_kwargs = face_recognition_kwargs func = getattr(face_recognition.api, self._feature) self.func = partial(func, **face_recognition_kwargs) super().__init__() def get_feature_names(self): return self._feature def _extract(self, stim): values = self.func(stim.data) feature_names = listify(self.get_feature_names()) return ExtractorResult(values, stim, self, features=feature_names) def _to_df(self, result): cols = listify(self._feature) return pd.DataFrame([[r] for r in result._data], columns=cols)
[docs]class FaceRecognitionFaceEncodingsExtractor(FaceRecognitionFeatureExtractor): ''' Uses the face_recognition package to extract a 128-dimensional encoding for every face detected in an image. For details, see documentation for face_recognition.api.face_encodings. ''' _feature = 'face_encodings'
[docs]class FaceRecognitionFaceLandmarksExtractor(FaceRecognitionFeatureExtractor): ''' Uses the face_recognition package to extract the locations of named features of faces in the image. For details, see documentation for face_recognition.api.face_landmarks.''' _feature = 'face_landmarks' def _to_df(self, result): data = pd.DataFrame.from_records(result._data) data.columns = ['{}_{}'.format(self._feature, c) for c in data.columns] return data
[docs]class FaceRecognitionFaceLocationsExtractor(FaceRecognitionFeatureExtractor): ''' Uses the face_recognition package to extract bounding boxes for all faces in an image. For details, see documentation for face_recognition.api.face_locations. ''' _feature = 'face_locations'