Yearly Archives: 2016


Hugin 1

Hugin is a cross-platform open source panorama photo stitching and HDR merging program developed by Pablo d’Angelo and others. It is a GUI front-end for Helmut Dersch’s Panorama Tools and Andrew Mihal’s Enblend and Enfuse. Stitching is accomplished by using several overlapping photos taken from the same location, and using control points to align and transform the photos so that they can be blended together to form a larger image. Hugin allows for the easy (optionally automatic) creation of control points between two images, optimization of the image transforms along with a preview window so the user can see whether the panorama is acceptable. Once the preview is correct, the panorama can be fully stitched, transformed and saved in a standard image format.

— From Wikipedia: https://en.wikipedia.org/wiki/Hugin_(software)

We have a set of images, which if stitched together they can produce a panorama. We wanted to create a panoramic ‘artwork’ using Prisma (because we like their work).
Unfortunately, a current limitation of Prisma, is that it will only produce square images of maximum size 1080px, so we could not supply it with a panorama an expect it to create the panoramic ‘artwork’.

To achieve our goal, we converted our images to ‘art’ using Prisma and we supplied the result to Hugin to create the panoramic ‘artwork’.
By using the simple wizard of Hugin we were able to create these lovely images presented in this post.

Note: Since the images we loaded into Hugin were processed by Prisma, they lost all their EXIF information.
Because of the missing EXIF information, Hugin could not know the focal length of the camera so we had to supply it manually.
In our case, for Galaxy S4 it was 35mm. After supplying this information everything went smoothly as you can see in the results.

We created two sets of images, one using the Mosaic filter (above) and another using the Dallas filter (below).

Useful links:

Advertisements

asn1c: Full working example of ASN.1 in C/C++

The following project demonstrates a full working example of encoding and decoding ASN.1 structures using the asn1c compiler of http://lionet.info/asn1c/

In this project we assumed that we have to encode a set of geometric elements, including:

  • A rectangle that is composed by its height and its width
  • A rectangular cuboid that it is composed by a rectangle and a depth parameter
  • A list of rectangular cuboids that has no limit on how many elements to add to it
  • A list of rectangular cuboids that must have at least one element and at most three
  • We assume that all parameters should be positive integer values

ASN.1 C Full Example (compressed) (1240 downloads)

Following is our ASN.1 syntax to describe the above elements:

Geometry.asn1

GeometryModule DEFINITIONS ::= BEGIN

Rectangle ::= SEQUENCE {
    height INTEGER (0..MAX),
    width INTEGER (0..MAX)
}

RectangularCuboid ::= SEQUENCE {
    depth INTEGER (0..MAX),
    rectangle Rectangle
}

UnlimitedRectangularCuboids ::= SEQUENCE OF RectangularCuboid

LimitedRectangularCuboids ::= SEQUENCE SIZE(1..3) OF RectangularCuboid

END

Inside the directory where our source is located, we created folder called geometryASN.
From that folder we executed the following command to generate the c code that is needed for our C/C++ source code to operate:

asn1c -fcompound-names -gen-PER ../Geometry.asn1

Following is our C source code that creates new ANS.1 elements, encodes them, decodes them and verifies that all limitations and constraints were met.

ASN.1 C Full Example (compressed) (1240 downloads)

main.cpp

//From the folder geometryASN, to convert the ASN1 to c execute the following
// asn1c -fcompound-names -gen-PER ../Geometry.asn1
#include <iostream>
#include "geometryASN/Rectangle.h"
#include "geometryASN/RectangularCuboid.h"
#include "geometryASN/LimitedRectangularCuboids.h"
#include "geometryASN/UnlimitedRectangularCuboids.h"

bool validate_constraints(asn_TYPE_descriptor_t *type_descriptor, const void *struct_ptr) {

  char error_buffer[128];
  size_t error_length = sizeof(error_buffer);
  const int return_value = asn_check_constraints(type_descriptor, struct_ptr, error_buffer, &error_length);

  if (return_value) {
    perror("asn_check_constraints() failed");
  }
  return (return_value == 0);
}

void *encode_and_decode_object(asn_TYPE_descriptor_t *type_descriptor, void *struct_ptr) {

  //First we validate that our object meets the expected constraints
  if (validate_constraints(type_descriptor, struct_ptr)) {
    void *buffer;
    asn_per_constraints_s *constraints = NULL;
    //Then, we encode the object to ASN.1 and assign the data to a buffer in memory
    const ssize_t ec = uper_encode_to_new_buffer(type_descriptor, constraints, struct_ptr, &buffer);
    if (ec == -1) {
      perror("uper_encode_to_new_buffer() failed");
    } else {
      //ASN.1 encoded object is not in the buffer variable and it is available for you to use.
      //Finally, since the encoding process went fine, we decode the data to verify with our own eyes that the process went smoothly
      void *decoded_object = 0;
      const asn_dec_rval_t rval = uper_decode(0, type_descriptor, &decoded_object, buffer, (size_t) ec, 0, 0);
      free(buffer);
      if (rval.code != RC_OK) {
        perror("uper_decode() failed");
        fprintf(stderr, "Broken encoding at byte %ld\n", rval.consumed);
      } else {
        return decoded_object;
      }
    }
  }
  return NULL;
}

int main(int argc, char *argv[]) {

  //Scenario A: We test basic encoding and decoding on a Rectangle.
  {
    //First we create a rectangle and then we encode it
    Rectangle_t *rectangle = (Rectangle_t *) calloc(1, sizeof(Rectangle_t));
    if (rectangle == NULL) {
      perror("calloc() failed");
      exit(EXIT_FAILURE);
    }
    rectangle->height = 10;
    rectangle->width = 150;

    Rectangle_t *decoded_rectangle = (Rectangle_t *) encode_and_decode_object(&asn_DEF_Rectangle, rectangle);

    if (decoded_rectangle != NULL) {
      if (rectangle->height != decoded_rectangle->height || rectangle->width != decoded_rectangle->width) {
        perror("uper_decode() failed. Wrong values found after decoding");
        ASN_STRUCT_FREE(asn_DEF_Rectangle, rectangle);
        ASN_STRUCT_FREE(asn_DEF_Rectangle, decoded_rectangle);
        exit(EXIT_FAILURE);
      }
    }
    ASN_STRUCT_FREE(asn_DEF_Rectangle, rectangle);
    ASN_STRUCT_FREE(asn_DEF_Rectangle, decoded_rectangle);
  }

  //Scenario B: We test basic encoding and decoding on a Rectangle.
  //We will provide a value that is out of the constraints area to force the test to fail.
  {
    //First we create a rectangle and then we encode it
    Rectangle_t *rectangle = (Rectangle_t *) calloc(1, sizeof(Rectangle_t));
    if (rectangle == NULL) {
      perror("calloc() failed");
      exit(EXIT_FAILURE);
    }
    rectangle->height = -10;
    rectangle->width = 150;

    Rectangle_t *decoded_rectangle = (Rectangle_t *) encode_and_decode_object(&asn_DEF_Rectangle, rectangle);

    if (decoded_rectangle != NULL) {
      perror("This test should have failed due to the constaint on the range of the valid values.");
      ASN_STRUCT_FREE(asn_DEF_Rectangle, rectangle);
      ASN_STRUCT_FREE(asn_DEF_Rectangle, decoded_rectangle);
      exit(EXIT_FAILURE);
    }
    ASN_STRUCT_FREE(asn_DEF_Rectangle, rectangle);
  }

  //Scenario C: We test basic encoding and decoding on a Rectangular Cuboid.
  {
    //First we create a rectangular cuboid and then we encode it
    RectangularCuboid_t *rectangular_cuboid = (RectangularCuboid_t *) calloc(1, sizeof(RectangularCuboid_t));
    if (rectangular_cuboid == NULL) {
      perror("calloc() failed");
      exit(EXIT_FAILURE);
    }
    rectangular_cuboid->depth = 27;
    rectangular_cuboid->rectangle.height = 10;
    rectangular_cuboid->rectangle.width = 150;

    RectangularCuboid_t *decoded_rectangular_cuboid = (RectangularCuboid_t *) encode_and_decode_object(
        &asn_DEF_RectangularCuboid, rectangular_cuboid);

    if (decoded_rectangular_cuboid != NULL) {
      if (rectangular_cuboid->rectangle.height != decoded_rectangular_cuboid->rectangle.height
          || rectangular_cuboid->rectangle.width != decoded_rectangular_cuboid->rectangle.width
          || rectangular_cuboid->depth != decoded_rectangular_cuboid->depth) {
        perror("uper_decode() failed. Wrong values found after decoding");
        ASN_STRUCT_FREE(asn_DEF_RectangularCuboid, rectangular_cuboid);
        ASN_STRUCT_FREE(asn_DEF_RectangularCuboid, decoded_rectangular_cuboid);
        exit(EXIT_FAILURE);
      }
    }
    ASN_STRUCT_FREE(asn_DEF_RectangularCuboid, rectangular_cuboid);
    ASN_STRUCT_FREE(asn_DEF_RectangularCuboid, decoded_rectangular_cuboid);
  }

  //Scenario D: We will create an array of elements that has no limitation on its size.
  {
    UnlimitedRectangularCuboids_t *unlimited_rectangular_cuboids = (UnlimitedRectangularCuboids_t *) calloc(1,
                                                                                                            sizeof(UnlimitedRectangularCuboids_t));
    if (unlimited_rectangular_cuboids == NULL) {
      perror("calloc() failed");
      exit(EXIT_FAILURE);
    }

    int i;
    for (i = 0; i < 10; i++) {       RectangularCuboid_t *tmp_rectangular_cuboid = (RectangularCuboid_t *) calloc(1, sizeof(RectangularCuboid_t));       if (tmp_rectangular_cuboid == NULL) {         perror("calloc() failed");         exit(EXIT_FAILURE);       }       tmp_rectangular_cuboid->depth = i;
      tmp_rectangular_cuboid->rectangle.height = i * 11;
      tmp_rectangular_cuboid->rectangle.width = i * 101;

      const int result = asn_set_add(unlimited_rectangular_cuboids, tmp_rectangular_cuboid);
      if (result != 0) {
        perror("asn_set_add() failed");
        ASN_STRUCT_FREE(asn_DEF_UnlimitedRectangularCuboids, unlimited_rectangular_cuboids);
        exit(EXIT_FAILURE);
      }
    }

    UnlimitedRectangularCuboids_t *decoded_unlimited_rectangular_cuboids = (UnlimitedRectangularCuboids_t *) encode_and_decode_object(
        &asn_DEF_UnlimitedRectangularCuboids, unlimited_rectangular_cuboids);

    if (decoded_unlimited_rectangular_cuboids != NULL) {
      for (i = 0; i < decoded_unlimited_rectangular_cuboids->list.count; i++) {
        RectangularCuboid_t *tmp_rectangular_cuboid = decoded_unlimited_rectangular_cuboids->list.array[i];
        if (tmp_rectangular_cuboid->rectangle.height != i * 11
            || tmp_rectangular_cuboid->rectangle.width != i * 101
            || tmp_rectangular_cuboid->depth != i) {
          perror("uper_decode() failed. Wrong values found after decoding");
          ASN_STRUCT_FREE(asn_DEF_UnlimitedRectangularCuboids, unlimited_rectangular_cuboids);
          ASN_STRUCT_FREE(asn_DEF_UnlimitedRectangularCuboids, decoded_unlimited_rectangular_cuboids);
          exit(EXIT_FAILURE);
        }
      }
    }
    ASN_STRUCT_FREE(asn_DEF_UnlimitedRectangularCuboids, unlimited_rectangular_cuboids);
    ASN_STRUCT_FREE(asn_DEF_UnlimitedRectangularCuboids, decoded_unlimited_rectangular_cuboids);
  }

  //Scenario E: We will create an array of elements that has a limitation on how many elements it can accept.
  //We will add more elements than expected and we expect the encoding to fail.
  {
    LimitedRectangularCuboids_t *limited_rectangular_cuboids = (LimitedRectangularCuboids_t *) calloc(1,
                                                                                                      sizeof(LimitedRectangularCuboids_t));
    if (limited_rectangular_cuboids == NULL) {
      perror("calloc() failed");
      exit(EXIT_FAILURE);
    }

    int i;
    for (i = 0; i < 10; i++) {       RectangularCuboid_t *tmp_rectangular_cuboid = (RectangularCuboid_t *) calloc(1, sizeof(RectangularCuboid_t));       if (tmp_rectangular_cuboid == NULL) {         perror("calloc() failed");         exit(EXIT_FAILURE);       }       tmp_rectangular_cuboid->depth = i;
      tmp_rectangular_cuboid->rectangle.height = i * 11;
      tmp_rectangular_cuboid->rectangle.width = i * 101;

      const int result = asn_set_add(limited_rectangular_cuboids, tmp_rectangular_cuboid);
      if (result != 0) {
        perror("asn_set_add() failed");
        ASN_STRUCT_FREE(asn_DEF_LimitedRectangularCuboids, limited_rectangular_cuboids);
        exit(EXIT_FAILURE);
      }
    }

    LimitedRectangularCuboids_t *decoded_limited_rectangular_cuboids = (LimitedRectangularCuboids_t *) encode_and_decode_object(
        &asn_DEF_LimitedRectangularCuboids, limited_rectangular_cuboids);

    if (decoded_limited_rectangular_cuboids != NULL) {
      perror("This test should have failed due to limitation on the size of the list.");
      ASN_STRUCT_FREE(asn_DEF_LimitedRectangularCuboids, limited_rectangular_cuboids);
      ASN_STRUCT_FREE(asn_DEF_LimitedRectangularCuboids, decoded_limited_rectangular_cuboids);
      exit(EXIT_FAILURE);
    }
    ASN_STRUCT_FREE(asn_DEF_LimitedRectangularCuboids, limited_rectangular_cuboids);
  }

  printf ("All tests were successful\n");
  return EXIT_SUCCESS;
}

ASN.1 C Full Example (compressed) (1240 downloads)


ECE795 – Study Notes

1. INTRODUCTION

Page 2

Machine learning algorithms must be trained using a large set of known data and then tested using another independent set before it is used on unknown data.

The result of running a machine learning algorithm can be expressed as a
function y(x) which takes a new x as input and that generates an output vector y, encoded in the same way as the target vectors. The precise form of the function y(x) is determined during the training phase, also known as the learning phase, on the basis of the training data. Once the model is trained it can then determine the identity of new elements, which are said to comprise a test set. The ability to categorize correctly new examples that differ from those used for training is known as generalization. In practical applications, the variability of the input vectors will be such that the training data can comprise only a tiny fraction of all possible input vectors, and so generalization is a central goal in pattern recognition.

The pre-processing stage is sometimes also called feature extraction. Note that new test data must be pre-processed using the same steps as the training data. The aim is to find useful features that are fast to compute, and yet that also preserve useful discriminatory information. Care must be taken during pre-processing because often information is discarded, and if this information is important to the solution of the problem then the overall accuracy of the system can suffer.

Page 3

Applications in which the training data comprises examples of the input vectors along with their corresponding target vectors are known as supervised learning problems. Cases such as the digit recognition example, in which the aim is to assign each input vector to one of a finite number of discrete categories, are called classification problems. If the desired output consists of one or more continuous variables, then the task is called regression. An example of a regression problem would be the prediction of the yield in a chemical manufacturing process in which the inputs consist of the concentrations of reactants, the temperature, and the pressure.

In other pattern recognition problems, the training data consists of a set of input
vectors x without any corresponding target values. The goal in such unsupervised learning problems may be to discover groups of similar examples within the data, where it is called clustering, or to determine the distribution of data within the input space, known as density estimation, or to project the data from a high-dimensional space down to two or three dimensions for the purpose of visualization.

Finally, the technique of reinforcement learning (Sutton and Barto, 1998) is concerned with the problem of finding suitable actions to take in a given situation in order to maximize a reward. Here the learning algorithm is not given examples of optimal outputs, in contrast to supervised learning, but must instead discover them by a process of trial and error. Typically there is a sequence of states and actions in which the learning algorithm is interacting with its environment. In many cases, the current action not only affects the immediate reward but also has an impact on the reward at all subsequent time steps.

The reward must then be attributed appropriately to all of the moves that led to it, even though some moves will have been good ones and others less so. This is an example of a credit assignment problem. A general feature of reinforcement learning is the trade-off between exploration, in which the system tries out new kinds of actions to see how effective they are, and exploitation, in which
the system makes use of actions that are known to yield a high reward.

1.1 Example: Polynomial Curve Fitting

Page 5

We fit the data using a polynomial function of the form:

y(x, w) = w_{0}x^{0} + w_{1}x^{1} + w_{2}x^{2} + . . . + w_{M}x^{M} = \sum_{j =0}^{M}w_{j}x^{j}

where M is the order of the polynomial.

The values of the coefficients will be determined by fitting the polynomial to the
training data. This can be done by minimizing an error function that measures the misfit between the function y(x, w), for any given value of w, and the training set data points.

Our error function: Sum of the squares of the errors between the predictions y(x_{n} , w) for each data point x_n and the corresponding target values t_n.

E(w) = \frac{1}{2}\sum_{n=1}^{N}\{y(x_{n},w) - t_{n}\}^2

Much higher order polynomial can cause Over-Fitting : the fitted curve oscillates wildly and gives a very poor representation of the function.

We can obtain some quantitative insight into the dependence of the generalization performance on M by considering a separate test set comprising 100 data points generated using exactly the same procedure used to generate the training set points but with new choices for the random noise values included in the target values.

Root Mean Square: E_{RMS} = \sqrt{2E(w*)/N}

The division by N allows us to compare different sizes of data sets on an equal footing, and the square root ensures that E_{RMS} is measured on the same scale (and in the same units) as the target variable t.

 

OTHER

To study

Curve Fitting

Additional Terms

Legend:

  • TP = True Positive
  • TN = True Negative
  • FP = False Positive
  • FN = False Negative
correct\ rate (accuracy) = \frac{TP + TN}{TP + TN + FP + FN} sensitivity = \frac{TP}{TP + FN} specificity = \frac{TN}{TN + FP}

Receiver Operating Characteristic

In statistics, a receiver operating characteristic (ROC), or ROC curve, is a graphical plot that illustrates the performance of a binary classifier system as its discrimination threshold is varied. The curve is created by plotting the true positive rate (sensitivity) against the false positive rate (1  – specificity) at various threshold settings.
— From https://en.wikipedia.org/wiki/Receiver_operating_characteristic

receiver-operating-characteristic-roc-sensitivity-and-1-specificityAssuming we have a system where changing its configuration we get the above results, we would pick the configuration that has the smallest Euclidean Distance from the perfect configuration. The perfect configuration can be found at point (0,1) where both Specificity and Sensitivity are both equal to one.

Chapters to ignore

Non – Parametric


Google Hash Code 2017 Limassol Cyprus – Call for participation

We’ll be hosting a hub at the Cyprus University of Technology for the Online Qualification Round of Hash Code, a team-based programming competition created by Google for university students and industry professionals. The Online Qualification Round takes place on the 23rd of February at 19:30 EET and registered teams from Cyprus are invited to participate from our hub, which will take place at the Labs of the University. Top scoring teams from the Online Qualification Round will then be invited to Google’s Paris office to compete in the Final Round of the competition in April.

If you’re interested in joining our hub, find a team (two to four people) and register at g.co/hashcode. Make sure to select Cyprus University of Technology from the list of hubs in the Judge System.

For more information about this and other hubs in Cyprus (including the twin event in Nicosia) visit https://goo.gl/XSfUPv

Hash Code 2017 Limassol Cyprus – Facebook Event

Thanks!

Address:

Cyprus University of Technology
Room: ΚΧΕ 1 - Computer Lab
Polyxeni Loizia and Eleni Autonomou Building (Old Cadastre)
Athinon Street
Limassol

Τεχνολογικό Πανεπιστήμιο Κύπρου
Δωμάτιο: ΚΧΕ 1 -  Εργαστήριο Ηλεκτρονικών Υπολογιστών
Κτήριο Πολυξένη Λοϊζία και Ελένη Αυτονόμου (Παλιό Κτηματολόγιο)
Οδός Αθηνών
Λεμεσός

Date and Time:

23 February 2017
From: 19:30 EET
To: 23:30 EET

Free Amenities Offered

High speed Internet access
Wi-Fi access to the Internet for your mobile devices (personal computers and smart phones)
Lab computers will be available for use by the participants
Food in the form of snacks and beverages will be available outside the labs


C/C++: Full example using a linked list with custom struct

The following code is an example that presents some basic functionality on simply linked lists. Specifically, it presents how to add an element to an empty list and then how to add more elements either to the start (prepend) or to the end (append) of the list.

list_helpers.c (compressed) (158 downloads)

We assume that our structure holds an integer and a dynamically created string, which we free after pop.

list_helpers.c (compressed) (158 downloads)

 

Source file (list_helpers.c)

#include <malloc.h>
#include "list_helpers.h"

void append(node_t **head, element_t *element) {

  struct node_t *new = malloc(sizeof(node_t));
  new->element = element;
  new->next = NULL;

  if (*head == NULL) {
    *head = new;
    return;
  }

  struct node_t *current = *head;

  while (current->next != NULL) {
    current = current->next;
  }

  current->next = new;
  return;
}

void prepend(node_t **head, element_t *element) {
  struct node_t *new = malloc(sizeof(node_t));

  new->element = element;
  new->next = *head;
  *head = new;
}

element_t *pop(node_t **head) {

  node_t *next = NULL;

  if (*head == NULL) {
    return NULL;
  }

  next = (*head)->next;
  element_t *element = (*head)->element;
  free(*head);
  *head = next;

  return element;
}

void clear(node_t **head) {
  element_t *current = pop(head);
  while (current != NULL) {
    free(current->username);
    free(current);
    current = pop(head);
  }
}

Header file (list_helpers.h)

#ifndef GM_S_LITTLE_HELPERS_LIST_HELPERS_H
#define GM_S_LITTLE_HELPERS_LIST_HELPERS_H

#ifdef __cplusplus
extern "C" {
#endif

typedef struct element_t element_t;
struct element_t {
  //We add random members to the element struct for the sake of the example
  char *username;
  unsigned int server;
};

typedef struct node_t node_t;
struct node_t {
  element_t *element;
  node_t *next;
};

void append(node_t **head, element_t *element);

void prepend(node_t **head, element_t *element);

element_t *pop(node_t **head);

void clear(node_t **head);

#ifdef __cplusplus
}
#endif

#endif //GM_S_LITTLE_HELPERS_LIST_HELPERS_H

Usage example (main.cpp)

#include <iostream>
#include "list_helpers.h"

element_t *create_user(const unsigned int server, const char *username) {

  element_t *user = (element_t *) malloc(sizeof(element_t));
  user->server = server;

  //For the sake of the example we used snprintf.
  //Upon successful return, snprintf returns the number of characters printed (excluding the null byte used to end output to strings).
  //For that reason we add one at the end of the length.
  const int length = snprintf(NULL, 0, "%s", username) + 1;
  user->username = (char *) malloc((sizeof(char) * length));
  snprintf(user->username, (size_t) length, "%s", username);
  return user;
}

int main(int argc, char *argv[]) {

  node_t *head = NULL;

  //Add the first element to the linked list
  append(&head, create_user(10, "xeirwn"));

  //Add the second element to the end of the linked list
  append(&head, create_user(12, "test"));

  //Add the third element to the end of the linked list
  append(&head, create_user(14, "banana"));

  //Add the fourth element to the beginning of the linked list
  prepend(&head, create_user(8, "apple"));

  //Popping each one to process it and then free it
  //Clearing the list
  element_t *current = pop(&head);
  while (current != NULL) {

    printf("%s\t%u\n", current->username, current->server);
    free(current->username);
    free(current);
    current = pop(&head);
  }

  //Safely clear the list. In this specific scenario it will have 0 side effects as the list was cleared above
  clear(&head);
  return 0;
}
list_helpers.c (compressed) (158 downloads)