diff --git a/configure.ac b/configure.ac
index d8230c0..dbe302d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1258,7 +1258,7 @@ AG_GST_CHECK_FEATURE(OPENCV, [opencv plugins], opencv, [
   dnl a new version and the no-backward-compatibility define. (There doesn't
   dnl seem to be a switch to suppress the warnings the cvcompat.h header
   dnl causes.)
-  PKG_CHECK_MODULES(OPENCV, opencv >= 2.0.0 opencv <= 2.1.0 , [
+  PKG_CHECK_MODULES(OPENCV, opencv >= 2.0.0 opencv <= 2.2.0 , [
     AC_PROG_CXX
     AC_LANG_CPLUSPLUS
     OLD_CPPFLAGS=$CPPFLAGS
diff --git a/ext/opencv/gstfaceblur.c b/ext/opencv/gstfaceblur.c
index 3ac2af4..29c8dc0 100644
--- a/ext/opencv/gstfaceblur.c
+++ b/ext/opencv/gstfaceblur.c
@@ -163,6 +163,7 @@ gst_faceblur_class_init (GstfaceblurClass * klass)
           DEFAULT_PROFILE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 }
 
+
 /* initialize the new element
  * instantiate pads and add them to element
  * set pad calback functions
@@ -269,7 +270,11 @@ gst_faceblur_chain (GstPad * pad, GstBuffer * buf)
   if (filter->cvCascade) {
     faces =
         cvHaarDetectObjects (filter->cvGray, filter->cvCascade,
-        filter->cvStorage, 1.1, 2, 0, cvSize (30, 30));
+        filter->cvStorage, 1.1, 2, 0, cvSize (30, 30)
+#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2)
+        , cvSize (32, 32)
+#endif
+        );
 
     if (faces && faces->total > 0) {
       buf = gst_buffer_make_writable (buf);
diff --git a/ext/opencv/gstfaceblur.h b/ext/opencv/gstfaceblur.h
index 34ea09a..9c98ce8 100644
--- a/ext/opencv/gstfaceblur.h
+++ b/ext/opencv/gstfaceblur.h
@@ -49,6 +49,10 @@
 #include <gst/gst.h>
 #include <cv.h>
 
+#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2)
+#include <opencv2/objdetect/objdetect.hpp>
+#endif
+
 G_BEGIN_DECLS
 /* #defines don't like whitespacey bits */
 #define GST_TYPE_FACEBLUR \
diff --git a/ext/opencv/gstfacedetect.c b/ext/opencv/gstfacedetect.c
index 0254b74..a3ced6d 100644
--- a/ext/opencv/gstfacedetect.c
+++ b/ext/opencv/gstfacedetect.c
@@ -408,8 +408,11 @@ gst_facedetect_transform_ip (GstOpencvVideoFilter * base, GstBuffer * buf,
     faces =
         cvHaarDetectObjects (filter->cvGray, filter->cvCascade,
         filter->cvStorage, filter->scale_factor, filter->min_neighbors,
-        filter->flags,
-        cvSize (filter->min_size_width, filter->min_size_height));
+        filter->flags, cvSize (filter->min_size_width, filter->min_size_height)
+#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2)
+        , cvSize (filter->min_size_width + 2, filter->min_size_height + 2)
+#endif
+        );
 
     if (faces && faces->total > 0) {
       msg = gst_facedetect_message_new (filter, buf);
diff --git a/ext/opencv/gstfacedetect.h b/ext/opencv/gstfacedetect.h
index fbb8718..a5a0b49 100644
--- a/ext/opencv/gstfacedetect.h
+++ b/ext/opencv/gstfacedetect.h
@@ -50,6 +50,10 @@
 #include <cv.h>
 #include "gstopencvvideofilter.h"
 
+#if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2)
+#include <opencv2/objdetect/objdetect.hpp>
+#endif
+
 G_BEGIN_DECLS
 /* #defines don't like whitespacey bits */
 #define GST_TYPE_FACEDETECT \
diff --git a/ext/opencv/gstopencvvideofilter.c b/ext/opencv/gstopencvvideofilter.c
index 7c42b19..23892cf 100644
--- a/ext/opencv/gstopencvvideofilter.c
+++ b/ext/opencv/gstopencvvideofilter.c
@@ -218,6 +218,8 @@ gst_opencv_video_filter_set_caps (GstBaseTransform * trans, GstCaps * incaps,
   GError *in_err = NULL;
   GError *out_err = NULL;
 
+  GST_DEBUG_OBJECT (trans, "gst_opencv_video_filter_set_caps");
+
   if (!gst_opencv_parse_iplimage_params_from_caps (incaps, &in_width,
           &in_height, &in_depth, &in_channels, &in_err)) {
     GST_WARNING_OBJECT (transform, "Failed to parse input caps: %s",
diff --git a/ext/opencv/gsttemplatematch.c b/ext/opencv/gsttemplatematch.c
index bc15d81..168b6b1 100644
--- a/ext/opencv/gsttemplatematch.c
+++ b/ext/opencv/gsttemplatematch.c
@@ -162,7 +162,7 @@ gst_templatematch_class_init (GstTemplateMatchClass * klass)
 
 /* initialize the new element
  * instantiate pads and add them to element
- * set pad calback functions
+ * set pad callback functions
  * initialize instance structure
  */
 static void
@@ -240,6 +240,8 @@ gst_templatematch_get_property (GObject * object, guint prop_id,
 {
   GstTemplateMatch *filter = GST_TEMPLATEMATCH (object);
 
+  GST_DEBUG_OBJECT (object, "gst_templatematch_get_property");
+
   switch (prop_id) {
     case PROP_METHOD:
       g_value_set_int (value, filter->method);
@@ -268,10 +270,16 @@ gst_templatematch_set_caps (GstPad * pad, GstCaps * caps)
   GstStructure *structure;
 
   filter = GST_TEMPLATEMATCH (gst_pad_get_parent (pad));
+
+  GST_DEBUG_OBJECT (filter, "gst_templatematch_set_caps");
+
   structure = gst_caps_get_structure (caps, 0);
   gst_structure_get_int (structure, "width", &width);
   gst_structure_get_int (structure, "height", &height);
 
+  GST_DEBUG_OBJECT (filter, "cvCreateImageHeader (cvSize(%d %d),%d,%d)",
+      width, height, IPL_DEPTH_8U, 3);
+
   filter->cvImage =
       cvCreateImageHeader (cvSize (width, height), IPL_DEPTH_8U, 3);
 
@@ -310,24 +318,39 @@ gst_templatematch_chain (GstPad * pad, GstBuffer * buf)
 
   filter = GST_TEMPLATEMATCH (GST_OBJECT_PARENT (pad));
 
+  GST_DEBUG_OBJECT (filter, "gst_templatematch_chain");
+
   /* FIXME Why template == NULL returns OK?
    * shouldn't it be a passthrough instead? */
   if ((!filter) || (!buf) || filter->template == NULL) {
     return GST_FLOW_OK;
   }
+  GST_DEBUG_OBJECT (filter, "Buffer size %u ", GST_BUFFER_SIZE (buf));
+
   filter->cvImage->imageData = (char *) GST_BUFFER_DATA (buf);
 
   if (!filter->cvDistImage) {
-    filter->cvDistImage =
-        cvCreateImage (cvSize (filter->cvImage->width -
-            filter->cvTemplateImage->width + 1,
-            filter->cvImage->height - filter->cvTemplateImage->height + 1),
-        IPL_DEPTH_32F, 1);
-    if (!filter->cvDistImage) {
-      GST_WARNING ("Couldn't create dist image.");
+    if (filter->cvTemplateImage->width > filter->cvImage->width) {
+      GST_WARNING ("Template Image is wider than input image");
+    } else if (filter->cvTemplateImage->height > filter->cvImage->height) {
+      GST_WARNING ("Template Image is taller than input image");
+    } else {
+
+      GST_DEBUG_OBJECT (filter, "cvCreateImage( Size(%d-%d+1,%d) %d, %d)",
+          filter->cvImage->width, filter->cvTemplateImage->width,
+          filter->cvImage->height - filter->cvTemplateImage->height + 1,
+          IPL_DEPTH_32F, 1);
+      filter->cvDistImage =
+          cvCreateImage (cvSize (filter->cvImage->width -
+              filter->cvTemplateImage->width + 1,
+              filter->cvImage->height - filter->cvTemplateImage->height + 1),
+          IPL_DEPTH_32F, 1);
+      if (!filter->cvDistImage) {
+        GST_WARNING ("Couldn't create dist image.");
+      }
     }
   }
-  if (filter->cvTemplateImage) {
+  if (filter->cvTemplateImage && filter->cvImage && filter->cvDistImage) {
     GstStructure *s;
     GstMessage *m;
 
@@ -389,8 +412,10 @@ gst_templatematch_load_template (GstTemplateMatch * filter)
   if (filter->template) {
     filter->cvTemplateImage =
         cvLoadImage (filter->template, CV_LOAD_IMAGE_COLOR);
+
     if (!filter->cvTemplateImage) {
-      GST_WARNING ("Couldn't load template image: %s.", filter->template);
+      GST_WARNING ("Couldn't load template image: %s. error: %s",
+          filter->template, g_strerror (errno));
     }
   }
 }
