diff --git a/src/filter/alpha0ps/alpha0ps.c b/src/filter/alpha0ps/alpha0ps.c
old mode 100755
new mode 100644
diff --git a/src/filter/alpha0ps/alphagrad.c b/src/filter/alpha0ps/alphagrad.c
old mode 100755
new mode 100644
diff --git a/src/filter/alpha0ps/alphaspot.c b/src/filter/alpha0ps/alphaspot.c
old mode 100755
new mode 100644
diff --git a/src/filter/blur/IIRblur.c b/src/filter/blur/IIRblur.c
old mode 100755
new mode 100644
diff --git a/src/filter/coloradj/coloradj_RGB.c b/src/filter/coloradj/coloradj_RGB.c
old mode 100755
new mode 100644
diff --git a/src/filter/denoise/hqdn3d.c b/src/filter/denoise/hqdn3d.c
old mode 100755
new mode 100644
diff --git a/src/filter/facebl0r/facebl0r.cpp b/src/filter/facebl0r/facebl0r.cpp
index 17446cc..fa21a35 100644
--- a/src/filter/facebl0r/facebl0r.cpp
+++ b/src/filter/facebl0r/facebl0r.cpp
@@ -22,49 +22,49 @@
 #include "frei0r.hpp"
 #include "frei0r_math.h"
 
-typedef struct {
-  IplImage* hsv;     //input image converted to HSV
-  IplImage* hue;     //hue channel of HSV image
-  IplImage* mask;    //image for masking pixels
-  IplImage* prob;    //face probability estimates for each pixel
+class TrackedObj {
+public:
+  void update_hist();
+  void update_hue_image (const cv::Mat& image);
+  cv::RotatedRect camshift_track_face();
+
+  cv::Mat hsv;     //input image converted to HSV
+  cv::Mat hue;     //hue channel of HSV image
+  cv::Mat mask;    //image for masking pixels
+  cv::Mat prob;    //face probability estimates for each pixel
 
-  CvHistogram* hist; //histogram of hue in original face image
+  cv::Mat hist;    //histogram of hue in original face image
+  static const int hist_bins;       //number of histogram bins
+  static const float hist_range[2]; //histogram range
+
+  cv::Rect prev_rect;  //location of face in previous frame
+  cv::RotatedRect curr_box;  //current face location estimate
+};
 
-  CvRect prev_rect;  //location of face in previous frame
-  CvBox2D curr_box;  //current face location estimate
-} TrackedObj;
+const float TrackedObj::hist_range[2] = { 0, 180 };
+const int TrackedObj::hist_bins = 30;
 
 class FaceBl0r: public frei0r::filter {
 
 public:
     FaceBl0r(int wdt, int hgt);
-    ~FaceBl0r();
+    ~FaceBl0r() = default;
 
     void update(double time,
                 uint32_t* out,
                 const uint32_t* in);
 
 private:
-    
-// camshift
-    TrackedObj* create_tracked_object (IplImage* image, CvRect* face_rect);
-    void destroy_tracked_object (TrackedObj* tracked_obj);
-    CvBox2D camshift_track_face (IplImage* image, TrackedObj* imgs);
-    void update_hue_image (const IplImage* image, TrackedObj* imgs);
-    
+
 //trackface
-    CvRect* detect_face (IplImage*, CvHaarClassifierCascade*, CvMemStorage*);
-    
+    std::vector<cv::Rect> detect_face();
+
+    TrackedObj tracked_obj;
 
-    TrackedObj* tracked_obj;
-    CvBox2D face_box; //area to draw
-    CvRect* face_rect;
-    
 //used by capture_video_frame, so we don't have to keep creating.
-    IplImage* image;
+    cv::Mat image;
 
-    CvHaarClassifierCascade* cascade;
-    CvMemStorage* storage;
+    cv::CascadeClassifier cascade;
 
     // plugin parameters
     std::string classifier;
@@ -77,7 +77,6 @@ class FaceBl0r: public frei0r::filter {
     double largest;
 
     std::string old_classifier;
-  
 
     unsigned int face_found;
     unsigned int face_notfound;
@@ -87,18 +86,12 @@ class FaceBl0r: public frei0r::filter {
 frei0r::construct<FaceBl0r> plugin("FaceBl0r",
 				  "automatic face blur",
 				  "ZioKernel, Biilly, Jilt, Jaromil, ddennedy",
-				  1,1, F0R_COLOR_MODEL_PACKED32);
+				  1,1, F0R_COLOR_MODEL_BGRA8888);
 
 FaceBl0r::FaceBl0r(int wdt, int hgt) {
 
-  face_rect = 0;
-  image = 0;
-  tracked_obj = 0;
   face_found = 0;
-  
-  cascade = 0;
-  storage = 0;
-  
+
   classifier = "/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml";
   register_param(classifier,
                  "Classifier",
@@ -120,52 +113,35 @@ FaceBl0r::FaceBl0r(int wdt, int hgt) {
   register_param(largest, "Largest", "Maximum object size in pixels, divided by 10000");
 }
 
-FaceBl0r::~FaceBl0r() {
-    if(tracked_obj)
-        destroy_tracked_object(tracked_obj);
-
-    if(cascade) cvReleaseHaarClassifierCascade(&cascade);
-    if(storage) cvReleaseMemStorage(&storage);
-    
-}
-
 void FaceBl0r::update(double time,
                       uint32_t* out,
-                          const uint32_t* in) {
-
-  if (!cascade) {
-      cvSetNumThreads(cvRound(threads * 100));
-      if (classifier.length() > 0) {
-	if (classifier == old_classifier) {
-	  // same as before, avoid repeating error messages
-	  memcpy(out, in, size * 4); // of course assuming we are RGBA only
-	  return;
-	} else old_classifier = classifier;
-
-	cascade = (CvHaarClassifierCascade*) cvLoad(classifier.c_str(), 0, 0, 0 );
-	if (!cascade) {
-	  fprintf(stderr, "ERROR in filter facebl0r, classifier cascade not found:\n");
-	  fprintf(stderr, " %s\n", classifier.c_str());
-	  memcpy(out, in, size * 4);
-	  return;
-	}
-	storage = cvCreateMemStorage(0);
-      }
-      else {
-	memcpy(out, in, size * 4);
-	return;
-      }
-  }
+                      const uint32_t* in)
+{
+    if (cascade.empty()) {
+        cv::setNumThreads(cvRound(threads * 100));
+        if (classifier.length() == 0 || classifier == old_classifier) {
+            // same as before, avoid repeating error messages
+            memcpy(out, in, size * 4); // of course assuming we are RGBA only
+            return;
+        }
+        old_classifier = classifier;
+    }
+
+    if (!cascade.load(classifier.c_str())) {
+        fprintf(stderr, "ERROR in filter facebl0r, classifier cascade not found:\n");
+        fprintf(stderr, " %s\n", classifier.c_str());
+        memcpy(out, in, size * 4);
+        return;
+    }
 
   // sanitize parameters
   recheck = CLAMP(recheck, 0.001, 1.0);
   search_scale = CLAMP(search_scale, 0.11, 1.0);
   neighbors = CLAMP(neighbors, 0.01, 1.0);
 
-  if( !image )
-      image = cvCreateImage( cvSize(width,height), IPL_DEPTH_8U, 4 );
-
-  memcpy(image->imageData, in, size * 4);
+  // copy input image to OpenCV
+  image = cv::Mat(height, width, CV_8UC4, (void*)in);
+  tracked_obj.update_hue_image(image);
 
   /*
     no face*
@@ -176,27 +152,24 @@ void FaceBl0r::update(double time,
        no face*
    */
   if(face_notfound>0) {
-
+      std::vector<cv::Rect> faces;
       if(face_notfound % cvRound(recheck * 1000) == 0)
-          face_rect = detect_face(image, cascade, storage);
+          faces = detect_face();
 
       // if no face detected
-      if (!face_rect) {
+      if (faces.empty()) {
           face_notfound++;
       } else {
-          //track detected face with camshift
-          if(tracked_obj)
-              destroy_tracked_object(tracked_obj);
-          tracked_obj = create_tracked_object(image, face_rect);
+          tracked_obj.prev_rect = faces[0];
+          tracked_obj.update_hist();
           face_notfound = 0;
           face_found++;
       }
-
   }
 
-  if(face_found>0) { 
+  if (face_found > 0) {
       //track the face in the new frame
-      face_box = camshift_track_face(image, tracked_obj);
+      cv::RotatedRect face_box = tracked_obj.camshift_track_face();
 
       int min = cvRound(smallest * 1000);
           min = min? min : 10;
@@ -210,17 +183,13 @@ void FaceBl0r::update(double time,
           face_notfound++;
       }
       else {
-////////////////////////////////////////////////////////////////////////
-	      cvSetImageROI (image, tracked_obj->prev_rect);
-//          cvSmooth (image, image, CV_BLUR, 22, 22, 0, 0);
-		  cvSmooth (image, image, CV_BLUR, 23, 23, 0, 0);
-//          cvSmooth (image, image, CV_GAUSSIAN, 11, 11, 0, 0);
-		  cvResetImageROI (image);
-////////////////////////////////////////////////////////////////////////
-      
+          cv::Rect blur_region = tracked_obj.prev_rect & cv::Rect({0, 0}, image.size());
+          cv::Mat blur(image, blur_region);
+          cv::blur(blur, blur, {23, 23}, cv::Point(-1, -1));
+
           //outline face ellipse
           if (ellipse)
-              cvEllipseBox(image, face_box, CV_RGB(255,0,0), 2, CV_AA, 0);
+              cv::ellipse(image, face_box, CV_RGB(255,0,0), 2, cv::LINE_AA);
 
           face_found++;
           if(face_found % cvRound(recheck * 1000) == 0)
@@ -228,133 +197,76 @@ void FaceBl0r::update(double time,
       }
   }
 
-  memcpy(out, image->imageData, size * 4);
-  cvReleaseImage(&image);
+  memcpy(out, image.data, size * 4);
 }
 
 /* Given an image and a classider, detect and return region. */
-CvRect* FaceBl0r::detect_face (IplImage* image,
-                               CvHaarClassifierCascade* cascade,
-                               CvMemStorage* storage) {
-    
-  CvRect* rect = 0;
-  
-  if (cascade && storage) {
+std::vector<cv::Rect> FaceBl0r::detect_face()
+{
+    if (cascade.empty()) {
+        return std::vector<cv::Rect>();
+    }
+
      //use an equalized gray image for better recognition
-     IplImage* gray = cvCreateImage(cvSize(image->width, image->height), 8, 1);
-     cvCvtColor(image, gray, CV_BGR2GRAY);
-     cvEqualizeHist(gray, gray);
-     cvClearMemStorage(storage);
+     cv::Mat gray;
+     cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
+     cv::equalizeHist(gray, gray);
 
       //get a sequence of faces in image
       int min = cvRound(smallest * 1000);
-      CvSeq *faces = cvHaarDetectObjects(gray, cascade, storage,
+      std::vector<cv::Rect> faces;
+      cascade.detectMultiScale(gray, faces,
          search_scale * 10.0,
          cvRound(neighbors * 100),
-         CV_HAAR_FIND_BIGGEST_OBJECT|//since we track only the first, get the biggest
-         CV_HAAR_DO_CANNY_PRUNING,  //skip regions unlikely to contain a face
-         cvSize(min, min));
-    
-      //if one or more faces are detected, return the first one
-      if(faces && faces->total)
-        rect = (CvRect*) cvGetSeqElem(faces, 0);
-
-      cvReleaseImage(&gray);
-  }
+         cv::CASCADE_FIND_BIGGEST_OBJECT|//since we track only the first, get the biggest
+         cv::CASCADE_DO_CANNY_PRUNING,  //skip regions unlikely to contain a face
+         cv::Size(min, min));
 
-  return rect;
+    return faces;
 }
 
-/* Create a camshift tracked object from a region in image. */
-TrackedObj* FaceBl0r::create_tracked_object (IplImage* image, CvRect* region) {
-  TrackedObj* obj;
-  
-  //allocate memory for tracked object struct
-  if((obj = (TrackedObj *) malloc(sizeof *obj)) != NULL) {
-    //create-image: size(w,h), bit depth, channels
-    obj->hsv  = cvCreateImage(cvGetSize(image), 8, 3);
-    obj->mask = cvCreateImage(cvGetSize(image), 8, 1);
-    obj->hue  = cvCreateImage(cvGetSize(image), 8, 1);
-    obj->prob = cvCreateImage(cvGetSize(image), 8, 1);
-
-    int hist_bins = 30;           //number of histogram bins
-    float hist_range[] = {0,180}; //histogram range
-    float* range = hist_range;
-    obj->hist = cvCreateHist(1,             //number of hist dimensions
-                             &hist_bins,    //array of dimension sizes
-                             CV_HIST_ARRAY, //representation format
-                             &range,        //array of ranges for bins
-                             1);            //uniformity flag
-  }
-  
-  //create a new hue image
-  update_hue_image(image, obj);
-
-  float max_val = 0.f;
-  
+void TrackedObj::update_hist()
+{
   //create a histogram representation for the face
-  cvSetImageROI(obj->hue, *region);
-  cvSetImageROI(obj->mask, *region);
-  cvCalcHist(&obj->hue, obj->hist, 0, obj->mask);
-  cvGetMinMaxHistValue(obj->hist, 0, &max_val, 0, 0 );
-  cvConvertScale(obj->hist->bins, obj->hist->bins,
-                 max_val ? 255.0/max_val : 0, 0);
-  cvResetImageROI(obj->hue);
-  cvResetImageROI(obj->mask);
-  
-  //store the previous face location
-  obj->prev_rect = *region;
-
-  return obj;
-}
-
-/* Release resources from tracked object. */
-void FaceBl0r::destroy_tracked_object (TrackedObj* obj) {
-  cvReleaseImage(&obj->hsv);
-  cvReleaseImage(&obj->hue);
-  cvReleaseImage(&obj->mask);
-  cvReleaseImage(&obj->prob);
-  cvReleaseHist(&obj->hist);
+  cv::Mat hue_roi(hue, prev_rect);
+  cv::Mat mask_roi(mask, prev_rect);
 
-  free(obj);
+  const float* range = hist_range;
+  cv::calcHist(&hue_roi, 1, nullptr, mask_roi, hist, 1, &hist_bins, &range);
+  normalize(hist, hist, 0, 255, cv::NORM_MINMAX);
 }
 
 /* Given an image and tracked object, return box position. */
-CvBox2D FaceBl0r::camshift_track_face (IplImage* image, TrackedObj* obj) {
-  CvConnectedComp components;
-
-  //create a new hue image
-  update_hue_image(image, obj);
-
+cv::RotatedRect TrackedObj::camshift_track_face()
+{
   //create a probability image based on the face histogram
-  cvCalcBackProject(&obj->hue, obj->prob, obj->hist);
-  cvAnd(obj->prob, obj->mask, obj->prob, 0);
+  const float* range = hist_range;
+  cv::calcBackProject(&hue, 1, nullptr, hist, prob, &range);
+  prob &= mask;
 
   //use CamShift to find the center of the new face probability
-  cvCamShift(obj->prob, obj->prev_rect,
-             cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1),
-             &components, &obj->curr_box);
+  cv::RotatedRect curr_box = CamShift(prob, prev_rect,
+    cv::TermCriteria(cv::TermCriteria::EPS | cv::TermCriteria::MAX_ITER, 10, 1 ));
 
-  //update face location and angle
-  obj->prev_rect = components.rect;
-  obj->curr_box.angle = -obj->curr_box.angle;
+  //update face location
+  prev_rect = curr_box.boundingRect();
 
-  return obj->curr_box;
+  return curr_box;
 }
 
-void FaceBl0r::update_hue_image (const IplImage* image, TrackedObj* obj) {
+void TrackedObj::update_hue_image (const cv::Mat& image) {
   //limits for calculating hue
   int vmin = 65, vmax = 256, smin = 55;
-  
+
   //convert to HSV color model
-  cvCvtColor(image, obj->hsv, CV_BGR2HSV);
-  
+  cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);
+
   //mask out-of-range values
-  cvInRangeS(obj->hsv,                               //source
-             cvScalar(0, smin, MIN(vmin, vmax), 0),  //lower bound
-             cvScalar(180, 256, MAX(vmin, vmax) ,0), //upper bound
-             obj->mask);                             //destination
-  
+  cv::inRange(hsv,                           //source
+      cv::Scalar(0, smin, MIN(vmin, vmax)),  //lower bound
+      cv::Scalar(180, 256, MAX(vmin, vmax)), //upper bound
+      mask);                                 //destination
+
   //extract the hue channel, split: src, dest channels
-  cvSplit(obj->hsv, obj->hue, 0, 0, 0 );
+  cv::extractChannel(hsv, hue, 0);
 }
diff --git a/src/filter/facedetect/facedetect.cpp b/src/filter/facedetect/facedetect.cpp
index 1906962..580b53b 100644
--- a/src/filter/facedetect/facedetect.cpp
+++ b/src/filter/facedetect/facedetect.cpp
@@ -148,13 +148,13 @@ class FaceDetect: public frei0r::filter
             count = 1;   // reset the recheck counter
             if (objects.size() > 0) // reset the list of objects
                 objects.clear();
-            double elapsed = (double) cvGetTickCount();
+            double elapsed = (double) cv::getTickCount();
 
             objects = detect();
 
             // use detection time to throttle frequency of re-detect vs. redraw (automatic recheck)
-            elapsed = cvGetTickCount() - elapsed;
-            elapsed = elapsed / ((double) cvGetTickFrequency() * 1000.0);
+            elapsed = cv::getTickCount() - elapsed;
+            elapsed = elapsed / ((double) cv::getTickFrequency() * 1000.0);
 
             // Automatic recheck uses an undocumented negative parameter value,
             // which is not compliant, but technically feasible.
@@ -188,7 +188,7 @@ class FaceDetect: public frei0r::filter
         }
 
         // use an equalized grayscale to improve detection
-        cv::cvtColor(image_roi, gray, CV_BGR2GRAY);
+        cv::cvtColor(image_roi, gray, cv::COLOR_BGR2GRAY);
 
         // use a smaller image to improve performance
         cv::resize(gray, small, cv::Size(cvRound(gray.cols * scale), cvRound(gray.rows * scale)));
@@ -249,8 +249,8 @@ class FaceDetect: public frei0r::filter
         {
             cv::Rect* r = (cv::Rect*) &objects[i];
             cv::Point center;
-            int thickness = stroke <= 0? CV_FILLED : cvRound(stroke * 100);
-            int linetype = antialias? CV_AA : 8;
+            int thickness = stroke <= 0? cv::FILLED : cvRound(stroke * 100);
+            int linetype = antialias? cv::LINE_AA : 8;
             
             center.x = cvRound((r->x + r->width * 0.5) / scale);
             center.y = cvRound((r->y + r->height * 0.5) / scale);
diff --git a/src/filter/medians/medians.c b/src/filter/medians/medians.c
old mode 100755
new mode 100644
diff --git a/src/filter/select0r/select0r.c b/src/filter/select0r/select0r.c
old mode 100755
new mode 100644
diff --git a/src/filter/sharpness/sharpness.c b/src/filter/sharpness/sharpness.c
old mode 100755
new mode 100644
