diff options
author | Antoine Villeret <avilleret@users.sourceforge.net> | 2012-12-07 17:57:13 +0000 |
---|---|---|
committer | Antoine Villeret <avilleret@users.sourceforge.net> | 2012-12-07 17:57:13 +0000 |
commit | 10d9a412a7a5d56e5061f1003d1fc244c7322197 (patch) | |
tree | d3dc04dced0df9894a2cf9d74fb4a46a4b16bb73 /pix_opencv_matchshape.cc | |
parent | bb63849f6bf5a14d7e06daef8da121b1f3150f5e (diff) |
- add contours and matchshape to build process
- update help file
svn path=/trunk/externals/pix_opencv/; revision=16651
Diffstat (limited to 'pix_opencv_matchshape.cc')
-rw-r--r-- | pix_opencv_matchshape.cc | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/pix_opencv_matchshape.cc b/pix_opencv_matchshape.cc new file mode 100644 index 0000000..75dc910 --- /dev/null +++ b/pix_opencv_matchshape.cc @@ -0,0 +1,221 @@ +//////////////////////////////////////////////////////// +// +// GEM - Graphics Environment for Multimedia +// +// zmoelnig@iem.kug.ac.at +// +// Implementation file +// +// Copyright (c) 1997-2000 Mark Danks. +// Copyright (c) Günther Geiger. +// Copyright (c) 2001-2002 IOhannes m zmoelnig. forum::für::umläute. IEM +// Copyright (c) 2002 James Tittle & Chris Clepper +// For information on usage and redistribution, and for a DISCLAIMER OF ALL +// WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution. +// +///////////////////////////////////////////////////////// +// based on code written by Lluis Gomez i Bigorda ( lluisgomez _at_ hangar _dot_ org ) (pix_opencv) +// Template for pix_opencv class + +#include "pix_opencv_matchshape.h" +#include <stdio.h> +#include <RTE/MessageCallbacks.h> + +using namespace std; + + +CPPEXTERN_NEW(pix_opencv_matchshape) + +///////////////////////////////////////////////////////// +// +// pix_opencv_matchshape +// +///////////////////////////////////////////////////////// +// Constructor +// +///////////////////////////////////////////////////////// +pix_opencv_matchshape :: pix_opencv_matchshape() : m_threshold(2), m_method(CV_CONTOURS_MATCH_I1) +{ + m_dataout = outlet_new(this->x_obj, 0); + m_template_vec_vec.clear(); + m_template_vec_mat.clear(); +} + +///////////////////////////////////////////////////////// +// Destructor +// +///////////////////////////////////////////////////////// +pix_opencv_matchshape :: ~pix_opencv_matchshape() +{ +} + +///////////////////////////////////////////////////////// +// processImage +// +///////////////////////////////////////////////////////// +void pix_opencv_matchshape :: processRGBAImage(imageStruct &image) +{ + error( "pix_opencv_matchshape : rgba format not supported" ); +} + +void pix_opencv_matchshape :: processRGBImage(imageStruct &image) { + error( "pix_opencv_matchshape : rgb format not supported"); +} + +void pix_opencv_matchshape :: processYUVImage(imageStruct &image) +{ + error( "pix_opencv_matchshape : yuv format not supported" ); +} + +void pix_opencv_matchshape :: processGrayImage(imageStruct &image) +{ + error( "pix_opencv_matchshape : gray format not supported" ); + error( "pix_opencv_matchshape only works on pd lists" ); + + // TODO add support to compare grayscale images +} + +///////////////////////////////////////////////////////// +// static member function +// +///////////////////////////////////////////////////////// +void pix_opencv_matchshape :: obj_setupCallback(t_class *classPtr) +{ + CPPEXTERN_MSG0(classPtr, "clear", clearMess); + CPPEXTERN_MSG(classPtr, "template", templateMess); + CPPEXTERN_MSG(classPtr, "contour", contourMess); + CPPEXTERN_MSG1(classPtr, "threshold", thresholdMess, float); + CPPEXTERN_MSG1(classPtr, "method", methodMess, int); +} + +void pix_opencv_matchshape :: clearMess(void) +{ + for ( vector<vector<cv::Point2f> >::iterator it=m_template_vec_vec.end(); it!=m_template_vec_vec.begin(); it--) + { + (*it).clear(); + } + m_template_vec_vec.clear(); + m_template_vec_mat.clear(); + + t_atom data; + SETFLOAT(&data, (float)m_template_vec_vec.size()); + outlet_anything(m_dataout, gensym("template_vec"), 1, &data); + + SETFLOAT(&data, (float)m_template_vec_mat.size()); + outlet_anything(m_dataout, gensym("template_mat"), 1, &data); +} + + +void pix_opencv_matchshape :: contourMess(t_symbol*s, int argc, t_atom*argv) +{ + if ( m_template_vec_vec.empty() ){ + error("no template to match, please load a template before matching"); + return; + } + + if ( (argc%2)!=0 ) { + error("template message argument should be multiple of 2"); + return; + } + + for (int i=0;i<argc;i++){ + if(argv[i].a_type!=A_FLOAT){ + error("template message should have only float arguments"); + return; + } + } + + vector<cv::Point2f> tmp_contour; + for (int i=2;i<argc;i+=2){ // start at index 2, first two elements are reserved (for compatibility) + cv::Point2f pt; + pt.x = atom_getfloat(argv+i); + pt.y = atom_getfloat(argv+i+1); + tmp_contour.push_back(pt); + } + + double comp, min(99999999999.); + int id(0),i(0); + for ( vector<vector<cv::Point2f> >::iterator it=m_template_vec_vec.begin(); it!=m_template_vec_vec.end(); ++it){ + comp = cv::matchShapes(tmp_contour, *it, m_method, 0.); + if ( comp < min ){ + min=comp; + id=i; + } + i++; + } + + if ( min < m_threshold ) + { + t_atom data[2]; + SETFLOAT(data,id); + SETFLOAT(data+1, min); + outlet_anything(m_dataout, gensym("match_vec"), 2, data); + } +} + +void pix_opencv_matchshape :: templateMess(t_symbol*s, int argc, t_atom*argv) +{ + if ( (argc%2)!=0 ) { + error("template message argument should be multiple of 2"); + return; + } + for (int i=0;i<argc;i++){ + if(argv[i].a_type!=A_FLOAT){ + error("template message should have only float arguments"); + return; + } + } + + vector<cv::Point2f> tmp_contour; + tmp_contour.clear(); + for (int i=2;i<argc;i+=2){ // start at index 2, first two elements are reserved (for compatibility) + cv::Point2f pt; + pt.x = atom_getfloat(argv+i); + pt.y = atom_getfloat(argv+i+1); + tmp_contour.push_back(pt); + } + m_template_vec_vec.push_back(tmp_contour); + + t_atom data; + SETFLOAT(&data, (int)m_template_vec_vec.size()); + outlet_anything(m_dataout, gensym("template_vec"), 1, &data); +} + +void pix_opencv_matchshape :: thresholdMess(float arg) +{ + m_threshold=(double)(arg>0.?arg:0.); + t_atom data; + SETFLOAT(&data, m_threshold); + outlet_anything(m_dataout, gensym("threshold"), 1, &data); +} + +void pix_opencv_matchshape :: methodMess(int arg) +{ + switch (arg) { + case 1: + m_method=CV_CONTOURS_MATCH_I1; + break; + case 2: + m_method=CV_CONTOURS_MATCH_I2; + break; + case 3: + m_method=CV_CONTOURS_MATCH_I3; + break; + default: + error("method should be 1, 2 or 3"); + m_method=CV_CONTOURS_MATCH_I1; + } + t_atom data; + switch (m_method) { + case CV_CONTOURS_MATCH_I1: + SETFLOAT(&data, 1); + break; + case CV_CONTOURS_MATCH_I2: + SETFLOAT(&data, 2); + break; + case CV_CONTOURS_MATCH_I3: + SETFLOAT(&data, 3); + break; + } + outlet_anything(m_dataout, gensym("method"), 1, &data); +} |