header: #pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace grip { /** * A representation of the different types of blurs that can be used. * */ enum BlurType { BOX, GAUSSIAN, MEDIAN, BILATERAL }; /** * GellowRect class. * * An OpenCV pipeline generated by GRIP. */ class GellowRect { private: cv::Mat hsvThresholdOutput; cv::Mat maskOutput; cv::Mat blurOutput; std::vector > findContoursOutput; std::vector > filterContoursOutput; std::vector > convexHullsOutput; void hsvThreshold(cv::Mat &, double [], double [], double [], cv::Mat &); void mask(cv::Mat &, cv::Mat &, cv::Mat &); void blur(cv::Mat &, BlurType &, double , cv::Mat &); void findContours(cv::Mat &, bool , std::vector > &); void filterContours(std::vector > &, double , double , double , double , double , double , double [], double , double , double , double , std::vector > &); void convexHulls(std::vector > &, std::vector > &); public: GellowRect(); void Process(cv::Mat& source0); cv::Mat* GetHsvThresholdOutput(); cv::Mat* GetMaskOutput(); cv::Mat* GetBlurOutput(); std::vector >* GetFindContoursOutput(); std::vector >* GetFilterContoursOutput(); std::vector >* GetConvexHullsOutput(); }; } // end namespace grip cpp file: #include "GellowRect.h" namespace grip { GellowRect::GellowRect() { } /** * Runs an iteration of the pipeline and updates outputs. */ void GellowRect::Process(cv::Mat& source0){ //Step HSV_Threshold0: //input cv::Mat hsvThresholdInput = source0; double hsvThresholdHue[] = {24.280575539568343, 38.703071672354945}; double hsvThresholdSaturation[] = {87.14028776978417, 255.0}; double hsvThresholdValue[] = {119.24460431654676, 255.0}; hsvThreshold(hsvThresholdInput, hsvThresholdHue, hsvThresholdSaturation, hsvThresholdValue, this->hsvThresholdOutput); //Step Mask0: //input cv::Mat maskInput = source0; cv::Mat maskMask = hsvThresholdOutput; mask(maskInput, maskMask, this->maskOutput); //Step Blur0: //input cv::Mat blurInput = hsvThresholdOutput; BlurType blurType = BlurType::MEDIAN; double blurRadius = 8.108108108108109; // default Double blur(blurInput, blurType, blurRadius, this->blurOutput); //Step Find_Contours0: //input cv::Mat findContoursInput = blurOutput; bool findContoursExternalOnly = false; // default Boolean findContours(findContoursInput, findContoursExternalOnly, this->findContoursOutput); //Step Filter_Contours0: //input std::vector > filterContoursContours = findContoursOutput; double filterContoursMinArea = 1000.0; // default Double double filterContoursMinPerimeter = 0.0; // default Double double filterContoursMinWidth = 0.0; // default Double double filterContoursMaxWidth = 1000.0; // default Double double filterContoursMinHeight = 0.0; // default Double double filterContoursMaxHeight = 1000.0; // default Double double filterContoursSolidity[] = {75.31760435571687, 100}; double filterContoursMaxVertices = 1000000.0; // default Double double filterContoursMinVertices = 0.0; // default Double double filterContoursMinRatio = 0.0; // default Double double filterContoursMaxRatio = 1000.0; // default Double filterContours(filterContoursContours, filterContoursMinArea, filterContoursMinPerimeter, filterContoursMinWidth, filterContoursMaxWidth, filterContoursMinHeight, filterContoursMaxHeight, filterContoursSolidity, filterContoursMaxVertices, filterContoursMinVertices, filterContoursMinRatio, filterContoursMaxRatio, this->filterContoursOutput); //Step Convex_Hulls0: //input std::vector > convexHullsContours = filterContoursOutput; convexHulls(convexHullsContours, this->convexHullsOutput); } /** * This method is a generated getter for the output of a HSV_Threshold. * @return Mat output from HSV_Threshold. */ cv::Mat* GellowRect::GetHsvThresholdOutput(){ return &(this->hsvThresholdOutput); } /** * This method is a generated getter for the output of a Mask. * @return Mat output from Mask. */ cv::Mat* GellowRect::GetMaskOutput(){ return &(this->maskOutput); } /** * This method is a generated getter for the output of a Blur. * @return Mat output from Blur. */ cv::Mat* GellowRect::GetBlurOutput(){ return &(this->blurOutput); } /** * This method is a generated getter for the output of a Find_Contours. * @return ContoursReport output from Find_Contours. */ std::vector >* GellowRect::GetFindContoursOutput(){ return &(this->findContoursOutput); } /** * This method is a generated getter for the output of a Filter_Contours. * @return ContoursReport output from Filter_Contours. */ std::vector >* GellowRect::GetFilterContoursOutput(){ return &(this->filterContoursOutput); } /** * This method is a generated getter for the output of a Convex_Hulls. * @return ContoursReport output from Convex_Hulls. */ std::vector >* GellowRect::GetConvexHullsOutput(){ return &(this->convexHullsOutput); } /** * Segment an image based on hue, saturation, and value ranges. * * @param input The image on which to perform the HSL threshold. * @param hue The min and max hue. * @param sat The min and max saturation. * @param val The min and max value. * @param output The image in which to store the output. */ void GellowRect::hsvThreshold(cv::Mat &input, double hue[], double sat[], double val[], cv::Mat &out) { cv::cvtColor(input, out, cv::COLOR_BGR2HSV); cv::inRange(out,cv::Scalar(hue[0], sat[0], val[0]), cv::Scalar(hue[1], sat[1], val[1]), out); } /** * Filter out an area of an image using a binary mask. * * @param input The image on which the mask filters. * @param mask The binary image that is used to filter. * @param output The image in which to store the output. */ void GellowRect::mask(cv::Mat &input, cv::Mat &mask, cv::Mat &output) { mask.convertTo(mask, CV_8UC1); cv::bitwise_xor(output, output, output); input.copyTo(output, mask); } /** * Softens an image using one of several filters. * * @param input The image on which to perform the blur. * @param type The blurType to perform. * @param doubleRadius The radius for the blur. * @param output The image in which to store the output. */ void GellowRect::blur(cv::Mat &input, BlurType &type, double doubleRadius, cv::Mat &output) { int radius = (int)(doubleRadius + 0.5); int kernelSize; switch(type) { case BOX: kernelSize = 2 * radius + 1; cv::blur(input,output,cv::Size(kernelSize, kernelSize)); break; case GAUSSIAN: kernelSize = 6 * radius + 1; cv::GaussianBlur(input, output, cv::Size(kernelSize, kernelSize), radius); break; case MEDIAN: kernelSize = 2 * radius + 1; cv::medianBlur(input, output, kernelSize); break; case BILATERAL: cv::bilateralFilter(input, output, -1, radius, radius); break; } } /** * Finds contours in an image. * * @param input The image to find contours in. * @param externalOnly if only external contours are to be found. * @param contours vector of contours to put contours in. */ void GellowRect::findContours(cv::Mat &input, bool externalOnly, std::vector > &contours) { std::vector hierarchy; contours.clear(); int mode = externalOnly ? cv::RETR_EXTERNAL : cv::RETR_LIST; int method = cv::CHAIN_APPROX_SIMPLE; cv::findContours(input, contours, hierarchy, mode, method); } /** * Filters through contours. * @param inputContours is the input vector of contours. * @param minArea is the minimum area of a contour that will be kept. * @param minPerimeter is the minimum perimeter of a contour that will be kept. * @param minWidth minimum width of a contour. * @param maxWidth maximum width. * @param minHeight minimum height. * @param maxHeight maximimum height. * @param solidity the minimum and maximum solidity of a contour. * @param minVertexCount minimum vertex Count of the contours. * @param maxVertexCount maximum vertex Count. * @param minRatio minimum ratio of width to height. * @param maxRatio maximum ratio of width to height. * @param output vector of filtered contours. */ void GellowRect::filterContours(std::vector > &inputContours, double minArea, double minPerimeter, double minWidth, double maxWidth, double minHeight, double maxHeight, double solidity[], double maxVertexCount, double minVertexCount, double minRatio, double maxRatio, std::vector > &output) { std::vector hull; output.clear(); for (std::vector contour: inputContours) { cv::Rect bb = boundingRect(contour); if (bb.width < minWidth || bb.width > maxWidth) continue; if (bb.height < minHeight || bb.height > maxHeight) continue; double area = cv::contourArea(contour); if (area < minArea) continue; if (arcLength(contour, true) < minPerimeter) continue; cv::convexHull(cv::Mat(contour, true), hull); double solid = 100 * area / cv::contourArea(hull); if (solid < solidity[0] || solid > solidity[1]) continue; if (contour.size() < minVertexCount || contour.size() > maxVertexCount) continue; double ratio = (double) bb.width / (double) bb.height; if (ratio < minRatio || ratio > maxRatio) continue; output.push_back(contour); } } /** * Compute the convex hulls of contours. * * @param inputContours The contours on which to perform the operation. * @param outputContours The contours where the output will be stored. */ void GellowRect::convexHulls(std::vector > &inputContours, std::vector > &outputContours) { std::vector > hull (inputContours.size()); outputContours.clear(); for (size_t i = 0; i < inputContours.size(); i++ ) { cv::convexHull(cv::Mat((inputContours)[i]), hull[i], false); } outputContours = hull; } } // end grip namespace