Exemplo n.º 1
0
class Model_FD:
    '''
    Class for the Face Detection Model.
    '''
    def __init__(self, model_name, device, extensions):

        self.plugin = None
        self.net = None
        self.input_blob = None
        self.output_blob = None
        self.exec_net = None
        self.infer_request = None
        self.input_shape = None
        self.output_shape = None
        self.input_name = None
        self.device = device
        self.extension = extensions
        self.model = model_name

    def load_model(self):
        '''
        This method is for loading the model to the device specified by the user.
        If your model requires any Plugins, this is where you can load them.
        '''
        model_xml = self.model + ".xml"
        model_weights = self.model + ".bin"

        self.plugin = IECore()
        self.net = IENetwork(model_xml, model_weights)

        self.exec_net = self.plugin.load_network(network=self.net,
                                                 device_name=self.device,
                                                 num_requests=1)

        if self.extension and 'CPU' in self.device:
            self.plugin.add_cpu_extension(self.extension)
        self.check_model()

        self.input_blob = next(iter(self.net.inputs))
        self.output_blob = next(iter(self.net.outputs))

        self.input_shape = self.net.inputs[self.input_blob].shape
        self.output_shape = self.net.outputs[self.output_blob].shape

    def predict(self, image, benchmark_timing):
        '''
        This method is meant for running predictions on the input image.
        '''
        global outputs
        self.exec_net.start_async(request_id=0,
                                  inputs={self.input_blob: image})

        if self.exec_net.requests[0].wait(-1) == 0:
            outputs = self.exec_net.requests[0].outputs[self.output_blob]

            if benchmark_timing:
                pp = PrettyPrinter(indent=4)
                print('Benchmark Timing for Face_Detection')
                pp.pprint(self.exec_net.requests[0].get_perf_counts())
                # Write get_perf_counts() data to a text file
                data = (self.exec_net.requests[0].get_perf_counts())
                self.write_benchmark('Benchmark Timing for Face_Detection',
                                     data)

        return outputs

    def check_model(self):

        supported_layers = self.plugin.query_network(network=self.net,
                                                     device_name=self.device)
        unsupported_layers = [
            l for l in self.net.layers.keys() if l not in supported_layers
        ]
        if len(unsupported_layers) != 0:
            log.error(
                "Unsupported layers found: {}".format(unsupported_layers))
            log.error(
                "Check whether extensions are available to add to IECore.")
            exit(1)

    def preprocess_input(self, image):
        '''
        Before feeding the data into the model for inference,
        you might have to preprocess it. This function is where you can do that.
        '''
        global pimage
        try:
            pimage = cv2.resize(image,
                                (self.input_shape[3], self.input_shape[2]),
                                interpolation=cv2.INTER_AREA)
            pimage = pimage.transpose((2, 0, 1))
            pimage = pimage.reshape(image, (1, *image.shape))
        except Exception as e:
            log.error(str(e))
        return pimage

    def preprocess_output(self, image, outputs, threshold, display):
        '''
        Before feeding the output of this model to the next model,
        you might have to preprocess the output. This function is where you can do that.
        '''
        global h, w
        try:
            h = image.shape[0]
            w = image.shape[1]
        except Exception as e:
            log.error(str(e))

        facebox = []
        # Drawing the box/boxes
        for obj in outputs[0][0]:
            if obj[2] > threshold:

                if obj[3] < 0:
                    obj[3] = -obj[3]
                if obj[4] < 0:
                    obj[4] = -obj[4]

                xmin = int(obj[3] * w)
                ymin = int(obj[4] * h)
                xmax = int(obj[5] * w)
                ymax = int(obj[6] * h)

                # Drawing the box in the image
                if display:
                    cv2.rectangle(image, (xmin, ymin), (xmax, ymax),
                                  (255, 0, 0), 1)
                facebox.append([xmin, ymin, xmax, ymax])

        return facebox

    def get_model_name(self):
        return self.model

    def write_benchmark(self, title, data):

        with open("FaceDetectione_benchmark_timing.txt", "a") as f:
            f.write(str(title) + "\n")
            f.write(str(data) + '\n')
            f.close()
Exemplo n.º 2
0
def main(args=None):
    try:
        # ------------------------------ 1. Parsing and validating input arguments -------------------------------------
        next_step()

        if not args:
            args = parse_args()

        # ------------------------------ 2. Loading Inference Engine ---------------------------------------------------
        next_step()

        device_name = args.target_device.upper()

        ie = IECore()

        if CPU_DEVICE_NAME in device_name:
            if args.path_to_extension:
                ie.add_cpu_extension(extension_path=args.path_to_extension,
                                     device_name=CPU_DEVICE_NAME)
        if GPU_DEVICE_NAME in device_name:
            if args.path_to_cldnn_config:
                ie.set_config({'CONFIG_FILE': args.path_to_cldnn_config},
                              GPU_DEVICE_NAME)
                logger.info("GPU extensions is loaded {}".format(
                    args.path_to_cldnn_config))

        logger.info("InferenceEngine:\n{: <9}{}".format("", get_version()))
        version_string = "Device is {}\n".format(device_name)
        for device, version in ie.get_versions(device_name).items():
            version_string += "{: <9}{}\n".format("", device)
            version_string += "{: <9}{:.<24}{} {}.{}\n".format(
                "", version.description, " version", version.major,
                version.minor)
            version_string += "{: <9}{:.<24} {}\n".format(
                "", "Build", version.build_number)
        logger.info(version_string)

        # --------------------- 3. Read the Intermediate Representation of the network ---------------------------------
        next_step()

        xml_filename = os.path.abspath(args.path_to_model)
        head, tail = os.path.splitext(xml_filename)
        bin_filename = os.path.abspath(head + BIN_EXTENSION)

        ie_network = IENetwork(xml_filename, bin_filename)

        input_info = ie_network.inputs

        if len(input_info) == 0:
            raise AttributeError('No inputs info is provided')

        # --------------------- 4. Resizing network to match image sizes and given batch -------------------------------
        next_step()

        batch_size = ie_network.batch_size
        precision = ie_network.precision

        if args.batch_size and args.batch_size != ie_network.batch_size:
            new_shapes = {}
            for key in input_info.keys():
                shape = input_info[key].shape
                layout = input_info[key].layout

                batchIndex = -1
                if ((layout == 'NCHW') or (layout == 'NCDHW')
                        or (layout == 'NHWC') or (layout == 'NDHWC')
                        or (layout == 'NC')):
                    batchIndex = 0
                elif (layout == 'CN'):
                    batchIndex = 1

                if ((batchIndex != -1)
                        and (shape[batchIndex] != args.batch_size)):
                    shape[batchIndex] = args.batch_size
                    new_shapes[key] = shape

            if (len(new_shapes) > 0):
                logger.info("Resizing network to batch = {}".format(
                    args.batch_size))
                ie_network.reshape(new_shapes)

            batch_size = args.batch_size

        logger.info("Network batch size: {}, precision {}".format(
            batch_size, precision))

        # --------------------- 5. Configuring input of the model ------------------------------------------------------
        next_step()

        for key in input_info.keys():
            if (isImage(input_info[key])):
                # Set the precision of input data provided by the user
                # Should be called before load of the network to the plugin
                input_info[key].precision = 'U8'

        # --------------------- 6. Setting device configuration --------------------------------------------------------
        next_step()

        devices = parseDevices(device_name)
        device_nstreams = parseValuePerDevice(devices, args.number_streams)
        for device in devices:
            if device == CPU_DEVICE_NAME:  ## CPU supports few special performance-oriented keys
                ## limit threading for CPU portion of inference
                if args.number_threads:
                    ie.set_config(
                        {'CPU_THREADS_NUM': str(args.number_threads)}, device)

                if MULTI_DEVICE_NAME in device_name and GPU_DEVICE_NAME in device_name:
                    ie.set_config({'CPU_BIND_THREAD': 'NO'}, CPU_DEVICE_NAME)
                else:
                    # pin threads for CPU portion of inference
                    ie.set_config(
                        {'CPU_BIND_THREAD': args.infer_threads_pinning},
                        device)

                ## for CPU execution, more throughput-oriented execution via streams
                # for pure CPU execution, more throughput-oriented execution via streams
                if args.api_type == 'async':
                    ie.set_config(
                        {
                            'CPU_THROUGHPUT_STREAMS':
                            str(device_nstreams.get(device))
                            if device in device_nstreams.keys() else
                            'CPU_THROUGHPUT_AUTO'
                        }, device)
                device_nstreams[device] = int(
                    ie.get_config(device, 'CPU_THROUGHPUT_STREAMS'))

            elif device == GPU_DEVICE_NAME:
                if args.api_type == 'async':
                    ie.set_config(
                        {
                            'GPU_THROUGHPUT_STREAMS':
                            str(device_nstreams.get(device))
                            if device in device_nstreams.keys() else
                            'GPU_THROUGHPUT_AUTO'
                        }, device)
                device_nstreams[device] = int(
                    ie.get_config(device, 'GPU_THROUGHPUT_STREAMS'))

                if MULTI_DEVICE_NAME in device_name and CPU_DEVICE_NAME in device_name:
                    ## multi-device execution with the CPU+GPU performs best with GPU trottling hint,
                    ## which releases another CPU thread (that is otherwise used by the GPU driver for active polling)
                    ie.set_config({'CLDNN_PLUGIN_THROTTLE': str(1)}, device)

            elif device == MYRIAD_DEVICE_NAME:
                ie.set_config(
                    {
                        'LOG_LEVEL': 'LOG_INFO',
                        'VPU_LOG_LEVEL': 'LOG_WARNING'
                    }, MYRIAD_DEVICE_NAME)

        # --------------------- 7. Loading the model to the device -----------------------------------------------------
        next_step()

        config = {'PERF_COUNT': ('YES' if args.perf_counts else 'NO')}

        exe_network = ie.load_network(ie_network,
                                      device_name,
                                      config=config,
                                      num_requests=args.number_infer_requests
                                      if args.number_infer_requests else 0)

        # --------------------- 8. Setting optimal runtime parameters --------------------------------------------------
        next_step()

        ## Number of requests
        infer_requests = exe_network.requests
        nireq = len(infer_requests)

        ## Iteration limit
        niter = args.number_iterations
        if niter and args.api_type == 'async':
            niter = (int)((niter + nireq - 1) / nireq) * nireq
            if (args.number_iterations != niter):
                logger.warn(
                    "Number of iterations was aligned by request number "
                    "from {} to {} using number of requests {}".format(
                        args.number_iterations, niter, nireq))

        ## Time limit
        duration_seconds = 0
        if args.time:
            ## time limit
            duration_seconds = args.time
        elif not args.number_iterations:
            ## default time limit
            duration_seconds = get_duration_in_secs(device)

        # ------------------------------------ 8. Creating infer requests and filling input blobs ----------------------
        next_step()

        request_queue = InferRequestsQueue(infer_requests)

        path_to_input = os.path.abspath(
            args.path_to_input) if args.path_to_input else None
        requests_input_data = getInputs(path_to_input, batch_size,
                                        ie_network.inputs, infer_requests)

        # ------------------------------------ 9. Measuring performance ------------------------------------------------

        progress_count = 0
        progress_bar_total_count = 10000

        output_string = "Start inference {}ronously".format(args.api_type)
        if (args.api_type == "async"):
            if output_string != "":
                output_string += ", "

            output_string += str(nireq) + " inference requests"
            device_ss = ''
            for device, nstreams in device_nstreams.items():
                if device_ss != '':
                    device_ss += ', '
                device_ss += "{} streams for {}".format(str(nstreams), device)
            if device_ss != '':
                output_string += " using " + device_ss

        output_string += ", limits: "
        if niter:
            if not duration_seconds:
                progress_bar_total_count = niter
            output_string += str(niter) + " iterations"

        if duration_seconds:
            if niter:
                output_string += ", "
            output_string += str(
                getDurationInMilliseconds(duration_seconds)) + " ms duration"

        next_step(output_string)

        ## warming up - out of scope
        infer_request = request_queue.getIdleRequest()
        if not infer_request:
            raise Exception("No idle Infer Requests!")

        if (args.api_type == 'sync'):
            infer_request.infer(requests_input_data[infer_request.id])
        else:
            infer_request.startAsync(requests_input_data[infer_request.id])

        request_queue.waitAll()
        request_queue.resetTimes()

        start_time = datetime.now()
        exec_time = (datetime.now() - start_time).total_seconds()
        iteration = 0

        progress_bar = ProgressBar(progress_bar_total_count,
                                   args.stream_output, args.progress)

        ## Start inference & calculate performance
        ## to align number if iterations to guarantee that last infer requests are executed in the same conditions **/
        while ((niter and iteration < niter)
               or (duration_seconds and exec_time < duration_seconds)
               or (args.api_type == "async" and iteration % nireq != 0)):
            infer_request = request_queue.getIdleRequest()
            if not infer_request:
                raise Exception("No idle Infer Requests!")

            if (args.api_type == 'sync'):
                infer_request.infer(requests_input_data[infer_request.id])
            else:
                infer_request.startAsync(requests_input_data[infer_request.id])
            iteration += 1

            exec_time = (datetime.now() - start_time).total_seconds()

            if niter:
                progress_bar.add_progress(1)
            else:
                ## calculate how many progress intervals are covered by current iteration.
                ## depends on the current iteration time and time of each progress interval.
                ## Previously covered progress intervals must be skipped.
                progress_interval_time = duration_seconds / progress_bar_total_count
                new_progress = (int)(exec_time / progress_interval_time -
                                     progress_count)
                progress_bar.add_progress(new_progress)
                progress_count += new_progress

        ## wait the latest inference executions
        request_queue.waitAll()

        total_duration_sec = request_queue.getDurationInSeconds()
        times = request_queue.times
        times.sort()
        latency_ms = median(times)
        fps = batch_size * 1000 / latency_ms if args.api_type == 'sync' else batch_size * iteration / total_duration_sec

        progress_bar.finish()

        # ------------------------------------ 10. Dumping statistics report -------------------------------------------
        next_step()

        if args.exec_graph_path:
            try:
                exec_graph_info = exe_network.get_exec_graph_info()
                exec_graph_info.serialize(args.exec_graph_path)
                logger.info("Executable graph is stored to {}".format(
                    args.exec_graph_path))
                del exec_graph_info
            except Exception as e:
                logging.exception(e)

        if args.perf_counts:
            for ni in range(int(nireq)):
                perf_counts = exe_network.requests[ni].get_perf_counts()
                logger.info(
                    "Pefrormance counts for {}-th infer request".format(ni))
                for layer, stats in perf_counts.items():
                    max_layer_name = 30
                    print("{:<30}{:<15}{:<30}{:<20}{:<20}{:<20}".format(
                        layer[:max_layer_name - 4] + '...' if
                        (len(layer) >= max_layer_name) else layer,
                        stats['status'],
                        'layerType: ' + str(stats['layer_type']),
                        'realTime: ' + str(stats['real_time']),
                        'cpu: ' + str(stats['cpu_time']),
                        'execType: ' + str(stats['exec_type'])))

        print("Count:      {} iterations".format(iteration))
        print("Duration:   {:.2f} ms".format(
            getDurationInMilliseconds(total_duration_sec)))
        if not MULTI_DEVICE_NAME in device_name:
            print("Latency:    {:.4f} ms".format(latency_ms))
        print("Throughput: {:.2f} FPS".format(fps))

        del exe_network
        del ie
        next_step.step_id = 0
    except Exception as e:
        logging.exception(e)
class Network:
    """
    Load and configure inference plugins for the specified target devices
    and performs synchronous and asynchronous modes for the specified infer requests.
    """
    def __init__(self):
        """
        Initialize any class variables desired

        """
        self.net = None
        self.plugin = None
        self.input_blob = None
        self.out_blob = None
        self.net_plugin = None
        self.infer_request_handle = None

    def load_model(self,
                   model,
                   device,
                   input_size,
                   output_size,
                   num_requests,
                   cpu_extension=None,
                   plugin=None):
        """
         Loads a network and an image to the Inference Engine plugin.
        :param model: .xml file of pre trained model
        :param cpu_extension: extension for the CPU device
        :param device: Target device
        :param input_size: Number of input layers
        :param output_size: Number of output layers
        :param num_requests: Index of Infer request value. Limited to device capabilities.
        :param plugin: Plugin for specified device
        :return:  Shape of input layer
        """

        model_xml = model
        model_bin = os.path.splitext(model_xml)[0] + ".bin"
        # Plugin initialization for specified device
        # and load extensions library if specified
        if not plugin:
            log.info("Initializing plugin for {} device...".format(device))
            self.plugin = IEPlugin(device=device)
        else:
            self.plugin = plugin

        if cpu_extension and 'CPU' in device:
            self.plugin.add_cpu_extension(cpu_extension)

        # Read IR
        log.info("Reading IR...")
        self.net = IENetwork(model=model_xml, weights=model_bin)
        log.info("Loading IR to the plugin...")

        if self.plugin.device == "CPU":
            supported_layers = self.plugin.get_supported_layers(self.net)
            not_supported_layers = \
                [l for l in self.net.layers.keys() if l not in supported_layers]
            if len(not_supported_layers) != 0:
                log.error("Following layers are not supported by "
                          "the plugin for specified device {}:\n {}".format(
                              self.plugin.device,
                              ', '.join(not_supported_layers)))
                log.error("Please try to specify cpu extensions library path"
                          " in command line parameters using -l "
                          "or --cpu_extension command line argument")
                sys.exit(1)

        if num_requests == 0:
            # Loads network read from IR to the plugin
            self.net_plugin = self.plugin.load(network=self.net)
        else:
            self.net_plugin = self.plugin.load(network=self.net,
                                               num_requests=num_requests)

        self.input_blob = next(iter(self.net.inputs))
        self.out_blob = next(iter(self.net.outputs))
        assert len(self.net.inputs.keys()) == input_size, \
            "Supports only {} input topologies".format(len(self.net.inputs))
        assert len(self.net.outputs) == output_size, \
            "Supports only {} output topologies".format(len(self.net.outputs))

        return self.plugin, self.get_input_shape()

    def load_model_2(self,
                     model,
                     device,
                     input_size,
                     output_size,
                     num_requests,
                     cpu_extension=None,
                     plugin=None):
        """
            Load the model
            Check for supported layers
            Add any necessary extensions
            Return the loaded inference plugin
        """

        model_xml = model
        model_bin = os.path.splitext(model_xml)[0] + ".bin"

        # Plugin initialization for specified device
        # and load extensions library if specified

        if not plugin:
            log.info("Initializing plugin for {} device...".format(device))
            self.plugin = IECore()
        else:
            self.plugin = plugin

        if cpu_extension and 'CPU' in device:
            self.plugin.add_extension(cpu_extension, "CPU")

        # Read IR
        log.info("Reading IR...")

        self.net = IECore.load_network(model=model_xml, weights=model_bin)
        log.info("Loading IR to the plugin...")

        if "CPU" in device:
            supported_layers = self.plugin.query_network(self.net, "CPU")
            not_supported_layers = \
                [l for l in self.net.layers.keys() if l not in supported_layers]
            if len(not_supported_layers) != 0:
                log.error("Following layers are not supported by "
                          "the plugin for specified device {}:\n {}".format(
                              device, ', '.join(not_supported_layers)))
                log.error("Please try to specify cpu extensions library path"
                          " in command line parameters using -l "
                          "or --cpu_extension command line argument")
                sys.exit(1)

        if num_requests == 0:
            # Loads network read from IR to the plugin
            self.net_plugin = self.plugin.load_network(network=self.net,
                                                       device_name=device)
        else:
            self.net_plugin = self.plugin.load_network(
                network=self.net,
                num_requests=num_requests,
                device_name=device)

        self.input_blob = next(iter(self.net.inputs))
        self.out_blob = next(iter(self.net.outputs))
        assert len(self.net.inputs.keys()) == input_size, \
            "Supports only {} input topologies".format(len(self.net.inputs))
        assert len(self.net.outputs) == output_size, \
            "Supports only {} output topologies".format(len(self.net.outputs))

        return self.plugin, self.get_input_shape()

    def get_input_shape(self):
        """
        Return the shape of the input layer

        """
        return self.net.inputs[self.input_blob].shape

    def exec_net(self, request_id, frame):
        """
        Start an asynchronous request
        Return any necessary information
        Note: You may need to update the function parameters.
        """
        self.infer_request_handle = self.net_plugin.start_async(
            request_id=request_id, inputs={self.input_blob: frame})
        return self.net_plugin

    def wait(self, request_id):
        """
            Wait for the request to be complete.
            Return any necessary information
            Note: You may need to update the function parameters.
        """
        request_waiting = self.net_plugin.requests[request_id].wait(-1)
        return request_waiting

    def get_output(self, request_id, output=None):
        """
           Extract and return the output results
           Note: You may need to update the function parameters.
       """
        if output:
            return self.infer_request_handle.outputs[output]
        else:
            return self.net_plugin.requests[request_id].outputs[self.out_blob]
Exemplo n.º 4
0
class Network:
    """
    Load and configure inference plugins for the specified target devices 
    and performs synchronous and asynchronous modes for the specified infer requests.
    """
    def __init__(self):
        ### TODO: Initialize any class variables desired ###
        self.net = None
        self.plugin = None
        self.input_blob = None
        self.output_blob = None
        self.net_plugin = None
        self.infer_request = None

    def load_model(self,
                   model,
                   device,
                   num_requests,
                   cpu_extension=None,
                   plugin=None):
        ### TODO: Load the model ###
        load_model_xml = model
        load_model_bin = os.path.splitext(load_model_xml)[0] + ".bin"

        while not plugin:
            log.info("Please wait. Starting plugin for {} device... ".format(
                device))
            self.plugin = IECore()

        else:
            self.plugin = plugin

        if cpu_extension and CPU in device:
            self.plugin.add_cpu_extension(cpu_extension)

        log.info('Reading IR, Please wait.')
        self.net = IENetwork(model=load_model_xml, weights=load_model_bin)
        log.info(
            'Completed. Loading IR to the plugin. This may take some time')
        ### TODO: Check for supported layers ###
        if self.plugin.device == "CPU":
            supported_layers = self.plugin.get_supported_layers(self.net)
            unsupported_layers = [
                l for l in self.net.layers.key() if l not in supported_layers
            ]

            if len(unsupported_layers) != 0:
                log.error(
                    'There are a number of unsupported layers found: '.format(
                        unsupported_layers))
                sys.exit(1)

        if num_request == 0:
            self.net_plugin = self.plugin.load(network=self.net)

        else:
            self.net_plugin = self.plugin.load(network=self.net,
                                               num_requests=num_requests)

        self.input_blob = next(iter(self.net.input))
        self.output_blob = next(iter(self.net.output))

        if len(self.net.inputs.key()) == input_size:
            log.error(
                'Sorry, this app supports {} input topologies. Please make the necessary changes and try again'
                .format(len(self.net.inputs)))
            sys.exit(1)

        if len(self.net.outputs) == output_size:
            log.error(
                'Sorry, this app supports {} output topologies. Please make the necessary changes and try again'
                .format(len(self.net.inputs)))
            sys.exit(1)

        return self.plugin, self.get_input_shape

        ### TODO: Add any necessary extensions ###
        ### TODO: Return the loaded inference plugin ###
        ### Note: You may need to update the function parameters. ###
        return

    def get_input_shape(self):
        ### TODO: Return the shape of the input layer ###
        return self.net.inputs[self.input.blob].shape

    def exec_net(self, request_id, frame):
        ### TODO: Start an asynchronous request ###
        ### TODO: Return any necessary information ###
        ### Note: You may need to update the function parameters. ###
        self.infer_request = self.net_plugin.start_async(
            request_id=request_id, inputs={self.input_blob: frame})

        return self.net_plugin

    def wait(self, request_id):
        ### TODO: Wait for the request to be complete. ###
        ### TODO: Return any necessary information ###
        ### Note: You may need to update the function parameters. ###

        wait_status = self.net_plugin.requests[request_id].wait(-1)

        return wait_status

    def get_output(self):
        ### TODO: Extract and return the output results
        ### Note: You may need to update the function parameters. ###

        if output:
            result = self.infer_request.outputs[output]

        else:
            result = self.net_plugin.requests[request_id].outputs[
                self.output_blob]

        return result

    def delete_instances(self):
        del self.net_plugin
        del self_plugin
        del self.net
Exemplo n.º 5
0
class Model_FLD:
    '''
    Class for the Face Landmarks Detection Model.
    '''
    def __init__(self, model_name, device, extensions):

        self.plugin = None
        self.net = None
        self.input_blob = None
        self.output_blob = None
        self.exec_net = None
        self.infer_request = None
        self.input_shape = None
        self.output_shape = None
        self.device = device
        self.extension = extensions
        self.model = model_name
        self.outputs = None
        self.eyes_coords_dict = None

    def load_model(self):
        '''
        This method is for loading the model to the device specified by the user.
        If your model requires any Plugins, this is where you can load them.
        '''
        model_xml = self.model + ".xml"
        model_weights = self.model + ".bin"

        self.plugin = IECore()
        self.net = IENetwork(model_xml, model_weights)

        self.exec_net = self.plugin.load_network(network=self.net,
                                                 device_name=self.device,
                                                 num_requests=1)

        if self.extension and 'CPU' in self.device:
            self.plugin.add_cpu_extension(self.extension)
        self.check_model()

        self.input_blob = next(iter(self.net.inputs))
        self.output_blob = next(iter(self.net.outputs))

        self.input_shape = self.net.inputs[self.input_blob].shape
        self.output_shape = self.net.outputs[self.output_blob].shape

    def predict(self, image, benchmark_timing):
        '''
        This method is meant for running predictions on the input image.
        '''

        self.exec_net.start_async(request_id=0,
                                  inputs={self.input_blob: image})
        if self.exec_net.requests[0].wait(-1) == 0:
            self.outputs = self.exec_net.requests[0].outputs[self.output_blob]

            if benchmark_timing:
                pp = PrettyPrinter(indent=4)
                print('Benchmark Timing for Facial_Landmark_Detection')
                pp.pprint(self.exec_net.requests[0].get_perf_counts())
                # Write get_perf_counts() data to a text file
                data = (self.exec_net.requests[0].get_perf_counts())
                self.write_benchmark(
                    'Benchmark Timing for Facial_Landmark_Detection', data)

        return self.outputs

    def check_model(self):
        supported_layers = self.plugin.query_network(network=self.net,
                                                     device_name=self.device)
        unsupported_layers = [
            l for l in self.net.layers.keys() if l not in supported_layers
        ]
        if len(unsupported_layers) != 0:
            log.error('Unsupported layers found:{}'.format(unsupported_layers))
            log.error(
                'Check for any extensions for these unsupported layers available for adding to IECore'
            )
            exit(1)

    def preprocess_input(self, image):
        '''
        Before feeding the data into the model for inference,
        you might have to preprocess it. This function is where you can do that.
        '''
        global pimage
        try:
            pimage = cv2.resize(image,
                                (self.input_shape[3], self.input_shape[2]))
            pimage = pimage.transpose((2, 0, 1))
            pimage = pimage.reshape(pimage, (1, *pimage.shape))
        except Exception as e:
            log.error(str(e))

        return pimage

    def preprocess_output(self, image, outputs, facebox, display):
        '''
        Before feeding the output of this model to the next model,
        you might have to preprocess the output. This function is where you can do that.

        The net outputs a blob with the shape: [1, 10], containing a row-vector of 10 floating point values
        for five landmarks coordinates in the form (x0, y0, x1, y1, ..., x5, y5).
         All the coordinates are normalized to be in range [0,1]
        '''
        """
        # Output layer names in Inference Engine format:
        # landmarks-regression-retail-0009:
        #   "95", [1, 10, 1, 1], containing a row-vector of 10 floating point values for five landmarks
        #         coordinates in the form (x0, y0, x1, y1, ..., x5, y5).
        #         All the coordinates are normalized to be in range [0,1]
        """

        normed_landmarks = outputs.reshape(1, 10)[0]

        height = facebox[3] - facebox[1]
        width = facebox[2] - facebox[0]

        if display:
            # Drawing the box/boxes
            for i in range(2):
                x = int(normed_landmarks[i * 2] * width)
                y = int(normed_landmarks[i * 2 + 1] * height)
                cv2.circle(image, (facebox[0] + x, facebox[1] + y), 30,
                           (0, 255, i * 255), 1)

        left_eye_point = [
            normed_landmarks[0] * width, normed_landmarks[1] * height
        ]
        right_eye_point = [
            normed_landmarks[2] * width, normed_landmarks[3] * height
        ]

        return left_eye_point, right_eye_point

    def get_model_name(self):
        return self.model

    def write_benchmark(self, title, data):

        with open("FacialLandmarks_benchmark_timing.txt", "a") as f:
            f.write(str(title) + "\n")
            f.write(str(data) + '\n')
            f.close()
Exemplo n.º 6
0
class Model_GE:
    '''
    Class for the gaze estimation Model.
    '''

    def __init__(self, model_name, device, extensions):
        self.plugin = None
        self.net = None
        self.exec_net = None
        self.infer_request = None
        self.output_shape = None
        self.device = device
        self.extension = extensions
        self.outputs = None
        self.head_pose_angles = None
        self.left_eye_image = None
        self.right_eye_image = None
        self.model = model_name
        self.head_pose_angles_shape = None
        self.left_eye_shape = None
        self.right_eye_shape = None

    def load_model(self,device):
        '''
        This method is for loading the model to the device specified by the user.
        If your model requires any Plugins, this is where you can load them.
        '''
        model_xml = self.model + ".xml"
        model_weights = self.model + ".bin"

        self.plugin = IECore()
        self.net = IENetwork(model_xml, model_weights)

        self.exec_net = self.plugin.load_network(network=self.net, device_name=device, num_requests=1)

        if self.extension and 'CPU' in self.device:
            self.plugin.add_cpu_extension(self.extension)
        self.check_model()

        self.input_blob = next(iter(self.net.inputs))
        self.input_blob2 = next(iter(self.net.inputs))

        self.input_shape = self.net.inputs[self.input_blob].shape
        self.output_blob = next(iter(self.net.outputs))
        self.output_shape = self.net.outputs[self.output_blob].shape

    def predict(self, processed_left_eye, processed_right_eye, head_position, benchmark_timing):

        input_dict = {'left_eye_image': processed_left_eye,
                      'right_eye_image': processed_right_eye,
                      'head_pose_angles': head_position}

        infer_request_handle = self.exec_net.start_async(request_id=0, inputs=input_dict)

        infer_status = infer_request_handle.wait()
        if infer_status == 0:
            self.outputs = self.exec_net.requests[0].outputs[self.output_blob][0]

            if benchmark_timing:
                pp = PrettyPrinter(indent=4)
                print('Benchmark Timing for Gaze_detection')
                pp.pprint(self.exec_net.requests[0].get_perf_counts())
                # Write get_perf_counts() data to a text file
                data = pp.pprint(self.exec_net.requests[0].get_perf_counts())
                self.write_benchmark('Benchmark Timing for Gaze_Estimation', data)

        return self.outputs

    def check_model(self):
        supported_layers = self.plugin.query_network(network=self.net, device_name=self.device)
        unsupported_layers = [l for l in self.net.layers.keys() if l not in supported_layers]
        if len(unsupported_layers) != 0:
            log.error('Unsupported layers found:{}'.format(unsupported_layers))
            log.error('Check for any extensions for these unsupported layers available for adding to IECore')
            exit(1)

    def eye_corp(self, face, eyepoint):

        Eye_shape = [1, 3, 60, 60]

        # cropping the eye
        x_center = eyepoint[0]
        y_center = eyepoint[1]
        width = Eye_shape[3]
        height = Eye_shape[2]

        # ymin:ymax, xmin:xmax
        face_width = face.shape[0]
        face_height = face.shape[1]

        face_array = np.array(face)

        ymin = int(y_center - height // 2) if int(y_center - height // 2) >= 0 else 0
        ymax = int(y_center + height // 2) if int(y_center + height // 2) <= face_height else face_height

        xmin = int(x_center - width // 2) if int(x_center - width // 2) >= 0 else 0
        xmax = int(x_center + width // 2) if int(x_center + width // 2) <= face_width else face_width

        eye_image = face_array[ymin:ymax, xmin:xmax]

        return eye_image

    def resize_frame(self, frame):

        global p_frame
        try:

            p_frame = cv2.resize(frame, (60, 60))
            p_frame = p_frame.transpose((2, 0, 1))
            p_frame = p_frame.reshape(1, *p_frame.shape)

        except Exception as e:
            log.error(str(e))

        return p_frame

    def preprocess_input(self, face, left_eye_point, right_eye_point):
        '''
        Before feeding the data into the model for inference,
        you might have to preprocess it. This function is where you can do that.
       Blob in the format [BxCxHxW] where:
        B - batch size
        C - number of channels
        H - image height
        W - image width
        with the name left_eye_image and the shape [1x3x60x60].
        Blob in the format [BxCxHxW] where:
        B - batch size
        C - number of channels
        H - image height
        W - image width
        with the name right_eye_image and the shape [1x3x60x60].
        Blob in the format [BxC] where:
        B - batch size
        C - number of channels
        with the name head_pose_angles and the shape [1x3].
        '''

        left_eye_image = self.eye_corp(face, left_eye_point)
        right_eye_image = self.eye_corp(face, right_eye_point)

        # eye shape [1x3x60x60]
        p_frame_left = self.resize_frame(left_eye_image)
        p_frame_right = self.resize_frame(right_eye_image)

        return p_frame_left, p_frame_right

    def preprocess_output(self, outputs, image, face, facebox, left_eye_point, right_eye_point, display):
        '''
        Before feeding the output of this model to the next model,
        you might have to preprocess the output. This function is where you can do that.
        '''
        output = np.squeeze(outputs)
        x = output[0]
        y = output[1]
        z = output[2]

        # left eye
        xmin, ymin, _, _ = facebox
        l_x_center = left_eye_point[0]
        l_y_center = left_eye_point[1]
        left_eye_center_x = int(xmin + l_x_center)
        left_eye_center_y = int(ymin + l_y_center)

        # right eye
        r_x_center = right_eye_point[0]
        r_y_center = right_eye_point[1]
        right_eye_center_x = int(xmin + r_x_center)
        right_eye_center_y = int(ymin + r_y_center)

        if display:
            cv2.arrowedLine(image, (left_eye_center_x, left_eye_center_y),
                            (left_eye_center_x + int(x * 100), left_eye_center_y + int(-y * 100)),
                            (255, 0, 0), 3)
            cv2.arrowedLine(image, (right_eye_center_x, right_eye_center_y),
                            (right_eye_center_x + int(x * 100), right_eye_center_y + int(-y * 100)),
                            (0, 255, 0), 3)

        return [x, y, z]

    def get_model_name(self):
        return self.model

    def write_benchmark(self, title, data):

        with open("Gaze_benchmark_timing.txt", "a") as f:
            f.write(str(title) + "\n")
            f.write(str(data) + '\n')
            f.close()
Exemplo n.º 7
0
class Model_HPE:
    '''
    Class for the Head Pose Estimation Model.
    '''

    def __init__(self, model_name, device, extensions):

        self.plugin = None
        self.net = None
        self.input_blob = None
        self.output_blob = None
        self.exec_net = None
        self.infer_request = None
        self.input_shape = None
        self.output_shape = None
        self.input_name = None
        self.device = device
        self.extension = extensions
        self.model = model_name
        self.output = None

    def load_model(self):
        '''
        This method is for loading the model to the device specified by the user.
        If your model requires any Plugins, this is where you can load them.
        '''
        model_xml = self.model + ".xml"
        model_weights = self.model + ".bin"

        self.plugin = IECore()
        self.net = IENetwork(model_xml, model_weights)

        self.exec_net = self.plugin.load_network(network=self.net, device_name=self.device,
                                                 num_requests=1)

        if self.extension and 'CPU' in self.device:
            self.plugin.add_cpu_extension(self.extension)
        self.check_model()

        self.input_blob = next(iter(self.net.inputs))
        self.input_shape = self.net.inputs[self.input_blob].shape
        self.output_blob = next(iter(self.net.outputs))
        self.output_shape = self.net.outputs[self.output_blob].shape

    def predict(self, image, benchmark_timing):
        self.exec_net.start_async(request_id=0, inputs={self.input_blob: image})
        if self.exec_net.requests[0].wait(-1) == 0:
            self.result = self.exec_net.requests[0].outputs

            if benchmark_timing:
                pp = PrettyPrinter(indent=4)
                print('Benchmark Timing for Head_Pose_Estimation')
                pp.pprint(self.exec_net.requests[0].get_perf_counts())
                # Write get_perf_counts() data to a text file
                data = (self.exec_net.requests[0].get_perf_counts())
                self.write_benchmark('Benchmark Timing for Head_Pose_Estimation', data)

        return self.result

    def check_model(self):
        supported_layers = self.plugin.query_network(network=self.net, device_name=self.device)
        unsupported_layers = [l for l in self.net.layers.keys() if l not in supported_layers]
        if len(unsupported_layers) != 0:
            log.error("Unsupported layers found: {}".format(unsupported_layers))
            log.error("Check whether extensions are available to add to IECore.")
            exit(1)

    def preprocess_input(self, image):

        temp = image.copy()
        temp = cv2.resize(temp, (self.input_shape[3], self.input_shape[2]))  # n,c,h,w
        temp = temp.transpose((2, 0, 1))
        temp = temp.reshape(1, *temp.shape)
        return temp

    def preprocess_output(self, image, outputs, facebox, face, display):

        output = []
        output.append(outputs['angle_y_fc'].tolist()[0][0])
        output.append(outputs['angle_p_fc'].tolist()[0][0])
        output.append(outputs['angle_r_fc'].tolist()[0][0])

        pitch = np.squeeze(outputs['angle_p_fc'])
        roll = np.squeeze(outputs['angle_r_fc'])
        yaw = np.squeeze(outputs['angle_y_fc'])
        axes_op = np.array([pitch, roll, yaw])

        if display:
            xmin, ymin, _, _ = facebox
            face_center = (xmin + face.shape[1] / 2, ymin + face.shape[0] / 2, 0)
            self.draw_axes(image, face_center, yaw, pitch, roll)

        return axes_op

    # code source: https://knowledge.udacity.com/questions/171017
    def draw_axes(self, frame, center_of_face, yaw, pitch, roll):
        focal_length = 950.0
        scale = 100

        yaw *= np.pi / 180.0
        pitch *= np.pi / 180.0
        roll *= np.pi / 180.0
        cx = int(center_of_face[0])
        cy = int(center_of_face[1])
        Rx = np.array([[1, 0, 0],
                       [0, math.cos(pitch), -math.sin(pitch)],
                       [0, math.sin(pitch), math.cos(pitch)]])
        Ry = np.array([[math.cos(yaw), 0, -math.sin(yaw)],
                       [0, 1, 0],
                       [math.sin(yaw), 0, math.cos(yaw)]])
        Rz = np.array([[math.cos(roll), -math.sin(roll), 0],
                       [math.sin(roll), math.cos(roll), 0],
                       [0, 0, 1]])
        # ref: https://www.learnopencv.com/rotation-matrix-to-euler-angles/
        R = Rz @ Ry @ Rx
        camera_matrix = self.build_camera_matrix(center_of_face, focal_length)
        xaxis = np.array(([1 * scale, 0, 0]), dtype='float32').reshape(3, 1)
        yaxis = np.array(([0, -1 * scale, 0]), dtype='float32').reshape(3, 1)
        zaxis = np.array(([0, 0, -1 * scale]), dtype='float32').reshape(3, 1)
        zaxis1 = np.array(([0, 0, 1 * scale]), dtype='float32').reshape(3, 1)
        o = np.array(([0, 0, 0]), dtype='float32').reshape(3, 1)
        o[2] = camera_matrix[0][0]
        xaxis = np.dot(R, xaxis) + o
        yaxis = np.dot(R, yaxis) + o
        zaxis = np.dot(R, zaxis) + o
        zaxis1 = np.dot(R, zaxis1) + o
        xp2 = (xaxis[0] / xaxis[2] * camera_matrix[0][0]) + cx
        yp2 = (xaxis[1] / xaxis[2] * camera_matrix[1][1]) + cy
        p2 = (int(xp2), int(yp2))
        cv2.line(frame, (cx, cy), p2, (0, 0, 255), 2)
        xp2 = (yaxis[0] / yaxis[2] * camera_matrix[0][0]) + cx
        yp2 = (yaxis[1] / yaxis[2] * camera_matrix[1][1]) + cy
        p2 = (int(xp2), int(yp2))
        cv2.line(frame, (cx, cy), p2, (0, 255, 0), 2)
        xp1 = (zaxis1[0] / zaxis1[2] * camera_matrix[0][0]) + cx
        yp1 = (zaxis1[1] / zaxis1[2] * camera_matrix[1][1]) + cy
        p1 = (int(xp1), int(yp1))
        xp2 = (zaxis[0] / zaxis[2] * camera_matrix[0][0]) + cx
        yp2 = (zaxis[1] / zaxis[2] * camera_matrix[1][1]) + cy
        p2 = (int(xp2), int(yp2))
        cv2.line(frame, p1, p2, (255, 0, 0), 2)
        cv2.circle(frame, p2, 3, (255, 0, 0), 2)
        return frame

    def build_camera_matrix(self, center_of_face, focal_length):
        cx = int(center_of_face[0])
        cy = int(center_of_face[1])
        camera_matrix = np.zeros((3, 3), dtype='float32')
        camera_matrix[0][0] = focal_length
        camera_matrix[0][2] = cx
        camera_matrix[1][1] = focal_length
        camera_matrix[1][2] = cy
        camera_matrix[2][2] = 1
        return camera_matrix

    def get_model_name(self):
        return self.model

    def write_benchmark(self, title, data):

        with open("headpose_benchmark_timing.txt", "a") as f:
            f.write(str(title) + "\n")
            f.write(str(data) + '\n')
            f.close()