summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--media-plugins/frei0r-plugins/Manifest1
-rw-r--r--media-plugins/frei0r-plugins/files/ocv4.patch368
-rw-r--r--media-plugins/frei0r-plugins/frei0r-plugins-1.7.0.ebuild63
3 files changed, 432 insertions, 0 deletions
diff --git a/media-plugins/frei0r-plugins/Manifest b/media-plugins/frei0r-plugins/Manifest
index c172fc28be6c..09f3285d7d1d 100644
--- a/media-plugins/frei0r-plugins/Manifest
+++ b/media-plugins/frei0r-plugins/Manifest
@@ -1 +1,2 @@
DIST frei0r-plugins-1.6.1.tar.gz 1103969 BLAKE2B febcfc0a5918834e38c2aad2016c0b72f3fed731732e482ae8f9564bb5c2e0825ce050149f6728a8263d6caef11810b33ee3edfb697b0f8a212ae996e0085f45 SHA512 843790389e6de83817d1c3744a91d3365864bb0c22cf6598707ccba5ec8933f6209434011cde1303e16edd89f6cde2f22aa1fb6eca3548d892a2c77332c44aac
+DIST frei0r-plugins-1.7.0.tar.gz 1214323 BLAKE2B 1b571361ced6dfc29c5b487ee78664995aab615b89ac9a0839254c5fc17ddc7147cf9eb7c2d6df33f518fa96b9761a185dba420037e6c9cdf7d0e70416aab76c SHA512 8c80e8e0ce8c302e633ea1f6ff4e2a141fd7a8bcb7fce25dc7f1f6521be11258a3efa1074c224c7323e6a17bc405413385be193a5c787e2f276252b50477ebce
diff --git a/media-plugins/frei0r-plugins/files/ocv4.patch b/media-plugins/frei0r-plugins/files/ocv4.patch
new file mode 100644
index 000000000000..74194e8174c7
--- /dev/null
+++ b/media-plugins/frei0r-plugins/files/ocv4.patch
@@ -0,0 +1,368 @@
+Index: frei0r-plugins-1.7.0/src/filter/facebl0r/facebl0r.cpp
+===================================================================
+--- frei0r-plugins-1.7.0.orig/src/filter/facebl0r/facebl0r.cpp
++++ frei0r-plugins-1.7.0/src/filter/facebl0r/facebl0r.cpp
+@@ -19,18 +19,20 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <opencv2/opencv.hpp>
++#include <opencv2/core/core_c.h>
++#include <opencv2/imgproc/imgproc_c.h>
+ #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
++ 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
+
+- CvRect prev_rect; //location of face in previous frame
++ cv::Rect prev_rect; //location of face in previous frame
+ CvBox2D curr_box; //current face location estimate
+ } TrackedObj;
+
+@@ -47,23 +49,23 @@ public:
+ private:
+
+ // camshift
+- TrackedObj* create_tracked_object (IplImage* image, CvRect* face_rect);
++ TrackedObj* create_tracked_object (cv::Mat& image, cv::Rect& 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);
++ CvBox2D camshift_track_face (cv::Mat& image, TrackedObj* imgs);
++ void update_hue_image (const cv::Mat& image, TrackedObj* imgs);
+
+ //trackface
+- CvRect* detect_face (IplImage*, CvHaarClassifierCascade*, CvMemStorage*);
++ void detect_face (const cv::Mat&, cv::CascadeClassifier*, cv::Rect& res, bool& found);
+
+
+ TrackedObj* tracked_obj;
+ CvBox2D face_box; //area to draw
+- CvRect* face_rect;
++ cv::Rect face_rect;
+
+ //used by capture_video_frame, so we don't have to keep creating.
+- IplImage* image;
++ cv::Mat image;
+
+- CvHaarClassifierCascade* cascade;
++ cv::CascadeClassifier* cascade;
+ CvMemStorage* storage;
+
+ // plugin parameters
+@@ -89,17 +91,17 @@ frei0r::construct<FaceBl0r> plugin("Face
+ "ZioKernel, Biilly, Jilt, Jaromil, ddennedy",
+ 1,1, F0R_COLOR_MODEL_PACKED32);
+
+-FaceBl0r::FaceBl0r(int wdt, int hgt) {
++FaceBl0r::FaceBl0r(int wdt, int hgt):
++ image(wdt, hgt, CV_8UC4)
++{
+
+- face_rect = 0;
+- image = 0;
+ tracked_obj = 0;
+ face_found = 0;
+
+ cascade = 0;
+ storage = 0;
+
+- classifier = "/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml";
++ classifier = "/usr/share/opencv4/haarcascades/haarcascade_frontalface_default.xml";
+ register_param(classifier,
+ "Classifier",
+ "Full path to the XML pattern model for recognition; look in /usr/share/opencv/haarcascades");
+@@ -124,7 +126,7 @@ FaceBl0r::~FaceBl0r() {
+ if(tracked_obj)
+ destroy_tracked_object(tracked_obj);
+
+- if(cascade) cvReleaseHaarClassifierCascade(&cascade);
++ if(cascade) delete cascade;
+ if(storage) cvReleaseMemStorage(&storage);
+
+ }
+@@ -142,7 +144,7 @@ void FaceBl0r::update(double time,
+ return;
+ } else old_classifier = classifier;
+
+- cascade = (CvHaarClassifierCascade*) cvLoad(classifier.c_str(), 0, 0, 0 );
++ cascade = new cv::CascadeClassifier(classifier);
+ if (!cascade) {
+ fprintf(stderr, "ERROR in filter facebl0r, classifier cascade not found:\n");
+ fprintf(stderr, " %s\n", classifier.c_str());
+@@ -162,10 +164,7 @@ void FaceBl0r::update(double time,
+ 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);
++ memcpy(image.data, in, size * 4);
+
+ /*
+ no face*
+@@ -176,12 +175,15 @@ void FaceBl0r::update(double time,
+ no face*
+ */
+ if(face_notfound>0) {
++ bool found = false;
+
+ if(face_notfound % cvRound(recheck * 1000) == 0)
+- face_rect = detect_face(image, cascade, storage);
++ {
++ detect_face(image, cascade, face_rect, found);
++ }
+
+ // if no face detected
+- if (!face_rect) {
++ if (!found) {
+ face_notfound++;
+ } else {
+ //track detected face with camshift
+@@ -211,16 +213,17 @@ void FaceBl0r::update(double time,
+ }
+ else {
+ ////////////////////////////////////////////////////////////////////////
+- cvSetImageROI (image, tracked_obj->prev_rect);
++ cv::Mat roi = image(tracked_obj->prev_rect);
+ // cvSmooth (image, image, CV_BLUR, 22, 22, 0, 0);
+- cvSmooth (image, image, CV_BLUR, 23, 23, 0, 0);
++ cv::blur (roi, roi, cv::Size(23,23));
+ // cvSmooth (image, image, CV_GAUSSIAN, 11, 11, 0, 0);
+- cvResetImageROI (image);
+ ////////////////////////////////////////////////////////////////////////
+
+ //outline face ellipse
+- if (ellipse)
+- cvEllipseBox(image, face_box, CV_RGB(255,0,0), 2, CV_AA, 0);
++ if (ellipse) {
++ CvSize axes = cvSize(face_box.size.width*0.5, face_box.size.height*0.5);
++ cv::ellipse(image, cvPointFrom32f(face_box.center), axes, face_box.angle, 0, 360, CV_RGB(255,0,0), 2, CV_AA, 0);
++ }
+
+ face_found++;
+ if(face_found % cvRound(recheck * 1000) == 0)
+@@ -228,133 +231,121 @@ 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) {
++void FaceBl0r::detect_face (const cv::Mat& image,
++ cv::CascadeClassifier* cascade,
++ cv::Rect& res,
++ bool& found) {
+
+- CvRect* rect = 0;
+-
+- if (cascade && storage) {
++ if (cascade) {
+ //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);
++ //IplImage* gray = cvCreateImage(cvSize(image->width, image->height), 8, 1);
++ 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 > objects;
++ std::vector< int > numDetections;
++ cascade->detectMultiScale(gray, objects, numDetections,
+ 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
++ 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
+ 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);
++ if(!objects.empty())
++ {
++ res = objects[0];
++ found = true;
++ }
+ }
+-
+- return rect;
+ }
+
+ /* Create a camshift tracked object from a region in image. */
+-TrackedObj* FaceBl0r::create_tracked_object (IplImage* image, CvRect* region) {
++TrackedObj* FaceBl0r::create_tracked_object (cv::Mat& image, cv::Rect& region) {
+ TrackedObj* obj;
+
++ int hist_bins = 30; //number of histogram bins
++ float hist_range[] = {0,180}; //histogram range
++ const float* range = hist_range;
++ const int channels[] = {0, 1, 2};
++
+ //allocate memory for tracked object struct
+- if((obj = (TrackedObj *) malloc(sizeof *obj)) != NULL) {
++ if((obj = new TrackedObj()) != 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
++ obj->hsv.create(image.size(), CV_8UC3);
++ obj->mask.create(image.size(), CV_8UC1);
++ obj->hue.create(image.size(), CV_8UC1);
++ obj->prob.create(image.size(), CV_8UC1);
+ }
+
+ //create a new hue image
+ update_hue_image(image, obj);
+
+- float max_val = 0.f;
++ double max_val = 0.f;
++ double min_val = 0.f;
+
+ //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);
++ cv::Mat hueroi = obj->hue(region);
++ cv::Mat maskroi = obj->mask(region);
++ cv::calcHist(&obj->hue, 1, channels, obj->mask, obj->hist, 1, &hist_bins, &range);
++ cv::minMaxIdx(obj->hist, &min_val, &max_val);
++ obj->hist = (max_val ? 255.0/max_val : 0) * obj->hist;
+
+ //store the previous face location
+- obj->prev_rect = *region;
++ 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);
+-
+- free(obj);
++ delete obj;
+ }
+
+ /* Given an image and tracked object, return box position. */
+-CvBox2D FaceBl0r::camshift_track_face (IplImage* image, TrackedObj* obj) {
+- CvConnectedComp components;
+-
++CvBox2D FaceBl0r::camshift_track_face (cv::Mat& image, TrackedObj* obj) {
+ //create a new hue image
+ update_hue_image(image, obj);
+
+ //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 int channels[] = {0, 1, 2};
++ float hist_range[] = {0,180}; //histogram range
++ const float* range = hist_range;
++ cv::calcBackProject(&obj->hue, 1, channels, obj->hist, obj->prob, &range);
++ obj->prob = obj->prob & obj->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 rrect = cv::CamShift(obj->prob, obj->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;
++ obj->prev_rect = rrect.boundingRect();
++ obj->curr_box = cvBox2D(rrect);
++ obj->curr_box.angle = -rrect.angle;
+
+ return obj->curr_box;
+ }
+
+-void FaceBl0r::update_hue_image (const IplImage* image, TrackedObj* obj) {
++void FaceBl0r::update_hue_image (const cv::Mat& image, TrackedObj* obj) {
+ //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, obj->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
++ cv::inRange(obj->hsv, //source
++ cv::Scalar(0, smin, MIN(vmin, vmax), 0), //lower bound
++ cv::Scalar(180, 256, MAX(vmin, vmax) ,0), //upper bound
+ obj->mask); //destination
+
+ //extract the hue channel, split: src, dest channels
+- cvSplit(obj->hsv, obj->hue, 0, 0, 0 );
++ cv::split(obj->hsv, obj->hue);
+ }
+Index: frei0r-plugins-1.7.0/src/filter/facedetect/facedetect.cpp
+===================================================================
+--- frei0r-plugins-1.7.0.orig/src/filter/facedetect/facedetect.cpp
++++ frei0r-plugins-1.7.0/src/filter/facedetect/facedetect.cpp
+@@ -21,6 +21,8 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <opencv2/opencv.hpp>
++#include <opencv2/core/core_c.h>
++#include <opencv2/imgproc/imgproc_c.h>
+ #include "frei0r.hpp"
+ #include "frei0r_math.h"
+
+@@ -65,7 +67,7 @@ public:
+ {
+ roi.width = roi.height = 0;
+ roi.x = roi.y = 0;
+- classifier = "/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml";
++ classifier = "/usr/share/opencv4/haarcascades/haarcascade_frontalface_default.xml";
+ register_param(classifier,
+ "Classifier",
+ "Full path to the XML pattern model for recognition; look in /usr/share/opencv/haarcascades");
diff --git a/media-plugins/frei0r-plugins/frei0r-plugins-1.7.0.ebuild b/media-plugins/frei0r-plugins/frei0r-plugins-1.7.0.ebuild
new file mode 100644
index 000000000000..0e6381b47c79
--- /dev/null
+++ b/media-plugins/frei0r-plugins/frei0r-plugins-1.7.0.ebuild
@@ -0,0 +1,63 @@
+# Copyright 1999-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+CMAKE_ECLASS=cmake
+inherit cmake-multilib
+
+DESCRIPTION="A minimalistic plugin API for video effects"
+HOMEPAGE="https://www.dyne.org/software/frei0r/"
+SRC_URI="https://files.dyne.org/frei0r/releases/${P}.tar.gz"
+
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="~amd64 ~arm ~arm64 ~hppa ~ppc ~ppc64 ~x86"
+IUSE="doc +facedetect +scale0tilt"
+
+RDEPEND="x11-libs/cairo[${MULTILIB_USEDEP}]
+ facedetect? ( >=media-libs/opencv-2.3.0:=[${MULTILIB_USEDEP}] )
+ scale0tilt? ( >=media-libs/gavl-1.2.0[${MULTILIB_USEDEP}] )"
+DEPEND="${RDEPEND}"
+BDEPEND="
+ virtual/pkgconfig
+ doc? ( app-doc/doxygen )"
+
+DOCS=( AUTHORS.txt ChangeLog.txt README.txt TODO.txt )
+PATCHES=( "${FILESDIR}/ocv4.patch" )
+
+src_prepare() {
+ cmake_src_prepare
+
+ local f=CMakeLists.txt
+
+ sed -i \
+ -e '/set(CMAKE_C_FLAGS/d' \
+ -e "/LIBDIR.*frei0r-1/s:lib:$(get_libdir):" \
+ ${f} || die
+
+ # https://bugs.gentoo.org/418243
+ sed -i \
+ -e '/set.*CMAKE_C_FLAGS/s:"): ${CMAKE_C_FLAGS}&:' \
+ src/filter/*/${f} || die
+}
+
+src_configure() {
+ cmake-multilib_src_configure \
+ "-DWITHOUT_OPENCV=$(usex !facedetect)" \
+ "-DWITHOUT_GAVL=$(usex !scale0tilt)"
+}
+
+src_compile() {
+ cmake-multilib_src_compile
+
+ if use doc; then
+ pushd doc
+ doxygen || die
+ popd
+ fi
+}
+
+multilib_src_install_all() {
+ use doc && dodoc -r doc/html
+}