Pages

Monday, 19 August 2013

Playing with the OpenCV HoG Detector

So... long-time-no-post.

I've just taken my robot for a walk to collect some data, while I wait for the 40GB to copy I thought I'd do a quick post. A few months ago I was playing the HoG detector in +OpenCV and using the PETS2009 data set.

My idea was that I might create a home security system from a bunch of old bits of hardware that are gathering dust.

- 1 x HTC Magic
- 1 x HTC Desire
- 1 x Fat Gecko Suction Mount
- 1 x Old HP Laptop

The plan is to use the two devices as IP Cams using this nifty app. Using the CURL lib I can access the images from C++ really easily and start throwing them at OpenCV

Here's a quick clip of the HoG detector running on the PETS09 data. It's not bad for an out-of-the-box solution.

OpenCV is available for Android so I could try running it directly on the handset, however the Magic isn't the most powerful, neither is the Desire; they are  unlikely to be able to process the images as fast as even a beaten up old lappy.
Now that the images are being fed into OpenCV it's time to think about  how I want to process them. Face recognition for the front door? Build a database of visitors? Get it to welcome me home?
Below is the code (mostly taken from CURL examples) to obtain the images from a network location and an example of the OpenCV HoG detector.
struct memoryStruct {
  char *memory;
  size_t size;
};

static void* CURL_realloc(void *ptr, size_t size)
{
  /* There might be a realloc() out there that doesn't like reallocing
     NULL pointers, so we take care of it here */
  if(ptr)
    return realloc(ptr, size);
  else
    return malloc(size);
}

size_t WriteMemoryCallback (void *ptr, size_t size, size_t nmemb, void *data) {
  size_t realsize = size * nmemb;
  struct memoryStruct *mem = (struct memoryStruct *)data;

  mem->memory = (char *)
  CURL_realloc(mem->memory, mem->size + realsize + 1);
  if (mem->memory) {
    memcpy(&(mem->memory[mem->size]), ptr, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = 0;
  }
  return realsize;
}

Mat getNewFrameFromAndroid(CURLcode res, memoryStruct buffer, CURL *curl) {
 while (true) {
   // set up the write to memory buffer
   // (buffer starts off empty)
   buffer.memory = NULL;
   buffer.size = 0;

   curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.8:8080/shot.jpg");

   // tell libcurl where to write the image (to a dynamic memory buffer)

   curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
   curl_easy_setopt(curl,CURLOPT_WRITEDATA, (void *) &buffer);

   // get the image from the specified URL
   res = curl_easy_perform(curl);

   // decode memory buffer using OpenCV
   cv::Mat imgTmp;
   imgTmp = cv::imdecode(cv::Mat(1, buffer.size, CV_8UC1, buffer.memory), CV_LOAD_IMAGE_UNCHANGED);

   if (!(imgTmp.empty())) {
    return imgTmp;
   }
 }
}
HOGDescriptor hog;
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());

vector<Rect> found;
hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);

No comments:

Post a Comment