Skip to content
Santi Muñoz edited this page Oct 30, 2015 · 1 revision

Wide Eyes Mobile SDK

Our Visual Recognition system is accesed through an API, see the docs here, however we provide some examples of mobile implementation of these calls to aid in the integration process of our solution.

Authentication

Our API is accessed as a web service and require authentication.

  • Api key: You get your apikey in our dashboard then you only need to include it in the headers of your http calls, check the docs here for details.

Image Preprocessing

  1. Take a picture from camera or load a picture from gallery.

  2. Ask user to draw a contour around the main object (shoe, t-shirt or whatever).

  3. Convert the contour coordinates from screen scale to image scale (because the screen size is different than image size). Here, a pseudo-code could be like this:

    Let's consider coor_x_screen, coord_y_screen as X Y contourd coordinates at screen scale.

ratio_screen = screen_height / screen_width
ratio_image = image_height / image_width
coord_x_image = coord_x_screen * ratio_image / ratio_screen
coord_y_image = coord_y_screen * ratio_image / ratio_screen
  1. Crop image using contour coordinates to obtain the main object image region (in this way, the sent image to the server is small and enough big for image processing). For this, we should follow the following procedure:
  • Get minimun and maximun of X (x0,x1) and Y (y0,y1) axis. Let's consider px and py are coord_x_image and coord_y_image respectivelly:
    int x0 = Integer.MAX_VALUE, x1 = Integer.MIN_VALUE;
    int y0 = Integer.MAX_VALUE, y1 = Integer.MIN_VALUE;
    // find max and min of X and Y
    for (int i=0; i<px.length; i++){
	if (px[i] < x0) x0 = Math.round(px[i]);
	if (px[i] > x1) x1 = Math.round(px[i]);
	if (py[i] < y0) y0 = Math.round(py[i]);
	if (py[i] > y1) y1 = Math.round(py[i]);
    }

the final values of (x0, y0) and (x1, y1) are (21, 20) and (380, 253) respectivelly. These values define the left-up and right-down corners of the bounding box.

  • Compute the centroid of the bounding box:
    c_x = (x1 + x0) * 0.5
    c_y = (y1 + y0) * 0.5
  • add margin to bounding box size:
  margin = 0.1; % 10% larger. This value is quite good for our propose
  width_with_margin = (x1-x0+1) * (1 + 2 * margin); <!-- left and right -->
  height_with_margin = (y1-y0+1) * (1 + 2 * margin); <!-- up and down -->
  • add this margin and create a new larger bounding box. Make sure that the new ** bounding box ** is whithin the image size (image_width and image_height):
  x0 = min(image_width -1 , max(0, c_x - width_with_margin * 0.5))
  y0 = min(image_height -1 , max(0, c_y - height_with_margin * 0.5))
  x1 = min(image_width -1 , max(0, c_x + width_with_margin * 0.5))
  y1 = min(image_height -1 , max(0, c_y + height_with_margin * 0.5))
  • crop the image by new bounding box:
  im = imcrop(image, [x0 y0 x1 y1]);
  • now, we have the cropped image im and we have to rescale it to a standar size (e.g. 400 pixels):
  standard_size = 400;
  w = im.get_width;
  h = im.get_height;
  scale = 1.f; (1 float)
  if (w > h){
        scale = standard_size / w;
        new_width = standard_size;
        new_height = h * scale;
        im = imresize(im, new_width, new_height);
  }
  else{
        scale = standard_size / h;
        new_width = w * scale;
        new_height = standard_size;
        im = imresize(im, new_width, new_height);
  }
  • Right now, we have cropped the main object (in this case, the shoe) to a standar size. Now, we have to do the same procedure (cropping and rescaling) for the contour.
   // crop the contour
   for (int i=0; i<contour_length; i++){
        px[i] = px[i] - x0;
        py[i] = py[i] - yo;
   }
   // resize the contour
   for (int i=0; i<contour_length; i++){
        px[i] = px[i] * scale;
        py[i] = py[i] * scale;
   }
  • return the cropped image: im and the contour (px, py).

All the above pseudocode are found [here]https://github.com/WideEyesTech/we-vision-android-sdk/blob/master/src/main/java/it/wideeyes/sdk/services/WEComputerVision.java)