/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright 2012 The MITRE Corporation * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include using namespace cv; using namespace br; /*! * \ingroup transforms * \brief Applies an eliptical mask * \author Josh Klontz \cite jklontz */ class Mask : public UntrainableTransform { Q_OBJECT void project(const Template &src, Template &dst) const { const Mat &m = src; Mat mask(m.size(), CV_8UC1); mask.setTo(1); const float SCALE = 1.1; ellipse(mask, RotatedRect(Point2f(m.cols/2, m.rows/2), Size2f(SCALE*m.cols, SCALE*m.rows), 0), 0, -1); dst = m.clone(); dst.m().setTo(0, mask); } }; BR_REGISTER(Transform, Mask) /*! * \ingroup transforms * \brief Masks image according to pixel change. * \author Josh Klontz \cite jklontz */ class GradientMask : public UntrainableTransform { Q_OBJECT Q_PROPERTY(int delta READ get_delta WRITE set_delta RESET reset_delta STORED false) BR_PROPERTY(int, delta, 1) void project(const Template &src, Template &dst) const { const Mat &m = src.m(); if (m.type() != CV_8UC1) qFatal("GradientMask operates on 8UC1 matrices."); Mat n = Mat(m.rows, m.cols, CV_8UC1); n.setTo(255); for (int i=0; i0) && (abs(m.at(i-1,j)-m.at(i,j)) > delta)) { n.at(i,j) = 0; continue; } if ((j+1(i,j+1)-m.at(i,j)) > delta)) { n.at(i,j) = 0; continue; } if ((i+1(i+1,j)-m.at(i,j)) > delta)) { n.at(i,j) = 0; continue; } if ((j>0) && (abs(m.at(i,j-1)-m.at(i,j)) > delta)) { n.at(i,j) = 0; continue; } } } dst = n; } }; BR_REGISTER(Transform, GradientMask) /*! * \ingroup transforms * \brief http://worldofcameras.wordpress.com/tag/skin-detection-opencv/ * \author Josh Klontz \cite jklontz */ class SkinMask : public UntrainableTransform { Q_OBJECT void project(const Template &src, Template &dst) const { Mat m; cvtColor(src, m, CV_BGR2YCrCb); std::vector mv; split(m, mv); Mat mask = Mat(m.rows, m.cols, CV_8UC1); for (int i=0; i(i,j); int Cb =mv[2].at(i,j); mask.at(i, j) = (Cr>130 && Cr<170) && (Cb>70 && Cb<125) ? 255 : 0; } } dst = mask; } }; BR_REGISTER(Transform, SkinMask) /*! * \ingroup transforms * \brief Morphological operator * \author Josh Klontz \cite jklontz */ class Morph : public UntrainableTransform { Q_OBJECT Q_ENUMS(Op) Q_PROPERTY(Op op READ get_op WRITE set_op RESET reset_op STORED false) Q_PROPERTY(int radius READ get_radius WRITE set_radius RESET reset_radius STORED false) public: /*!< */ enum Op { Erode = MORPH_ERODE, Dilate = MORPH_DILATE, Open = MORPH_OPEN, Close = MORPH_CLOSE, Gradient = MORPH_GRADIENT, TopHat = MORPH_TOPHAT, BlackHat = MORPH_BLACKHAT }; private: BR_PROPERTY(Op, op, Close) BR_PROPERTY(int, radius, 1) Mat kernel; void init() { Mat kernel = Mat(radius, radius, CV_8UC1); kernel.setTo(255); } void project(const Template &src, Template &dst) const { morphologyEx(src, dst, op, kernel); } }; BR_REGISTER(Transform, Morph) /*! * \ingroup transforms * \brief Set the template's label to the area of the largest convex hull. * \author Josh Klontz \cite jklontz */ class LargestConvexArea : public UntrainableTransform { Q_OBJECT void project(const Template &src, Template &dst) const { std::vector< std::vector > contours; findContours(src.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); double maxArea = 0; foreach (const std::vector &contour, contours) { std::vector hull; convexHull(contour, hull); double area = contourArea(contour); double hullArea = contourArea(hull); if (area / hullArea > 0.98) maxArea = std::max(maxArea, area); } dst.file.setLabel(maxArea); } }; BR_REGISTER(Transform, LargestConvexArea) #include "mask.moc"