Saturday, December 26, 2015

Python, OpenCV: Video Capture and Display

OpenCV: Video Capture

import time
import cv2

video_capture = cv2.VideoCapture(0)
while True:
    t0=time.time()
    ret, frame = video_capture.read()
    t1=time.time()
    print "passed ", t1-t0, "s"

    cv2.imshow('Video', frame)
    #on pressing "q" exit
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
        
video_capture.release()
cv2.destroyAllWindows()  

Frames Per Second Counter

#test how many frames per second for a webcam
import time
import cv2

video_capture = cv2.VideoCapture(1)
t0 = time.time()
i=0
while True:
    ret, frame = video_capture.read()
    print frame.shape
    t = time.time()
    if t-t0 > 1:
        t0=t
        print "frames ",i
        i=0
        
    i+=1    
                    
    cv2.imshow('Video', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
        
video_capture.release()
cv2.destroyAllWindows()   

Wednesday, December 23, 2015

Python: JSON socket - Server/Client Structure

JSON Socket Library

#file:jsonsocket.py
#https://github.com/mdebbar/jsonsocket
import json, socket

class Server(object):
  """
  A JSON socket server used to communicate with a JSON socket client. All the
  data is serialized in JSON. How to use it:

  server = Server(host, port)
  while True:
    server.accept()
    data = server.recv()
    # shortcut: data = server.accept().recv()
    server.send({'status': 'ok'})
  """

  backlog = 5
  client = None

  def __init__(self, host, port):
    self.socket = socket.socket()
    self.socket.bind((host, port))
    self.socket.listen(self.backlog)

  def __del__(self):
    self.close()

  def accept(self):
    # if a client is already connected, disconnect it
    if self.client:
      self.client.close()
    self.client, self.client_addr = self.socket.accept()
    return self

  def send(self, data):
    if not self.client:
      raise Exception('Cannot send data, no client is connected')
    _send(self.client, data)
    return self

  def recv(self):
    if not self.client:
      raise Exception('Cannot receive data, no client is connected')
    return _recv(self.client)

  def close(self):
    if self.client:
      self.client.close()
      self.client = None
    if self.socket:
      self.socket.close()
      self.socket = None


class Client(object):
  """
  A JSON socket client used to communicate with a JSON socket server. All the
  data is serialized in JSON. How to use it:

  data = {
    'name': 'Patrick Jane',
    'age': 45,
    'children': ['Susie', 'Mike', 'Philip']
  }
  client = Client()
  client.connect(host, port)
  client.send(data)
  response = client.recv()
  # or in one line:
  response = Client().connect(host, port).send(data).recv()
  """

  socket = None

  def __del__(self):
    self.close()

  def connect(self, host, port):
    self.socket = socket.socket()
    self.socket.connect((host, port))
    return self

  def send(self, data):
    if not self.socket:
      raise Exception('You have to connect first before sending data')
    _send(self.socket, data)
    return self

  def recv(self):
    if not self.socket:
      raise Exception('You have to connect first before receiving data')
    return _recv(self.socket)

  def recv_and_close(self):
    data = self.recv()
    self.close()
    return data

  def close(self):
    if self.socket:
      self.socket.close()
      self.socket = None

## helper functions ##

def _send(socket, data):
  try:
    serialized = json.dumps(data)
  except (TypeError, ValueError), e:
    raise Exception('You can only send JSON-serializable data')
  # send the length of the serialized data first
  socket.send('%d\n' % len(serialized))
  # send the serialized data
  socket.sendall(serialized)

def _recv(socket):
  # read the length of the data, letter by letter until we reach EOL
  length_str = ''
  char = socket.recv(1)
  while char != '\n':
    length_str += char
    char = socket.recv(1)
  total = int(length_str)
  # use a memoryview to receive the data chunk by chunk efficiently
  view = memoryview(bytearray(total))
  next_offset = 0
  while total - next_offset > 0:
    recv_size = socket.recv_into(view[next_offset:], total - next_offset)
    next_offset += recv_size
  try:
    deserialized = json.loads(view.tobytes())
  except (TypeError, ValueError), e:
    raise Exception('Data received was not in JSON format')
  return deserialized

Server

#file:server.py
from jsonsocket import Server

host = 'LOCALHOST'
port = 8080

server = Server(host, port)

while True:
    server.accept()
    data = server.recv()
    server.send({"response":data})

server.close()

Client

#file:client.py
from jsonsocket import Client
import time

host = 'LOCALHOST'
port = 8080

i=1
while True:
    client = Client()
    client.connect(host, port).send({'test':i})
    i+=1
    response = client.recv()
    print response
    client.close()
    time.sleep(1)

Tuesday, December 22, 2015

Python: Pitfalls Filled

# list to string, separated by comma
lis = [1,2,3]
print ",".join(map(str, lis))

# print system time in formated way - logging time
from time import gmtime, strftime
strftime("%Y-%m-%d %H:%M:%S", gmtime())

#appending dict or merging two dicts
b={}
d=b.copy()
d.update({'list':0})

#joining dict with string
yook = {'a':0,'img':['url2','url2']}
print str(yook) + "asd"

#pretty print (json - dict)
a= {u'response': {u'url': u'http://www.faceplusplus.com/static/img/demo/9.jpg', u'img_id': u'2081892e329727f350337509ff939a29', u'img_width': 540, u'session_id': u'd6fdce4b591e43dabbd8d31f68db0a46', u'face': [{u'attribute': {u'gender': {u'confidence': 99.7639, u'value': u'Male'}, u'age': {u'range': 9, u'value': 23}, u'race': {u'confidence': 99.9662, u'value': u'White'}, u'smiling': {u'value': 13.909}}, u'face_id': u'42dd2bdec1f8fae250a8d4c6b5f11837', u'tag': u'', u'position': {u'eye_left': {u'y': 44.727248, u'x': 58.625}, u'center': {u'y': 46.730245, u'x':59.537037}, u'width': 5.0, u'mouth_left': {u'y': 47.659401, u'x': 58.412037}, u'height': 7.356948, u'mouth_right': {u'y': 47.838692, u'x': 60.201481}, u'nose':{u'y': 46.782834, u'x': 59.463519}, u'eye_right': {u'y': 44.922616, u'x': 60.493333}}}], u'img_height': 367}}

from pprint import pprint
pprint(a)

It is prettier, isn't it?

{u'response': {u'face': [{u'attribute': {u'age': {u'range': 9,
                                                  u'value': 23},
                                         u'gender': {u'confidence': 99.7639,
                                                     u'value': u'Male'},
                                         u'race': {u'confidence': 99.9662,
                                                   u'value': u'White'},
                                         u'smiling': {u'value': 13.909}},
                          u'face_id': u'42dd2bdec1f8fae250a8d4c6b5f11837',
                          u'position': {u'center': {u'x': 59.537037,
                                                    u'y': 46.730245},
                                        u'eye_left': {u'x': 58.625,
                                                      u'y': 44.727248},
                                        u'eye_right': {u'x': 60.493333,
                                                       u'y': 44.922616},
                                        u'height': 7.356948,
                                        u'mouth_left': {u'x': 58.412037,
                                                        u'y': 47.659401},
                                        u'mouth_right': {u'x': 60.201481,
                                                         u'y': 47.838692},
                                        u'nose': {u'x': 59.463519,
                                                  u'y': 46.782834},
                                        u'width': 5.0},
                          u'tag': u''}],
               u'img_height': 367,
               u'img_id': u'2081892e329727f350337509ff939a29',
               u'img_width': 540,
               u'session_id': u'd6fdce4b591e43dabbd8d31f68db0a46',
               u'url': u'http://www.faceplusplus.com/static/img/demo/9.jpg'}}

Friday, December 18, 2015

Windows DOS Batch: Rename all the folders numerically

The following snippet renames all folders in current directory to numbers starting from 0.

set i=0
for %f in (*) do (set /A "i=i+1")

References

Thursday, December 17, 2015

Python: Call Function From String

Somehow there is a need to make calls from string, i.e. I have the name of the functions in string, now I need to call that function from that string.

import inspect

class API:
    def f1(self):
        print "f1 is called from",self.__class__.__name__
        
def f1():
    print "f1 is called from",inspect.stack()[0][3]
        
api = API()
a = "f1"

globals()[a]()
getattr(api,a)()

The results should be

f1 is called from f1
f1 is called from API

Tuesday, December 1, 2015

Windows cmd: Create Incrementing Folders With For Loop

Bring up Windows console with Win+R and cmd, type

for /l %i in (1,1,100);do mkdir %i

Syntax

      FOR /L %%parameter IN (start,step,end) DO command 

Notice that, double percentage symbol is used for batch file, and on the command line

%%parameter : A replaceable parameter:
                 in a batch file use %%i (on the command line %i)

References

Tuesday, November 3, 2015

HTML5 Image Capture on Mobile and Server-side Handling

Since on mobile browsers, the video tag is not fully supported, one need to use the following to take a shot.

<button onclick="$('#inputv').trigger('click');">Take a shot</button>
<input type="file" id="inputv" name="inputv" accept="image/*" capture="camera" style="display:none">
<div id="f_img"></div>

And on js side, you need to utilize FileReader object to read the image shot from it. The image is stored in base64 string format, which can be added to src attribute to show the image on the page.

window.addEventListener("DOMContentLoaded", function(){
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        $("#inputv").change(function(e){
                var f = e.target.files[0];
                //  alert(f.size);
                var reader = new FileReader();
                reader.onload = function(e) {
                    //write your code to process the image
                    $("#f_img").html('<img src="' + e.target.result + '">');
                };
                reader.readAsDataURL(f);
        });
    // Great success! All the File APIs are supported.
    } else {
        $("#notice").append('The File APIs are not fully supported in this browser.');
    }

The image in base64 can be uploaded to the server part using input tag with the type as text. A possible server-side handling witten in python can be the following:

from flask import request

image = request.form['image']

def save_b64(image):
    img_str = str(image) #unicode to str obj
    head="data:image/jpeg;base64,"
    if str(img_str).startswith(head):
        l = len(head)
        img_str = img_str[l:]
    
    import time
    timestr = time.strftime("%Y%m%d%H%M%S")
    path = "image/capture-" + timestr + ".jpg"
    try:
        img = open(path, "wb")
        img.write(img_str.decode('base64'))
        img.close()
        return path
    except Exception as e:
        return False

Monday, April 20, 2015

OpenCV: Passing Parameters to Trackbar Callback Function

OpenCV Trackbars are created through the system call like below, with a callback function which is called when there is any change on the bar.

createTrackbar("Dummy Trackbar Name", "Dummy Window Name", &pos, max_pos, onTrackbarChange, &u);

Here pos is the pass-by-ref variable that records the current position of trackbar, max_pos denotes its maximum possible value of this variable that the bar can handle. onTrackbarChange is the callback function u is the user data that is passed to the callback function.

onTrackbarChange is prototyped as

void onTrackbarChange(int, void*);

Since there is only limited parameters, the data has to be packaged into an object or a structure like this,

typedef struct {
 Mat* grad;
 Mat* dst;
 Mat* detected_edges;
 int* pos;
 int* ratio;
 int* kernel_size;
 char* window_name;
} userdata;

Of cource, the members within userdata structure could be whatever type you might need. Here I grab a snippet of what my demo is using. Thus you can implement the callback function on demand.

void onTrackbarChange(int pos, void* ud) {
 userdata u = *static_cast(ud);

 // Reduce noise with a kernel 3x3
 blur(*u.grad, *u.detected_edges, Size(3, 3));

 // Canny detector
 Canny(*u.detected_edges, *u.detected_edges, *u.pos, *u.pos*(*u.ratio), *u.kernel_size);

 // Using Canny's output as a mask, we display our result
 *u.dst = Scalar::all(0);

 (*u.grad).copyTo(*u.dst, *u.detected_edges);
 imshow(u.window_name, *u.dst);
        waitKey(0);
}