From ba994f4404b6eadcab4e0ead46ef4d3ffeceb024 Mon Sep 17 00:00:00 2001 From: Antoine Villeret Date: Thu, 10 Jul 2014 14:39:22 +0000 Subject: lots of changes ! 1. switch to a new build system based on automake (because we need to check for some lib on ./configure before make) 2. sort files in different directory 3. add some new features (some of them need OpenCV >= 2.4.5) svn path=/trunk/externals/pix_opencv/; revision=17324 --- src/pix_opencv_surf.cc | 1054 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1054 insertions(+) create mode 100644 src/pix_opencv_surf.cc (limited to 'src/pix_opencv_surf.cc') diff --git a/src/pix_opencv_surf.cc b/src/pix_opencv_surf.cc new file mode 100644 index 0000000..5a5b46d --- /dev/null +++ b/src/pix_opencv_surf.cc @@ -0,0 +1,1054 @@ + +// +// 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. +// +///////////////////////////////////////////////////////// + +#if HAVE_LIBOPENCV_NONFREE +#include "pix_opencv_surf.h" + +#include + + +CPPEXTERN_NEW(pix_opencv_surf) + +///////////////////////////////////////////////////////// +// +// pix_opencv_surf +// +///////////////////////////////////////////////////////// +// Constructor +// +///////////////////////////////////////////////////////// + +pix_opencv_surf :: pix_opencv_surf() +{ + int i; + + comp_xsize=320; + comp_ysize=240; + + m_dataout = outlet_new(this->x_obj, &s_anything); + + night_mode = 0; + x_maxmove = 20; + x_delaunay = -1; + x_threshold = -1; + + objectKeypoints = NULL; + objectDescriptors = NULL; + x_hessian = 1000; + x_ftolerance = 5; + + x_markall = 0; + for ( i=0; icomp_xsize!=image.xsize)&&(this->comp_ysize!=image.ysize)) + { + + this->comp_xsize=image.xsize; + this->comp_ysize=image.ysize; + + cvReleaseImage( &rgba ); + cvReleaseImage( &orgb ); + cvReleaseImage( &rgb ); + cvReleaseImage( &gray ); + cvReleaseImage( &ogray ); + + rgba = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 4 ); + orgb = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 3 ); + rgb = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 3 ); + gray = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 1 ); + ogray = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 1 ); + + } + + memcpy( rgba->imageData, image.data, image.xsize*image.ysize*4 ); + cvCvtColor(rgba, orgb, CV_BGRA2BGR); + cvCvtColor(rgba, rgb, CV_BGRA2BGR); + cvCvtColor(rgba, gray, CV_BGRA2GRAY); + + x_storage = cvCreateMemStorage(0); + + if( night_mode ) + cvZero( rgb ); + + for ( im=0; im= 0 ) + { + // init data structures for the delaunay + x_fullrect.x = -comp_xsize/2; + x_fullrect.y = -comp_ysize/2; + x_fullrect.width = 2*comp_xsize; + x_fullrect.height = 2*comp_ysize; + + x_subdiv = cvCreateSubdiv2D( CV_SEQ_KIND_SUBDIV2D, sizeof(*x_subdiv), + sizeof(CvSubdiv2DPoint), + sizeof(CvQuadEdge2D), + x_storage ); + cvInitSubdivDelaunay2D( x_subdiv, x_fullrect ); + } + + cvExtractSURF( gray, 0, &objectKeypoints, &objectDescriptors, x_storage, cvSURFParams(x_hessian, 1) ); + descsize = (int)(objectDescriptors->elem_size/sizeof(float)); + + for( i = 0; i < objectKeypoints->total; i++ ) + { + CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, i ); + const float* rdesc = (const float*)cvGetSeqElem( objectDescriptors, i ); + + if ( x_delaunay == 0 ) // add all the points + { + cvSubdivDelaunay2DInsert( x_subdiv, r1->pt ); + cvCalcSubdivVoronoi2D( x_subdiv ); + } + + // only add points included in (color-threshold) 0 ) && ( x_xmark[x_delaunay-1] != -1 ) ) + { + int px = cvPointFrom32f(r1->pt).x; + int py = cvPointFrom32f(r1->pt).y; + int ppx, ppy; + + // eight connected pixels + for ( ppx=px-1; ppx<=px+1; ppx++ ) + { + for ( ppy=py-1; ppy<=py+1; ppy++ ) + { + if ( ( ppx < 0 ) || ( ppx >= comp_xsize ) ) continue; + if ( ( ppy < 0 ) || ( ppy >= comp_ysize ) ) continue; + + uchar red = ((uchar*)(orgb->imageData + orgb->widthStep*ppx))[ppy*3]; + uchar green = ((uchar*)(orgb->imageData + orgb->widthStep*ppx))[ppy*3+1]; + uchar blue = ((uchar*)(orgb->imageData + orgb->widthStep*ppx))[ppy*3+2]; + + uchar pred = ((uchar*)(orgb->imageData + orgb->widthStep*x_xmark[x_delaunay-1]))[x_ymark[x_delaunay-1]*3]; + uchar pgreen = ((uchar*)(orgb->imageData + orgb->widthStep*x_xmark[x_delaunay-1]))[x_ymark[x_delaunay-1]*3+1]; + uchar pblue = ((uchar*)(orgb->imageData + orgb->widthStep*x_xmark[x_delaunay-1]))[x_ymark[x_delaunay-1]*3+2]; + + int diff = abs(red-pred) + abs(green-pgreen) + abs(blue-pblue); + + // post( "pdp_opencv_surf : point (%d,%d,%d) : diff : %d", blue, green, red, diff ); + + if ( diff < x_threshold ) + { + cvSubdivDelaunay2DInsert( x_subdiv, r1->pt ); + cvCalcSubdivVoronoi2D( x_subdiv ); + } + } + } + } + + cvCircle( rgb, cvPointFrom32f(r1->pt), 3, CV_RGB(0,255,0), -1, 8,0); + + // mark the point if it is not already + if ( x_markall ) + { + int marked = 0; + + for ( im=0; impt.x-x_xmark[im], 2 ) + pow( r1->pt.y-x_ymark[im], 2 ) ); + + if ( odist <= x_maxmove ) + { + marked = 1; + // post( "pdp_opencv_surf : point already marked" ); + break; + } + } + if ( !marked ) + { + for ( i=0; ipt.x; + x_ymark[i] = r1->pt.y; + x_found[i] = x_ftolerance; + memset( (float * )x_rdesc[i], 0x0, DSCSIZE*sizeof(float)); + break; + } + } + } + } + } + + for ( im=0; imcomp_ysize)?comp_xsize:comp_ysize; + + for( i = 0; i < objectKeypoints->total; i++ ) + { + CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, i ); + const float* rdesc = (const float*)cvGetSeqElem( objectDescriptors, i ); + int descsize = (int)(objectDescriptors->elem_size/sizeof(float)); + + // manually marked points + // recognized on position + odist=sqrt( pow( r1->pt.x-x_xmark[im], 2 ) + pow( r1->pt.y-x_ymark[im], 2 ) ); + + if ( odist <= x_maxmove ) + { + if ( odist < dist ) + { + oi=im; + x_xmark[oi]=r1->pt.x; + x_ymark[oi]=r1->pt.y; + memcpy( (float * )x_rdesc[oi], rdesc, descsize*sizeof(float)); + dist = odist; + } + } + } + + if ( oi !=-1 ) + { + sprintf( tindex, "%d", oi ); + cvPutText( rgb, tindex, cvPoint(x_xmark[oi],x_ymark[oi]), &font, CV_RGB(255,255,255)); + x_found[oi] = x_ftolerance; + SETFLOAT(&x_list[0], oi); + SETFLOAT(&x_list[1], x_xmark[oi]); + SETFLOAT(&x_list[2], x_ymark[oi]); + outlet_list( m_dataout, 0, 3, x_list ); + } + } + + // draw the delaunay + if ( x_delaunay >= 0 ) + { + CvSeqReader reader; + int i, total = x_subdiv->edges->total; + int elem_size = x_subdiv->edges->elem_size; + + cvStartReadSeq( (CvSeq*)(x_subdiv->edges), &reader, 0 ); + + for( i = 0; i < total; i++ ) + { + CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr); + CvSubdiv2DPoint* org_pt; + CvSubdiv2DPoint* dst_pt; + CvPoint2D32f org; + CvPoint2D32f dst; + CvPoint iorg, idst; + + if( CV_IS_SET_ELEM( edge )) + { + org_pt = cvSubdiv2DEdgeOrg((CvSubdiv2DEdge)edge); + dst_pt = cvSubdiv2DEdgeDst((CvSubdiv2DEdge)edge); + + if( org_pt && dst_pt ) + { + org = org_pt->pt; + dst = dst_pt->pt; + + iorg = cvPoint( cvRound( org.x ), cvRound( org.y )); + idst = cvPoint( cvRound( dst.x ), cvRound( dst.y )); + + if ( ( org.x > 0 ) && ( org.x < comp_xsize ) && + ( dst.x > 0 ) && ( dst.x < comp_xsize ) && + ( org.y > 0 ) && ( org.y < comp_ysize ) && + ( dst.y > 0 ) && ( dst.y < comp_ysize ) ) + cvLine( rgb, iorg, idst, CV_RGB(255,0,0), 1, CV_AA, 0 ); + } + } + + CV_NEXT_SEQ_ELEM( elem_size, reader ); + } + } + + // suppress lost points + for ( im=0; imimageData, image.xsize*image.ysize*4 ); +} + +void pix_opencv_surf :: processRGBImage(imageStruct &image) +{ + int i, k; + int im, oi; + int marked; + int descsize; + char tindex[4]; + float dist, odist; + + if ((this->comp_xsize!=image.xsize)&&(this->comp_ysize!=image.ysize)) + { + + this->comp_xsize=image.xsize; + this->comp_ysize=image.ysize; + + cvReleaseImage( &rgba ); + cvReleaseImage( &orgb ); + cvReleaseImage( &rgb ); + cvReleaseImage( &gray ); + cvReleaseImage( &ogray ); + + rgba = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 4 ); + orgb = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 3 ); + rgb = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 3 ); + gray = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 1 ); + ogray = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 1 ); + + } + + memcpy( rgb->imageData, image.data, image.xsize*image.ysize*3 ); + memcpy( orgb->imageData, image.data, image.xsize*image.ysize*3 ); + cvCvtColor(rgb, gray, CV_BGRA2GRAY); + + x_storage = cvCreateMemStorage(0); + + if( night_mode ) + cvZero( rgb ); + + for ( im=0; im= 0 ) + { + // init data structures for the delaunay + x_fullrect.x = -comp_xsize/2; + x_fullrect.y = -comp_ysize/2; + x_fullrect.width = 2*comp_xsize; + x_fullrect.height = 2*comp_ysize; + + x_subdiv = cvCreateSubdiv2D( CV_SEQ_KIND_SUBDIV2D, sizeof(*x_subdiv), + sizeof(CvSubdiv2DPoint), + sizeof(CvQuadEdge2D), + x_storage ); + cvInitSubdivDelaunay2D( x_subdiv, x_fullrect ); + } + + cvExtractSURF( gray, 0, &objectKeypoints, &objectDescriptors, x_storage, cvSURFParams(x_hessian, 1) ); + descsize = (int)(objectDescriptors->elem_size/sizeof(float)); + + for( i = 0; i < objectKeypoints->total; i++ ) + { + CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, i ); + const float* rdesc = (const float*)cvGetSeqElem( objectDescriptors, i ); + + if ( x_delaunay == 0 ) // add all the points + { + cvSubdivDelaunay2DInsert( x_subdiv, r1->pt ); + cvCalcSubdivVoronoi2D( x_subdiv ); + } + + // only add points included in (color-threshold) 0 ) && ( x_xmark[x_delaunay-1] != -1 ) ) + { + int px = cvPointFrom32f(r1->pt).x; + int py = cvPointFrom32f(r1->pt).y; + int ppx, ppy; + + // eight connected pixels + for ( ppx=px-1; ppx<=px+1; ppx++ ) + { + for ( ppy=py-1; ppy<=py+1; ppy++ ) + { + if ( ( ppx < 0 ) || ( ppx >= comp_xsize ) ) continue; + if ( ( ppy < 0 ) || ( ppy >= comp_ysize ) ) continue; + + uchar red = ((uchar*)(orgb->imageData + orgb->widthStep*ppx))[ppy*3]; + uchar green = ((uchar*)(orgb->imageData + orgb->widthStep*ppx))[ppy*3+1]; + uchar blue = ((uchar*)(orgb->imageData + orgb->widthStep*ppx))[ppy*3+2]; + + uchar pred = ((uchar*)(orgb->imageData + orgb->widthStep*x_xmark[x_delaunay-1]))[x_ymark[x_delaunay-1]*3]; + uchar pgreen = ((uchar*)(orgb->imageData + orgb->widthStep*x_xmark[x_delaunay-1]))[x_ymark[x_delaunay-1]*3+1]; + uchar pblue = ((uchar*)(orgb->imageData + orgb->widthStep*x_xmark[x_delaunay-1]))[x_ymark[x_delaunay-1]*3+2]; + + int diff = abs(red-pred) + abs(green-pgreen) + abs(blue-pblue); + + // post( "pdp_opencv_surf : point (%d,%d,%d) : diff : %d", blue, green, red, diff ); + + if ( diff < x_threshold ) + { + cvSubdivDelaunay2DInsert( x_subdiv, r1->pt ); + cvCalcSubdivVoronoi2D( x_subdiv ); + } + } + } + } + + cvCircle( rgb, cvPointFrom32f(r1->pt), 3, CV_RGB(0,255,0), -1, 8,0); + + // mark the point if it is not already + if ( x_markall ) + { + int marked = 0; + + for ( im=0; impt.x-x_xmark[im], 2 ) + pow( r1->pt.y-x_ymark[im], 2 ) ); + + if ( odist <= x_maxmove ) + { + marked = 1; + // post( "pdp_opencv_surf : point already marked" ); + break; + } + } + if ( !marked ) + { + for ( i=0; ipt.x; + x_ymark[i] = r1->pt.y; + x_found[i] = x_ftolerance; + memset( (float * )x_rdesc[i], 0x0, DSCSIZE*sizeof(float)); + break; + } + } + } + } + } + + for ( im=0; imcomp_ysize)?comp_xsize:comp_ysize; + + for( i = 0; i < objectKeypoints->total; i++ ) + { + CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, i ); + const float* rdesc = (const float*)cvGetSeqElem( objectDescriptors, i ); + int descsize = (int)(objectDescriptors->elem_size/sizeof(float)); + + // manually marked points + // recognized on position + odist=sqrt( pow( r1->pt.x-x_xmark[im], 2 ) + pow( r1->pt.y-x_ymark[im], 2 ) ); + + if ( odist <= x_maxmove ) + { + if ( odist < dist ) + { + oi=im; + x_xmark[oi]=r1->pt.x; + x_ymark[oi]=r1->pt.y; + memcpy( (float * )x_rdesc[oi], rdesc, descsize*sizeof(float)); + dist = odist; + } + } + } + + if ( oi !=-1 ) + { + sprintf( tindex, "%d", oi ); + cvPutText( rgb, tindex, cvPoint(x_xmark[oi],x_ymark[oi]), &font, CV_RGB(255,255,255)); + x_found[oi] = x_ftolerance; + SETFLOAT(&x_list[0], oi); + SETFLOAT(&x_list[1], x_xmark[oi]); + SETFLOAT(&x_list[2], x_ymark[oi]); + outlet_list( m_dataout, 0, 3, x_list ); + } + } + + // draw the delaunay + if ( x_delaunay >= 0 ) + { + CvSeqReader reader; + int i, total = x_subdiv->edges->total; + int elem_size = x_subdiv->edges->elem_size; + + cvStartReadSeq( (CvSeq*)(x_subdiv->edges), &reader, 0 ); + + for( i = 0; i < total; i++ ) + { + CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr); + CvSubdiv2DPoint* org_pt; + CvSubdiv2DPoint* dst_pt; + CvPoint2D32f org; + CvPoint2D32f dst; + CvPoint iorg, idst; + + if( CV_IS_SET_ELEM( edge )) + { + org_pt = cvSubdiv2DEdgeOrg((CvSubdiv2DEdge)edge); + dst_pt = cvSubdiv2DEdgeDst((CvSubdiv2DEdge)edge); + + if( org_pt && dst_pt ) + { + org = org_pt->pt; + dst = dst_pt->pt; + + iorg = cvPoint( cvRound( org.x ), cvRound( org.y )); + idst = cvPoint( cvRound( dst.x ), cvRound( dst.y )); + + if ( ( org.x > 0 ) && ( org.x < comp_xsize ) && + ( dst.x > 0 ) && ( dst.x < comp_xsize ) && + ( org.y > 0 ) && ( org.y < comp_ysize ) && + ( dst.y > 0 ) && ( dst.y < comp_ysize ) ) + cvLine( rgb, iorg, idst, CV_RGB(255,0,0), 1, CV_AA, 0 ); + } + } + + CV_NEXT_SEQ_ELEM( elem_size, reader ); + } + } + + // suppress lost points + for ( im=0; imimageData, image.xsize*image.ysize*3 ); +} + +void pix_opencv_surf :: processYUVImage(imageStruct &image) +{ + post( "pix_opencv_surf : yuv format not supported" ); +} + +void pix_opencv_surf :: processGrayImage(imageStruct &image) +{ + int i, k; + int im, oi; + int marked; + int descsize; + char tindex[4]; + float dist, odist; + + if ((this->comp_xsize!=image.xsize)&&(this->comp_ysize!=image.ysize)) + { + + this->comp_xsize=image.xsize; + this->comp_ysize=image.ysize; + + cvReleaseImage( &rgba ); + cvReleaseImage( &orgb ); + cvReleaseImage( &rgb ); + cvReleaseImage( &gray ); + cvReleaseImage( &ogray ); + + rgba = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 4 ); + orgb = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 3 ); + rgb = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 3 ); + gray = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 1 ); + ogray = cvCreateImage( cvSize(comp_xsize, comp_ysize), 8, 1 ); + + } + + memcpy( gray->imageData, image.data, image.xsize*image.ysize ); + memcpy( ogray->imageData, image.data, image.xsize*image.ysize ); + x_storage = cvCreateMemStorage(0); + + if( night_mode ) + cvZero( gray ); + + for ( im=0; im= 0 ) + { + // init data structures for the delaunay + x_fullrect.x = -comp_xsize/2; + x_fullrect.y = -comp_ysize/2; + x_fullrect.width = 2*comp_xsize; + x_fullrect.height = 2*comp_ysize; + + x_subdiv = cvCreateSubdiv2D( CV_SEQ_KIND_SUBDIV2D, sizeof(*x_subdiv), + sizeof(CvSubdiv2DPoint), + sizeof(CvQuadEdge2D), + x_storage ); + cvInitSubdivDelaunay2D( x_subdiv, x_fullrect ); + } + + cvExtractSURF( ogray, 0, &objectKeypoints, &objectDescriptors, x_storage, cvSURFParams(x_hessian, 1) ); + descsize = (int)(objectDescriptors->elem_size/sizeof(float)); + + for( i = 0; i < objectKeypoints->total; i++ ) + { + CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, i ); + const float* rdesc = (const float*)cvGetSeqElem( objectDescriptors, i ); + + if ( x_delaunay == 0 ) // add all the points + { + cvSubdivDelaunay2DInsert( x_subdiv, r1->pt ); + cvCalcSubdivVoronoi2D( x_subdiv ); + } + + // only add points included in (color-threshold) 0 ) && ( x_xmark[x_delaunay-1] != -1 ) ) + { + int px = cvPointFrom32f(r1->pt).x; + int py = cvPointFrom32f(r1->pt).y; + int ppx, ppy; + + // eight connected pixels + for ( ppx=px-1; ppx<=px+1; ppx++ ) + { + for ( ppy=py-1; ppy<=py+1; ppy++ ) + { + if ( ( ppx < 0 ) || ( ppx >= comp_xsize ) ) continue; + if ( ( ppy < 0 ) || ( ppy >= comp_ysize ) ) continue; + + uchar lum = ((uchar*)(ogray->imageData + ogray->widthStep*ppx))[ppy]; + + uchar plum = ((uchar*)(ogray->imageData + ogray->widthStep*x_xmark[x_delaunay-1]))[x_ymark[x_delaunay-1]]; + + int diff = abs(lum-plum); + + if ( diff < x_threshold ) + { + cvSubdivDelaunay2DInsert( x_subdiv, r1->pt ); + cvCalcSubdivVoronoi2D( x_subdiv ); + } + } + } + } + + cvCircle( gray, cvPointFrom32f(r1->pt), 3, CV_RGB(255,255,255), -1, 8,0); + + // mark the point if it is not already + if ( x_markall ) + { + int marked = 0; + + for ( im=0; impt.x-x_xmark[im], 2 ) + pow( r1->pt.y-x_ymark[im], 2 ) ); + + if ( odist <= x_maxmove ) + { + marked = 1; + // post( "pdp_opencv_surf : point already marked" ); + break; + } + } + + if ( !marked ) + { + for ( i=0; ipt.x; + x_ymark[i] = r1->pt.y; + x_found[i] = x_ftolerance; + memset( (float * )x_rdesc[i], 0x0, DSCSIZE*sizeof(float)); + break; + } + } + } + } + } + + for ( im=0; imcomp_ysize)?comp_xsize:comp_ysize; + + for( i = 0; i < objectKeypoints->total; i++ ) + { + CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, i ); + const float* rdesc = (const float*)cvGetSeqElem( objectDescriptors, i ); + int descsize = (int)(objectDescriptors->elem_size/sizeof(float)); + + // manually marked points + // recognized on position + odist=sqrt( pow( r1->pt.x-x_xmark[im], 2 ) + pow( r1->pt.y-x_ymark[im], 2 ) ); + + if ( odist <= x_maxmove ) + { + if ( odist < dist ) + { + oi=im; + x_xmark[oi]=r1->pt.x; + x_ymark[oi]=r1->pt.y; + memcpy( (float * )x_rdesc[oi], rdesc, descsize*sizeof(float)); + dist = odist; + } + } + } + + if ( oi !=-1 ) + { + sprintf( tindex, "%d", oi ); + cvPutText( gray, tindex, cvPoint(x_xmark[oi],x_ymark[oi]), &font, CV_RGB(255,255,255)); + x_found[oi] = x_ftolerance; + SETFLOAT(&x_list[0], oi); + SETFLOAT(&x_list[1], x_xmark[oi]); + SETFLOAT(&x_list[2], x_ymark[oi]); + outlet_list( m_dataout, 0, 3, x_list ); + } + } + + // draw the delaunay + if ( x_delaunay >= 0 ) + { + CvSeqReader reader; + int i, total = x_subdiv->edges->total; + int elem_size = x_subdiv->edges->elem_size; + + cvStartReadSeq( (CvSeq*)(x_subdiv->edges), &reader, 0 ); + + for( i = 0; i < total; i++ ) + { + CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr); + CvSubdiv2DPoint* org_pt; + CvSubdiv2DPoint* dst_pt; + CvPoint2D32f org; + CvPoint2D32f dst; + CvPoint iorg, idst; + + if( CV_IS_SET_ELEM( edge )) + { + org_pt = cvSubdiv2DEdgeOrg((CvSubdiv2DEdge)edge); + dst_pt = cvSubdiv2DEdgeDst((CvSubdiv2DEdge)edge); + + if( org_pt && dst_pt ) + { + org = org_pt->pt; + dst = dst_pt->pt; + + iorg = cvPoint( cvRound( org.x ), cvRound( org.y )); + idst = cvPoint( cvRound( dst.x ), cvRound( dst.y )); + + if ( ( org.x > 0 ) && ( org.x < comp_xsize ) && + ( dst.x > 0 ) && ( dst.x < comp_xsize ) && + ( org.y > 0 ) && ( org.y < comp_ysize ) && + ( dst.y > 0 ) && ( dst.y < comp_ysize ) ) + cvLine( gray, iorg, idst, CV_RGB(255,255,255), 1, CV_AA, 0 ); + } + } + + CV_NEXT_SEQ_ELEM( elem_size, reader ); + } + } + + // suppress lost points + for ( im=0; imimageData, image.xsize*image.ysize ); +} + +///////////////////////////////////////////////////////// +// static member function +// +///////////////////////////////////////////////////////// + +void pix_opencv_surf :: obj_setupCallback(t_class *classPtr) +{ + class_addmethod(classPtr, (t_method)&pix_opencv_surf::nightModeMessCallback, + gensym("nightmode"), A_FLOAT, A_NULL); + class_addmethod(classPtr, (t_method)&pix_opencv_surf::hessianMessCallback, + gensym("hessian"), A_FLOAT, A_NULL); + class_addmethod(classPtr, (t_method)&pix_opencv_surf::markMessCallback, + gensym("mark"), A_GIMME, A_NULL); + class_addmethod(classPtr, (t_method)&pix_opencv_surf::deleteMessCallback, + gensym("delete"), A_FLOAT, A_NULL); + class_addmethod(classPtr, (t_method)&pix_opencv_surf::clearMessCallback, + gensym("clear"), A_NULL); + class_addmethod(classPtr, (t_method)&pix_opencv_surf::maxMoveMessCallback, + gensym("maxmove"), A_FLOAT, A_NULL); + class_addmethod(classPtr, (t_method)&pix_opencv_surf::ftoleranceMessCallback, + gensym("ftolerance"), A_FLOAT, A_NULL); + class_addmethod(classPtr, (t_method)&pix_opencv_surf::delaunayMessCallback, + gensym("delaunay"), A_SYMBOL, A_NULL); + class_addmethod(classPtr, (t_method)&pix_opencv_surf::pdelaunayMessCallback, + gensym("pdelaunay"), A_FLOAT, A_FLOAT, A_NULL); +} + +void pix_opencv_surf :: nightModeMessCallback(void *data, t_floatarg nightmode) +{ + GetMyClass(data)->nightModeMess((float)nightmode); +} + +void pix_opencv_surf :: hessianMessCallback(void *data, t_floatarg hessian) +{ + GetMyClass(data)->hessianMess((float)hessian); +} + +void pix_opencv_surf :: markMessCallback(void *data, t_symbol *s, int argc, t_atom *argv) +{ + GetMyClass(data)->markMess(argc, argv); +} + +void pix_opencv_surf :: deleteMessCallback(void *data, t_floatarg index) +{ + GetMyClass(data)->deleteMess((float)index); +} + +void pix_opencv_surf :: clearMessCallback(void *data) +{ + GetMyClass(data)->clearMess(); +} + +void pix_opencv_surf :: maxMoveMessCallback(void *data, t_floatarg maxmove) +{ + GetMyClass(data)->maxMoveMess((float)maxmove); +} + +void pix_opencv_surf :: ftoleranceMessCallback(void *data, t_floatarg ftolerance) +{ + GetMyClass(data)->ftoleranceMess((float)ftolerance); +} + +void pix_opencv_surf :: delaunayMessCallback(void *data, t_symbol *s) +{ + GetMyClass(data)->delaunayMess(s); +} + +void pix_opencv_surf :: pdelaunayMessCallback(void *data, t_floatarg fpoint, t_floatarg fthreshold) +{ + GetMyClass(data)->pdelaunayMess((float)fpoint, (float)fthreshold); +} + +void pix_opencv_surf :: nightModeMess(float nightmode) +{ + if ((nightmode==0.0)||(nightmode==1.0)) night_mode = (int)nightmode; +} + +void pix_opencv_surf :: hessianMess(float hessian) +{ + if (hessian>0.0) x_hessian = (int)hessian; +} + +void pix_opencv_surf :: markMess(int argc, t_atom *argv) +{ + int i; + int inserted; + + if ( argc == 1 ) // mark all or none + { + if ( argv[0].a_type != A_SYMBOL ) + { + error( "pix_opencv_surf : wrong argument (should be 'all')" ); + return; + } + if ( !strcmp( argv[0].a_w.w_symbol->s_name, "all" ) ) + { + x_markall = 1; + return; + } + if ( !strcmp( argv[0].a_w.w_symbol->s_name, "none" ) ) + { + x_markall = 0; + clearMess(); + return; + } + } + else + { + if ( ( argv[0].a_type != A_FLOAT ) || ( argv[1].a_type != A_FLOAT ) ) + { + error( "pix_opencv_surf : wrong argument (should be mark px py)" ); + return; + } + else + { + float fpx = argv[0].a_w.w_float; + float fpy = argv[1].a_w.w_float; + int px, py; + + if ( ( fpx < 0.0 ) || ( fpx > comp_xsize ) || ( fpy < 0.0 ) || ( fpy > comp_ysize ) ) + { + return; + } + + px = (int)fpx; + py = (int)fpy; + inserted = 0; + for ( i=0; i MAX_MARKERS ) ) + { + return; + } + + x_xmark[(int)index-1] = -1; + x_ymark[(int)index-1] = -1; + +} + +void pix_opencv_surf :: clearMess(void) +{ + int i; + + for ( i=0; i=3.0) maxmove = (int)maxmove; +} + +void pix_opencv_surf :: ftoleranceMess(float ftolerance) +{ + if (ftolerance>=0.0) ftolerance = (int)ftolerance; +} + +void pix_opencv_surf :: delaunayMess(t_symbol *s) +{ + if (s == gensym("on")) + x_delaunay = 0; + if (s == gensym("off")) + x_delaunay = -1; +} + +void pix_opencv_surf :: pdelaunayMess(float point, float threshold) +{ + if (((int)point>0) && ((int)point