/** * * @author greg (at) myrobotlab.org * * This file is part of MyRobotLab (http://myrobotlab.org). * * MyRobotLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version (subject to the "Classpath" exception * as provided in the LICENSE.txt file that accompanied this code). * * MyRobotLab is distributed in the hope that it will be useful or fun, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * All libraries in thirdParty bundle are subject to their own license * requirements - please refer to http://myrobotlab.org/libraries for * details. * * Enjoy ! * * */ package org.myrobotlab.opencv; import static org.bytedeco.javacpp.opencv_core.cvAnd; import static org.bytedeco.javacpp.opencv_core.cvCopy; import static org.bytedeco.javacpp.opencv_core.cvCreateImage; import static org.bytedeco.javacpp.opencv_core.cvGetSize; import static org.bytedeco.javacpp.opencv_core.cvInRangeS; import static org.bytedeco.javacpp.opencv_core.cvScalar; import static org.bytedeco.javacpp.opencv_core.cvSetImageCOI; import static org.bytedeco.javacpp.opencv_imgproc.CV_BGR2HSV; import static org.bytedeco.javacpp.opencv_imgproc.cvCvtColor; import java.awt.Color; import java.awt.image.BufferedImage; import org.bytedeco.javacpp.opencv_core.CvScalar; import org.bytedeco.javacpp.opencv_core.IplImage; import org.myrobotlab.logging.LoggerFactory; import org.myrobotlab.service.OpenCV; import org.slf4j.Logger; public class OpenCVFilterInRange extends OpenCVFilter { private static final long serialVersionUID = 1L; public final static Logger log = LoggerFactory.getLogger(OpenCVFilterInRange.class.getCanonicalName()); // http://cgi.cse.unsw.edu.au/~cs4411/wiki/index.php?title=OpenCV_Guide#Calculating_color_histograms int useMask = 0; public final static int HUE_MASK = 1; public final static int VALUE_MASK = 2; public final static int SATURATION_MASK = 4; public boolean useHue = false; public float hueMinValue = 0.0f; public float hueMaxValue = 256.0f; public boolean useValue = false; public float valueMinValue = 0.0f; public float valueMaxValue = 256.0f; public boolean useSaturation = false; public float saturationMinValue = 0.0f; public float saturationMaxValue = 256.0f; transient IplImage hsv = null; transient IplImage hue = null; transient IplImage hueMask = null; transient IplImage value = null; transient IplImage valueMask = null; transient IplImage saturation = null; transient IplImage saturationMask = null; transient IplImage temp = null; transient IplImage mask = null; transient IplImage ret = null; transient BufferedImage frameBuffer = null; transient CvScalar hueMin = cvScalar(hueMinValue, 0.0, 0.0, 0.0); transient CvScalar hueMax = cvScalar(hueMaxValue, 0.0, 0.0, 0.0); transient CvScalar valueMin = cvScalar(valueMinValue, 0.0, 0.0, 0.0); transient CvScalar valueMax = cvScalar(valueMaxValue, 0.0, 0.0, 0.0); transient CvScalar saturationMin = cvScalar(saturationMinValue, 0.0, 0.0, 0.0); transient CvScalar saturationMax = cvScalar(saturationMaxValue, 0.0, 0.0, 0.0); public OpenCVFilterInRange() { super(); } public OpenCVFilterInRange(String name) { super(name); } @Override public void imageChanged(IplImage image) { // TODO Auto-generated method stub } @Override public IplImage process(IplImage image, OpenCVData data) { ret = image; if (hsv == null) { hsv = cvCreateImage(cvGetSize(image), 8, 3); hue = cvCreateImage(cvGetSize(image), 8, 1); hueMask = cvCreateImage(cvGetSize(image), 8, 1); value = cvCreateImage(cvGetSize(image), 8, 1); valueMask = cvCreateImage(cvGetSize(image), 8, 1); saturation = cvCreateImage(cvGetSize(image), 8, 1); saturationMask = cvCreateImage(cvGetSize(image), 8, 1); temp = cvCreateImage(cvGetSize(image), 8, 1); mask = cvCreateImage(cvGetSize(image), 8, 1); } // load up desired mask case useMask = useSaturation ? 1 : 0; useMask = useMask << 1; useMask = useMask | (useValue ? 1 : 0); useMask = useMask << 1; useMask = useMask | (useHue ? 1 : 0); if (image == null) { log.error("image is null"); } // convert to more stable HSV // cvCvtColor(image, hsv, CV_RGB2HSV); // # 41 // #define CV_BGR2HSV 40 - not defined in javacv // cvResetImageCOI(image);// added reset - still get Input COI is not // supported cvSetImageCOI(hsv, 0); // added reset - still get Input COI is not // supported cvCvtColor(image, hsv, CV_BGR2HSV); if ((useMask & HUE_MASK) == 1) { // copy out hue cvSetImageCOI(hsv, 1); cvCopy(hsv, hue); // cfg values if changed if (hueMin.magnitude() != hueMinValue || hueMax.magnitude() != hueMaxValue) { hueMin = cvScalar(hueMinValue, 0.0, 0.0, 0.0); hueMax = cvScalar(hueMaxValue, 0.0, 0.0, 0.0); } // create hue mask cvInRangeS(hue, hueMin, hueMax, hueMask); } if ((useMask & VALUE_MASK) == 2) { // copy out value cvSetImageCOI(hsv, 3); cvCopy(hsv, value); // look for changed config - update if changed if (valueMin.magnitude() != valueMinValue || valueMax.magnitude() != valueMaxValue) { valueMin = cvScalar(valueMinValue, 0.0, 0.0, 0.0); valueMax = cvScalar(valueMaxValue, 0.0, 0.0, 0.0); } // create value mask cvInRangeS(value, valueMin, valueMax, valueMask); } if ((useMask & SATURATION_MASK) == 4) { // copy out saturation cvSetImageCOI(hsv, 2); cvCopy(hsv, saturation); // look for changed config - update if changed if (saturationMin.magnitude() != saturationMinValue || saturationMax.magnitude() != saturationMaxValue) { saturationMin = cvScalar(saturationMinValue, 0.0, 0.0, 0.0); saturationMax = cvScalar(saturationMaxValue, 0.0, 0.0, 0.0); } // create saturation mask cvInRangeS(saturation, saturationMin, saturationMax, saturationMask); } switch (useMask) { case 0: // !hue !value !sat ret = image; break; case 1: // hue !value !sat ret = hueMask; break; case 2: // !hue value !sat ret = valueMask; break; case 3: // hue value !sat cvAnd(hueMask, valueMask, mask, null); ret = mask; break; case 4: // !hue !value sat ret = saturationMask; break; case 5: // hue !value sat cvAnd(hueMask, saturationMask, mask, null); // cvAnd(saturationMask, hueMask, mask, null); ret = mask; break; case 6: // !hue value sat cvAnd(valueMask, saturationMask, mask, null); ret = mask; break; case 7: // hue value sat cvAnd(hueMask, valueMask, temp, null); cvAnd(temp, saturationMask, mask, null); // ?? ret = mask; break; default: log.error("unknown useMask " + useMask); break; } return ret; } public void samplePoint(Integer x, Integer y) { frameBuffer = OpenCV.IplImageToBufferedImage(hsv); int rgb = frameBuffer.getRGB(x, y); Color c = new Color(rgb); log.error(x + "," + y + " h " + c.getRed() + " s " + c.getGreen() + " v " + c.getBlue()); } }