aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine Villeret <avilleret@users.sourceforge.net>2013-01-15 14:29:08 +0000
committerAntoine Villeret <avilleret@users.sourceforge.net>2013-01-15 14:29:08 +0000
commit8ef221c853850bfa0ded97192a6894f8e4d942db (patch)
treef72b70b4a34b5707064dbe9fb431ec736db9f511
parente4dbd3c6669edc7648e1e101082b5be3c419789b (diff)
add writing to tables methods
contours could be huge and may lead to stack overflow with the list iteratiion drawing function using tables and gemvertexbuffer also improve performances svn path=/trunk/externals/pix_opencv/; revision=16868
-rw-r--r--pix_opencv_contours.cc258
-rw-r--r--pix_opencv_contours.h6
2 files changed, 202 insertions, 62 deletions
diff --git a/pix_opencv_contours.cc b/pix_opencv_contours.cc
index d8f162d..85d6ea4 100644
--- a/pix_opencv_contours.cc
+++ b/pix_opencv_contours.cc
@@ -38,7 +38,11 @@ pix_opencv_contours :: pix_opencv_contours() : m_area_threshold(30), \
m_enable_contours(1), \
m_enable_hulls(1), \
m_enable_defects(1), \
- m_hierarchy_level(-1)
+ m_hierarchy_level(-1), \
+ m_taboutput(0), \
+ m_x_arrayname(NULL), \
+ m_y_arrayname(NULL), \
+ m_z_arrayname(NULL)
{
m_dataout_middle = outlet_new(this->x_obj, 0);
m_dataout_right = outlet_new(this->x_obj, 0);
@@ -85,7 +89,7 @@ void pix_opencv_contours :: processGrayImage(imageStruct &image)
/*****************/
/* Find Contours */
/*****************/
-
+
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
@@ -145,75 +149,191 @@ void pix_opencv_contours :: processGrayImage(imageStruct &image)
}
if ( m_enable_contours )
- {
- t_atom*info;
- info = new t_atom[(int) m_contours.size()*20+2];
- // info : 20x(contour_nb) matrix
- // info for each contour : area, rotrect corner (8 float), rotrect center, rotrect size, rotation angle, number of segments, length of contour, other are reserved for future use
- int count(0);
- SETFLOAT(info+1, 20.);
- int info_offset(2);
-
- for( size_t i = 0 ; i < m_contours.size(); i++ )
- {
- if (!m_contours[i].empty() && m_contours[i].size() > 2) {
- SETFLOAT(info+info_offset, (float) cv::contourArea(m_contours[i]));
-
- cv::RotatedRect rot_rect = cv::minAreaRect(m_contours[i]);
- cv::Point2f corners[4];
- rot_rect.points(corners);
- double length = cv::arcLength(m_contours[i],true);
- for (int j=0;j<4;j++) {
- SETFLOAT(info+info_offset+j*2+1, corners[j].x/image.xsize);
- SETFLOAT(info+info_offset+j*2+2, corners[j].y/image.ysize);
- }
+ {
+ t_atom*info;
+ info = new t_atom[(int) m_contours.size()*20+2];
+ // info : 20x(contour_nb) matrix
+ // info for each contour : area, rotrect corner (8 float), rotrect center, rotrect size, rotation angle, number of segments, length of contour, other are reserved for future use
+ int count(0);
+ SETFLOAT(info+1, 20.);
+ int info_offset(2);
+
+ for( size_t i = 0 ; i < m_contours.size(); i++ )
+ {
+ if (!m_contours[i].empty() && m_contours[i].size() > 2) {
+ SETFLOAT(info+info_offset, (float) cv::contourArea(m_contours[i]));
+
+ cv::RotatedRect rot_rect = cv::minAreaRect(m_contours[i]);
+ cv::Point2f corners[4];
+ rot_rect.points(corners);
+ double length = cv::arcLength(m_contours[i],true);
+ for (int j=0;j<4;j++) {
+ SETFLOAT(info+info_offset+j*2+1, corners[j].x/image.xsize);
+ SETFLOAT(info+info_offset+j*2+2, corners[j].y/image.ysize);
+ }
- SETFLOAT(info+info_offset+9, rot_rect.center.x/image.xsize);
- SETFLOAT(info+info_offset+10, rot_rect.center.y/image.ysize);
- SETFLOAT(info+info_offset+11, rot_rect.size.width/image.xsize);
- SETFLOAT(info+info_offset+12, rot_rect.size.height/image.xsize);
- SETFLOAT(info+info_offset+13, rot_rect.angle);
- SETFLOAT(info+info_offset+14, m_contours[i].size()); // number of points in segment
- SETFLOAT(info+info_offset+15, (float) length);
- SETFLOAT(info+info_offset+16, 0);
- SETFLOAT(info+info_offset+17, 0);
- SETFLOAT(info+info_offset+18, 0);
- SETFLOAT(info+info_offset+19, 0);
-
- info_offset+=20;
- count++;
+ SETFLOAT(info+info_offset+9, rot_rect.center.x/image.xsize);
+ SETFLOAT(info+info_offset+10, rot_rect.center.y/image.ysize);
+ SETFLOAT(info+info_offset+11, rot_rect.size.width/image.xsize);
+ SETFLOAT(info+info_offset+12, rot_rect.size.height/image.xsize);
+ SETFLOAT(info+info_offset+13, rot_rect.angle);
+ SETFLOAT(info+info_offset+14, m_contours[i].size()); // number of points in segment
+ SETFLOAT(info+info_offset+15, (float) length);
+ SETFLOAT(info+info_offset+16, 0);
+ SETFLOAT(info+info_offset+17, 0);
+ SETFLOAT(info+info_offset+18, 0);
+ SETFLOAT(info+info_offset+19, 0);
+
+ info_offset+=20;
+ count++;
+ }
}
- }
- SETFLOAT(info, (float) count);
- if (count) outlet_anything(m_dataout_right, gensym("info"), count*20+2, info);
- else outlet_float(m_dataout_right, 0);
+
+ if ( !m_taboutput ){
+
+ SETFLOAT(info, (float) count);
+ if (count) outlet_anything(m_dataout_right, gensym("info"), count*20+2, info);
+ else outlet_float(m_dataout_right, 0);
+
+ for( size_t i = 0 ; i < m_contours.size() ; i++ )
+ {
+ if (!m_contours[i].empty() && m_contours[i].size() > 2) {
+ int size = 2+m_contours[i].size()*2;
+ t_atom*ap = new t_atom[size];
+ SETFLOAT(ap, static_cast<t_float>(m_contours[i].size()));
+ SETFLOAT(ap+1, 2.0);
+
+ int offset(2);
+
+ for ( size_t j = 0 ; j < m_contours[i].size() ; j++){
+ cv::Point pt = m_contours[i][j];
+ SETFLOAT(ap+offset,(float) pt.x/image.xsize);
+ SETFLOAT(ap+offset+1,(float) pt.y/image.ysize);
+ offset+=2;
+ }
+ outlet_anything(m_dataout_middle, gensym("contour"), size, ap);
+ if(ap)delete[]ap;ap=NULL;
+
+ }
+ }
+
+
+ if (info) delete info;
+ info = NULL;
+
+ } else {
- for( size_t i = 0 ; i < m_contours.size() ; i++ )
- {
- if (!m_contours[i].empty() && m_contours[i].size() > 2) {
- int size = 2+m_contours[i].size()*2;
- t_atom*ap = new t_atom[size];
- SETFLOAT(ap, static_cast<t_float>(m_contours[i].size()));
- SETFLOAT(ap+1, 2.0);
+ //~ put contours in 3 tables.
+ //~ contours are separated by a -1 value
+
+ if ( m_x_arrayname == NULL || m_y_arrayname == NULL || m_z_arrayname == NULL){
+ error("please settab before trying to write into...");
+ return;
+ }
+
+ int size(0), vecxsize(0), vecysize(0), veczsize(0);
+ t_garray *ax, *ay, *az;
+ t_word *vecx, *vecy, *vecz;
+
+ //~ check if array exist
+ if (!(ax = (t_garray *)pd_findbyclass(m_x_arrayname, garray_class))){
+ error("%s: no such array", m_x_arrayname->s_name);
+ return;
+ }
+ if (!(ay = (t_garray *)pd_findbyclass(m_y_arrayname, garray_class))){
+ error("%s: no such array", m_y_arrayname->s_name);
+ return;
+ }
+ if (!(az = (t_garray *)pd_findbyclass(m_z_arrayname, garray_class))){
+ error("%s: no such array", m_z_arrayname->s_name);
+ return;
+ }
+
+ //~ check array and resize if needed
+ for( size_t i = 0 ; i < m_contours.size(); i++ ){
+ size+=m_contours[i].size()+3;
+ }
+
+ if (!garray_getfloatwords(ax, &vecxsize, &vecx)){
+ error("%s: bad template for tabwrite", m_x_arrayname->s_name);
+ return;
+ } else if ( vecxsize != size ){
+ garray_resize_long(ax,size);
+ if (!garray_getfloatwords(ax, &vecxsize, &vecx)){
+ error("%s: can't resize correctly", m_x_arrayname->s_name);
+ return;
+ }
+ }
+
+ if (!garray_getfloatwords(ay, &vecysize, &vecy)){
+ error("%s: bad template for tabwrite", m_y_arrayname->s_name);
+ return;
+ } else if ( vecysize != size ){
+ garray_resize_long(ay,size);
+ if (!garray_getfloatwords(ay, &vecysize, &vecy)){
+ error("%s: can't resize correctly", m_y_arrayname->s_name);
+ return;
+ }
+ }
+
+ if (!garray_getfloatwords(az, &veczsize, &vecz)){
+ error("%s: bad template for tabwrite", m_z_arrayname->s_name);
+ return;
+ } else if ( veczsize != size ){
+ garray_resize_long(az,size);
+ if (!garray_getfloatwords(az, &veczsize, &vecz)){
+ error("%s: can't resize correctly", m_z_arrayname->s_name);
+ return;
+ }
+ }
+
+ int n=0;
+
+ for( size_t i = 0 ; i < m_contours.size(); i++ )
+ {
+ if (n >= vecxsize || n>=vecysize || n>=veczsize)
+ {
+ error("array are not wide engouth");
+ return;
+ }
- int offset(2);
+ unsigned int j;
+ cv::Point pt;
+ pt = m_contours[i][0];
+ //~ start with blank point
+ vecx[n].w_float = (float) pt.x/image.xsize;
+ vecy[n].w_float = (float) pt.y/image.ysize;
+ vecz[n].w_float = 0.;
+ n++;
+
+ for ( j = 0 ; j < m_contours[i].size() ; j++) {
- for ( size_t j = 0 ; j < m_contours[i].size() ; j++){
- cv::Point pt = m_contours[i][j];
- SETFLOAT(ap+offset,(float) pt.x/image.xsize);
- SETFLOAT(ap+offset+1,(float) pt.y/image.ysize);
- offset+=2;
+ pt = m_contours[i][j];
+
+ vecx[n].w_float = (float) pt.x/image.xsize;
+ vecy[n].w_float = (float) pt.y/image.ysize;
+ vecz[n].w_float = 1.;
+ n++;
}
- outlet_anything(m_dataout_middle, gensym("contour"), size, ap);
- if(ap)delete[]ap;ap=NULL;
-
+ // close contour
+ pt = m_contours[i][0];
+ vecx[n].w_float = (float) pt.x/image.xsize;
+ vecy[n].w_float = (float) pt.y/image.ysize;
+ vecz[n].w_float = 1.;
+ n++;
+ // add a blank point to draw invisible segment
+ vecz[n++].w_float = 0.;
+
+
}
+ //~ comment the redraw fnt if not needed
+ garray_redraw(ax);
+ garray_redraw(ay);
+ garray_redraw(az);
}
-
- if (info) delete info;
- info = NULL;
}
+
//~ cv::drawContours(imgMat2, m_contours, -1, cv::Scalar(128,255,255), 3);
/**********************/
@@ -329,6 +449,8 @@ void pix_opencv_contours :: obj_setupCallback(t_class *classPtr)
CPPEXTERN_MSG1(classPtr, "convexhulls", convexhullsMess, double);
CPPEXTERN_MSG1(classPtr, "convexitydefects", convexitydefectsMess, double);
CPPEXTERN_MSG1(classPtr, "hierarchy_level", hierarchyMess, double);
+ CPPEXTERN_MSG1(classPtr, "taboutput", taboutputMess, float);
+ CPPEXTERN_MSG3(classPtr, "settab", tableMess, t_symbol*, t_symbol*, t_symbol*);
}
/////////////////////////////////////////////////////////
@@ -366,3 +488,17 @@ void pix_opencv_contours :: hierarchyMess(double arg)
m_hierarchy_level = arg < -1 ? -1 : arg;
m_mode = m_hierarchy_level == -1 ? CV_RETR_LIST : CV_RETR_TREE;
}
+
+void pix_opencv_contours :: taboutputMess(float arg)
+{
+ m_taboutput = arg > 0;
+}
+void pix_opencv_contours :: tableMess(t_symbol*xarray, t_symbol*yarray, t_symbol*zarray)
+{
+ // check if arrays exist
+ m_x_arrayname = xarray;
+ m_y_arrayname = yarray;
+ m_z_arrayname = zarray;
+
+ m_taboutput = 1;
+}
diff --git a/pix_opencv_contours.h b/pix_opencv_contours.h
index fb1ebe1..b546aca 100644
--- a/pix_opencv_contours.h
+++ b/pix_opencv_contours.h
@@ -65,6 +65,8 @@ class GEM_EXTERN pix_opencv_contours : public GemPixObj
void convexhullsMess(double arg);
void convexitydefectsMess(double arg);
void hierarchyMess(double arg);
+ void taboutputMess(float arg);
+ void tableMess(t_symbol*x, t_symbol*y, t_symbol*z);
private:
@@ -76,7 +78,9 @@ class GEM_EXTERN pix_opencv_contours : public GemPixObj
double m_area_threshold; // min area for contour
double m_epsilon;
- int m_enable_contours, m_enable_hulls, m_enable_defects, m_hierarchy_level, m_mode;
+ int m_enable_contours, m_enable_hulls, m_enable_defects, m_hierarchy_level, m_mode, m_taboutput;
+
+ t_symbol *m_x_arrayname, *m_y_arrayname, *m_z_arrayname;
};
#endif // for header file