aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rwxr-xr-xpix_opencv_hough_circles.cc11
-rwxr-xr-xpix_opencv_hough_lines-help.pd163
-rwxr-xr-xpix_opencv_hough_lines.cc600
-rwxr-xr-xpix_opencv_hough_lines.h110
5 files changed, 880 insertions, 6 deletions
diff --git a/Makefile b/Makefile
index f32b644..f702dd5 100644
--- a/Makefile
+++ b/Makefile
@@ -35,7 +35,7 @@ endif
.SUFFIXES = $(EXTENSION)
-SOURCES = pix_opencv_edge.cc pix_opencv_laplace.cc pix_opencv_morphology.cc pix_opencv_distrans.cc pix_opencv_motempl.cc pix_opencv_haarcascade.cc pix_opencv_contours_boundingrect.cc pix_opencv_bgsubstract.cc pix_opencv_contours_convexity.cc pix_opencv_dft.cc pix_opencv_lk.cc pix_opencv_hist_compare.cc pix_opencv_knear.cc pix_opencv_threshold.cc pix_opencv_floodfill.cc pix_opencv_athreshold.cc pix_opencv_bgstats.cc pix_opencv_camshift.cc pix_opencv_hu_compare.cc pix_opencv_pgh_compare.cc pix_opencv_hough_circles.cc
+SOURCES = pix_opencv_edge.cc pix_opencv_laplace.cc pix_opencv_morphology.cc pix_opencv_distrans.cc pix_opencv_motempl.cc pix_opencv_haarcascade.cc pix_opencv_contours_boundingrect.cc pix_opencv_bgsubstract.cc pix_opencv_contours_convexity.cc pix_opencv_dft.cc pix_opencv_lk.cc pix_opencv_hist_compare.cc pix_opencv_knear.cc pix_opencv_threshold.cc pix_opencv_floodfill.cc pix_opencv_athreshold.cc pix_opencv_bgstats.cc pix_opencv_camshift.cc pix_opencv_hu_compare.cc pix_opencv_pgh_compare.cc pix_opencv_hough_circles.cc pix_opencv_hough_lines.cc
all: $(SOURCES:.cc=.$(EXTENSION))
diff --git a/pix_opencv_hough_circles.cc b/pix_opencv_hough_circles.cc
index 40595d1..2ebbdcf 100755
--- a/pix_opencv_hough_circles.cc
+++ b/pix_opencv_hough_circles.cc
@@ -202,21 +202,22 @@ void pix_opencv_hough_circles :: processGrayImage(imageStruct &image)
memcpy( gray->imageData, image.data, image.xsize*image.ysize );
- if( night_mode )
- cvZero( gray );
-
x_storage = cvCreateMemStorage(0);
cvSmooth( gray, gray, CV_GAUSSIAN, 9, 9 );
CvSeq* circles = cvHoughCircles( gray, x_storage, CV_HOUGH_GRADIENT, x_resolution, x_mindist, x_threshold, x_threshold2 );
+
+ if( night_mode )
+ cvZero( gray );
+
ucircles = (circles->total>x_maxcircles)?x_maxcircles:circles->total;
for( i = 0; i < ucircles; i++ )
{
float* p = (float*)cvGetSeqElem( circles, i );
char tindex[10];
- cvCircle( gray, cvPoint(cvRound(p[0]),cvRound(p[1])), 3, CV_RGB(0,255,0), -1, 8, 0 );
- cvCircle( gray, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(255,0,0), 3, 8, 0 );
+ cvCircle( gray, cvPoint(cvRound(p[0]),cvRound(p[1])), 3, CV_RGB(255,255,255), -1, 8, 0 );
+ cvCircle( gray, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(255,255,255), 3, 8, 0 );
SETFLOAT(&x_list[0], i);
SETFLOAT(&x_list[1], cvRound(p[0]));
SETFLOAT(&x_list[2], cvRound(p[1]));
diff --git a/pix_opencv_hough_lines-help.pd b/pix_opencv_hough_lines-help.pd
new file mode 100755
index 0000000..2ac7bf3
--- /dev/null
+++ b/pix_opencv_hough_lines-help.pd
@@ -0,0 +1,163 @@
+#N canvas 0 0 1043 756 10;
+#X obj 396 -37 gemhead;
+#X obj 370 595 pix_texture;
+#X obj 372 616 square 2;
+#X obj 43 200 cnv 15 220 70 empty empty empty 20 12 0 14 -195568 -66577
+0;
+#N canvas 0 22 454 304 gemwin 0;
+#X obj 67 89 outlet;
+#X obj 67 10 inlet;
+#X obj 67 41 route create;
+#X msg 67 70 set destroy;
+#X msg 182 68 set create;
+#N canvas 87 154 247 179 Gem.init 0;
+#X obj 118 46 loadbang;
+#X msg 118 81 reset;
+#X obj 118 113 outlet;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X restore 289 80 pd Gem.init;
+#X obj 160 260 gemwin;
+#X msg 159 207 create \, 1;
+#X msg 235 208 destroy;
+#X msg 281 180 frame 5;
+#X obj 162 170 t b b b;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X connect 2 0 10 0;
+#X connect 2 1 4 0;
+#X connect 2 1 8 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 7 0 6 0;
+#X connect 8 0 6 0;
+#X connect 9 0 6 0;
+#X connect 10 0 7 0;
+#X connect 10 2 9 0;
+#X restore 47 245 pd gemwin;
+#X msg 48 220 destroy;
+#X text 45 203 Create window and render;
+#X obj 216 478 pix_texture;
+#X obj 216 506 square 2;
+#X obj 364 112 translateXYZ -2 0 0;
+#X obj 365 138 separator;
+#X obj 344 187 cnv 15 600 400 empty empty empty 20 12 0 14 -24198 -66577
+0;
+#X obj 511 -66 bng 25 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 524 128 unpack 0 0 0;
+#X floatatom 514 151 5 0 0 3 length - -;
+#X floatatom 563 151 5 0 0 3 width - -;
+#X floatatom 613 151 5 0 0 3 height - -;
+#X obj 568 109 bng 15 250 50 0 empty empty end_reached 20 7 0 10 -262144
+-1 -1;
+#X floatatom 550 74 5 0 10000 1 frame# - -;
+#X obj 511 -37 openpanel;
+#X msg 511 -17 open \$1;
+#X obj 499 92 pix_film;
+#X msg 517 26 auto \$1;
+#X obj 517 8 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 366 163 translateXYZ 4 0 0;
+#X obj 580 26 loadbang;
+#X msg 580 51 colorspace RGBA;
+#X msg 685 51 colorspace RGB;
+#X msg 789 51 colorspace Grey;
+#X obj 370 486 pix_opencv_hough_lines;
+#X obj 554 456 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X msg 469 454 nightmode \$1;
+#X text 573 457 set nightmode;
+#X floatatom 500 304 5 0 0 0 - - -;
+#X msg 399 270 mode \$1;
+#X obj 495 241 vradio 15 1 0 3 empty empty empty 0 -8 0 10 -262144
+-1 -1 0;
+#X text 516 241 CV_HOUGH_STANDARD;
+#X text 516 255 CV_HOUGH_PROBABILISTIC;
+#X text 517 271 CV_HOUGN_MULTI_SCALE;
+#X msg 411 301 threshold \$1;
+#X msg 425 331 minlength \$1;
+#X floatatom 511 332 5 0 0 0 - - -;
+#X floatatom 491 358 5 0 0 0 - - -;
+#X msg 440 357 gap \$1;
+#X text 534 358 gap betwwen lines ( default 10 \, for mode CV_HOUGH_PROBABILISTIC
+);
+#X text 548 329 minimum length ( default 30 \, for mode CV_HOUGH_PROBABILISTIC
+);
+#X floatatom 545 396 5 0 0 0 - - -;
+#X floatatom 567 428 5 0 0 0 - - -;
+#X msg 444 394 aresolution \$1;
+#X msg 462 426 dresolutyion \$1;
+#X text 611 424 distance resolution ( default 1 \, for mode CV_HOUGH_MULTI_SCALE
+);
+#X text 583 393 angle resolution ( default 1 \, for mode CV_HOUGH_MULTI_SCALE
+);
+#X msg 385 200 maxlines \$1;
+#X floatatom 464 201 5 0 0 0 - - -;
+#X text 505 197 maximum nuber of lines detected ( default : 10 );
+#X text 539 300 threshold ( default 50 );
+#X text 404 223 Detection mode ( default : CV_HOUGH_PROBABILISTIC )
+;
+#X floatatom 514 555 5 0 0 0 - - -;
+#X floatatom 550 556 5 0 0 0 - - -;
+#X obj 514 515 route 1 2 3 4 5 6 7 8 9 10;
+#X text 683 514 position of each line;
+#X obj 514 535 unpack f f f f;
+#X text 517 569 X1;
+#X text 553 569 Y1;
+#X floatatom 587 556 5 0 0 0 - - -;
+#X floatatom 623 557 5 0 0 0 - - -;
+#X text 590 570 X2;
+#X text 626 570 Y2;
+#X text 68 59 written by Lluis Gomez i Bigorda ( lluisgomez@hangar.org
+) and Yves Degoyon ( ydegoyon@gmail.com );
+#X text 67 44 pix_opencv_hough_lines : Hough lines algorithm;
+#X connect 0 0 21 0;
+#X connect 1 0 2 0;
+#X connect 4 0 5 0;
+#X connect 5 0 4 0;
+#X connect 7 0 8 0;
+#X connect 9 0 7 0;
+#X connect 9 0 10 0;
+#X connect 10 0 24 0;
+#X connect 12 0 19 0;
+#X connect 13 0 14 0;
+#X connect 13 1 15 0;
+#X connect 13 2 16 0;
+#X connect 17 0 18 0;
+#X connect 18 0 21 1;
+#X connect 19 0 20 0;
+#X connect 20 0 21 0;
+#X connect 21 0 9 0;
+#X connect 21 1 13 0;
+#X connect 21 2 17 0;
+#X connect 22 0 21 0;
+#X connect 23 0 22 0;
+#X connect 24 0 29 0;
+#X connect 25 0 26 0;
+#X connect 26 0 21 0;
+#X connect 27 0 21 0;
+#X connect 28 0 21 0;
+#X connect 29 0 1 0;
+#X connect 29 1 59 0;
+#X connect 30 0 31 0;
+#X connect 31 0 29 0;
+#X connect 33 0 39 0;
+#X connect 34 0 29 0;
+#X connect 35 0 34 0;
+#X connect 39 0 29 0;
+#X connect 40 0 29 0;
+#X connect 41 0 40 0;
+#X connect 42 0 43 0;
+#X connect 43 0 29 0;
+#X connect 46 0 48 0;
+#X connect 47 0 49 0;
+#X connect 48 0 29 0;
+#X connect 49 0 29 0;
+#X connect 52 0 29 0;
+#X connect 53 0 52 0;
+#X connect 59 0 61 0;
+#X connect 61 0 57 0;
+#X connect 61 1 58 0;
+#X connect 61 2 64 0;
+#X connect 61 3 65 0;
diff --git a/pix_opencv_hough_lines.cc b/pix_opencv_hough_lines.cc
new file mode 100755
index 0000000..cf84305
--- /dev/null
+++ b/pix_opencv_hough_lines.cc
@@ -0,0 +1,600 @@
+////////////////////////////////////////////////////////
+//
+// 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.
+//
+/////////////////////////////////////////////////////////
+
+#include "pix_opencv_hough_lines.h"
+#include <stdio.h>
+
+CPPEXTERN_NEW(pix_opencv_hough_lines)
+
+/////////////////////////////////////////////////////////
+//
+// pix_opencv_hough_lines
+//
+/////////////////////////////////////////////////////////
+// Constructor
+//
+/////////////////////////////////////////////////////////
+
+pix_opencv_hough_lines :: pix_opencv_hough_lines()
+{
+ int i;
+
+ comp_xsize=320;
+ comp_ysize=240;
+
+ m_dataout = outlet_new(this->x_obj, &s_anything);
+
+ x_mode = CV_HOUGH_PROBABILISTIC;
+ x_threshold = 50;
+ x_maxlines = 10;
+ x_minlength = 30.0;
+ x_gap = 10.0;
+ x_aresolution = 10.0;
+ x_dresolution = 30.0;
+ night_mode = 0;
+
+ cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, 1.0, 1.0, 0, 1, 8 );
+
+ rgba = cvCreateImage(cvSize(comp_xsize,comp_ysize), IPL_DEPTH_8U, 4);
+ rgb = cvCreateImage(cvSize(comp_xsize,comp_ysize), IPL_DEPTH_8U, 3);
+ gray = cvCreateImage(cvSize(comp_xsize,comp_ysize), IPL_DEPTH_8U, 1);
+
+}
+
+/////////////////////////////////////////////////////////
+// Destructor
+//
+/////////////////////////////////////////////////////////
+pix_opencv_hough_lines :: ~pix_opencv_hough_lines()
+{
+ //Destroy cv_images to clean memory
+ cvReleaseImage(&rgba);
+ cvReleaseImage(&rgb);
+ cvReleaseImage(&gray);
+}
+
+/////////////////////////////////////////////////////////
+// processImage
+//
+/////////////////////////////////////////////////////////
+void pix_opencv_hough_lines :: processRGBAImage(imageStruct &image)
+{
+ int i, ulines;
+
+ if ((this->comp_xsize!=image.xsize)&&(this->comp_ysize!=image.ysize))
+ {
+
+ this->comp_xsize=image.xsize;
+ this->comp_ysize=image.ysize;
+
+ cvReleaseImage(&rgba);
+ cvReleaseImage(&rgb);
+ cvReleaseImage(&gray);
+
+ rgba = cvCreateImage(cvSize(comp_xsize,comp_ysize), IPL_DEPTH_8U, 4);
+ rgb = cvCreateImage(cvSize(comp_xsize,comp_ysize), IPL_DEPTH_8U, 3);
+ gray = cvCreateImage(cvSize(comp_xsize,comp_ysize), IPL_DEPTH_8U, 1);
+
+ }
+
+ memcpy( rgba->imageData, image.data, image.xsize*image.ysize*4 );
+ cvCvtColor( rgba, gray, CV_BGRA2GRAY );
+
+ cvCanny( gray, gray, 50, 200, 3 );
+
+ if( night_mode )
+ cvZero( rgba );
+
+ x_storage = cvCreateMemStorage(0);
+
+ switch( x_mode )
+ {
+ case CV_HOUGH_STANDARD:
+
+ x_lines = cvHoughLines2( gray, x_storage, x_mode, 1, CV_PI/180, x_threshold, 0, 0 );
+
+ if ( x_lines )
+ {
+ ulines = ( x_lines->total >= x_maxlines ) ? x_maxlines:x_lines->total;
+ for( i=0; i<ulines; i++ )
+ {
+ float* line = (float*)cvGetSeqElem(x_lines,i);
+ float rho = line[0];
+ float theta = line[1];
+ CvPoint pt1, pt2;
+ char tindex[10];
+ double a = cos(theta), b = sin(theta);
+ double x0 = a*rho, y0 = b*rho;
+ pt1.x = cvRound(x0 + 1000*(-b));
+ pt1.y = cvRound(y0 + 1000*(a));
+ pt2.x = cvRound(x0 - 1000*(-b));
+ pt2.y = cvRound(y0 - 1000*(a));
+ cvLine( rgba, pt1, pt2, CV_RGB(255,0,0), 3, 8 );
+ SETFLOAT(&x_list[0], i);
+ SETFLOAT(&x_list[1], pt1.x);
+ SETFLOAT(&x_list[2], pt1.y);
+ SETFLOAT(&x_list[3], pt2.x);
+ SETFLOAT(&x_list[4], pt2.y);
+ outlet_list( m_dataout, 0, 5, x_list );
+ pt1.x = (pt1.x+pt2.x)/2;
+ pt1.y = (pt1.y+pt2.y)/2;
+ sprintf( tindex, "%d", i );
+ cvPutText( rgba, tindex, pt1, &font, CV_RGB(255,255,255));
+ }
+ }
+ break;
+
+ case CV_HOUGH_PROBABILISTIC:
+
+ x_lines = cvHoughLines2( gray, x_storage, x_mode, 1, CV_PI/180, x_threshold, x_minlength, x_gap );
+
+ if ( x_lines )
+ {
+ ulines = ( x_lines->total >= x_maxlines ) ? x_maxlines:x_lines->total;
+ for( i=0; i<ulines; i++ )
+ {
+ CvPoint* line = (CvPoint*)cvGetSeqElem(x_lines,i);
+ char tindex[10];
+ cvLine( rgba, line[0], line[1], CV_RGB(255,0,0), 3, 8 );
+ SETFLOAT(&x_list[0], i);
+ SETFLOAT(&x_list[1], line[0].x);
+ SETFLOAT(&x_list[2], line[0].y);
+ SETFLOAT(&x_list[3], line[1].x);
+ SETFLOAT(&x_list[4], line[1].y);
+ outlet_list( m_dataout, 0, 5, x_list );
+ line[0].x = (line[0].x+line[1].x)/2;
+ line[0].y = (line[0].y+line[1].y)/2;
+ sprintf( tindex, "%d", i );
+ cvPutText( rgba, tindex, line[0], &font, CV_RGB(255,255,255));
+ }
+ }
+ break;
+
+ case CV_HOUGH_MULTI_SCALE:
+
+ x_lines = cvHoughLines2( gray, x_storage, x_mode, 1, CV_PI/180, x_threshold, x_dresolution, x_aresolution );
+
+ if ( x_lines )
+ {
+ ulines = ( x_lines->total >= x_maxlines ) ? x_maxlines:x_lines->total;
+ for( i = 0; i < ulines; i++ )
+ {
+ float* line = (float*)cvGetSeqElem(x_lines,i);
+ float rho = line[0];
+ float theta = line[1];
+ char tindex[10];
+ CvPoint pt1, pt2;
+ double a = cos(theta), b = sin(theta);
+ double x0 = a*rho, y0 = b*rho;
+ pt1.x = cvRound(x0 + 1000*(-b));
+ pt1.y = cvRound(y0 + 1000*(a));
+ pt2.x = cvRound(x0 - 1000*(-b));
+ pt2.y = cvRound(y0 - 1000*(a));
+ cvLine( rgba, pt1, pt2, CV_RGB(255,0,0), 3, 8 );
+ SETFLOAT(&x_list[0], i);
+ SETFLOAT(&x_list[1], pt1.x);
+ SETFLOAT(&x_list[2], pt1.y);
+ SETFLOAT(&x_list[3], pt2.x);
+ SETFLOAT(&x_list[4], pt2.y);
+ outlet_list( m_dataout, 0, 5, x_list );
+ pt1.x = (pt1.x+pt2.x)/2;
+ pt1.y = (pt1.y+pt2.y)/2;
+ sprintf( tindex, "%d", i );
+ cvPutText( rgba, tindex, pt1, &font, CV_RGB(255,255,255));
+ }
+ }
+ break;
+ }
+
+ cvReleaseMemStorage( &x_storage );
+ memcpy( image.data, rgba->imageData, image.xsize*image.ysize*4 );
+
+}
+
+void pix_opencv_hough_lines :: processRGBImage(imageStruct &image)
+{
+ int i, ulines;
+
+ if ((this->comp_xsize!=image.xsize)&&(this->comp_ysize!=image.ysize))
+ {
+
+ this->comp_xsize=image.xsize;
+ this->comp_ysize=image.ysize;
+
+ cvReleaseImage(&rgba);
+ cvReleaseImage(&rgb);
+ cvReleaseImage(&gray);
+
+ rgba = cvCreateImage(cvSize(comp_xsize,comp_ysize), IPL_DEPTH_8U, 4);
+ rgb = cvCreateImage(cvSize(comp_xsize,comp_ysize), IPL_DEPTH_8U, 3);
+ gray = cvCreateImage(cvSize(comp_xsize,comp_ysize), IPL_DEPTH_8U, 1);
+
+ }
+
+ memcpy( rgb->imageData, image.data, image.xsize*image.ysize*3 );
+ cvCvtColor( rgb, gray, CV_BGR2GRAY );
+
+ cvCanny( gray, gray, 50, 200, 3 );
+
+ if( night_mode )
+ cvZero( rgb );
+
+ x_storage = cvCreateMemStorage(0);
+
+ switch( x_mode )
+ {
+ case CV_HOUGH_STANDARD:
+
+ x_lines = cvHoughLines2( gray, x_storage, x_mode, 1, CV_PI/180, x_threshold, 0, 0 );
+
+ if ( x_lines )
+ {
+ ulines = ( x_lines->total >= x_maxlines ) ? x_maxlines:x_lines->total;
+ for( i=0; i<ulines; i++ )
+ {
+ float* line = (float*)cvGetSeqElem(x_lines,i);
+ float rho = line[0];
+ float theta = line[1];
+ CvPoint pt1, pt2;
+ char tindex[10];
+ double a = cos(theta), b = sin(theta);
+ double x0 = a*rho, y0 = b*rho;
+ pt1.x = cvRound(x0 + 1000*(-b));
+ pt1.y = cvRound(y0 + 1000*(a));
+ pt2.x = cvRound(x0 - 1000*(-b));
+ pt2.y = cvRound(y0 - 1000*(a));
+ cvLine( rgb, pt1, pt2, CV_RGB(255,0,0), 3, 8 );
+ SETFLOAT(&x_list[0], i);
+ SETFLOAT(&x_list[1], pt1.x);
+ SETFLOAT(&x_list[2], pt1.y);
+ SETFLOAT(&x_list[3], pt2.x);
+ SETFLOAT(&x_list[4], pt2.y);
+ outlet_list( m_dataout, 0, 5, x_list );
+ pt1.x = (pt1.x+pt2.x)/2;
+ pt1.y = (pt1.y+pt2.y)/2;
+ sprintf( tindex, "%d", i );
+ cvPutText( rgb, tindex, pt1, &font, CV_RGB(255,255,255));
+ }
+ }
+ break;
+
+ case CV_HOUGH_PROBABILISTIC:
+
+ x_lines = cvHoughLines2( gray, x_storage, x_mode, 1, CV_PI/180, x_threshold, x_minlength, x_gap );
+
+ if ( x_lines )
+ {
+ ulines = ( x_lines->total >= x_maxlines ) ? x_maxlines:x_lines->total;
+ for( i=0; i<ulines; i++ )
+ {
+ CvPoint* line = (CvPoint*)cvGetSeqElem(x_lines,i);
+ char tindex[10];
+ cvLine( rgb, line[0], line[1], CV_RGB(255,0,0), 3, 8 );
+ SETFLOAT(&x_list[0], i);
+ SETFLOAT(&x_list[1], line[0].x);
+ SETFLOAT(&x_list[2], line[0].y);
+ SETFLOAT(&x_list[3], line[1].x);
+ SETFLOAT(&x_list[4], line[1].y);
+ outlet_list( m_dataout, 0, 5, x_list );
+ line[0].x = (line[0].x+line[1].x)/2;
+ line[0].y = (line[0].y+line[1].y)/2;
+ sprintf( tindex, "%d", i );
+ cvPutText( rgb, tindex, line[0], &font, CV_RGB(255,255,255));
+ }
+ }
+ break;
+
+ case CV_HOUGH_MULTI_SCALE:
+
+ x_lines = cvHoughLines2( gray, x_storage, x_mode, 1, CV_PI/180, x_threshold, x_dresolution, x_aresolution );
+
+ if ( x_lines )
+ {
+ ulines = ( x_lines->total >= x_maxlines ) ? x_maxlines:x_lines->total;
+ for( i = 0; i < ulines; i++ )
+ {
+ float* line = (float*)cvGetSeqElem(x_lines,i);
+ float rho = line[0];
+ float theta = line[1];
+ char tindex[10];
+ CvPoint pt1, pt2;
+ double a = cos(theta), b = sin(theta);
+ double x0 = a*rho, y0 = b*rho;
+ pt1.x = cvRound(x0 + 1000*(-b));
+ pt1.y = cvRound(y0 + 1000*(a));
+ pt2.x = cvRound(x0 - 1000*(-b));
+ pt2.y = cvRound(y0 - 1000*(a));
+ cvLine( rgb, pt1, pt2, CV_RGB(255,0,0), 3, 8 );
+ SETFLOAT(&x_list[0], i);
+ SETFLOAT(&x_list[1], pt1.x);
+ SETFLOAT(&x_list[2], pt1.y);
+ SETFLOAT(&x_list[3], pt2.x);
+ SETFLOAT(&x_list[4], pt2.y);
+ outlet_list( m_dataout, 0, 5, x_list );
+ pt1.x = (pt1.x+pt2.x)/2;
+ pt1.y = (pt1.y+pt2.y)/2;
+ sprintf( tindex, "%d", i );
+ cvPutText( rgb, tindex, pt1, &font, CV_RGB(255,255,255));
+ }
+ }
+ break;
+ }
+
+ cvReleaseMemStorage( &x_storage );
+ memcpy( image.data, rgb->imageData, image.xsize*image.ysize*3 );
+
+}
+
+void pix_opencv_hough_lines :: processYUVImage(imageStruct &image)
+{
+ post( "pix_opencv_hough_lines : yuv format not supported" );
+}
+
+void pix_opencv_hough_lines :: processGrayImage(imageStruct &image)
+{
+ int i, ulines;
+
+ if ((this->comp_xsize!=image.xsize)&&(this->comp_ysize!=image.ysize))
+ {
+
+ this->comp_xsize=image.xsize;
+ this->comp_ysize=image.ysize;
+
+ cvReleaseImage(&rgba);
+ cvReleaseImage(&rgb);
+ cvReleaseImage(&gray);
+
+ rgba = cvCreateImage(cvSize(comp_xsize,comp_ysize), IPL_DEPTH_8U, 4);
+ rgb = cvCreateImage(cvSize(comp_xsize,comp_ysize), IPL_DEPTH_8U, 3);
+ gray = cvCreateImage(cvSize(comp_xsize,comp_ysize), IPL_DEPTH_8U, 1);
+
+ }
+
+ memcpy( gray->imageData, image.data, image.xsize*image.ysize );
+ cvCanny( gray, gray, 50, 200, 3 );
+
+ x_storage = cvCreateMemStorage(0);
+
+ switch( x_mode )
+ {
+ case CV_HOUGH_STANDARD:
+
+ x_lines = cvHoughLines2( gray, x_storage, x_mode, 1, CV_PI/180, x_threshold, 0, 0 );
+
+ if( night_mode )
+ cvZero( gray );
+
+ if ( x_lines )
+ {
+ ulines = ( x_lines->total >= x_maxlines ) ? x_maxlines:x_lines->total;
+ for( i=0; i<ulines; i++ )
+ {
+ float* line = (float*)cvGetSeqElem(x_lines,i);
+ float rho = line[0];
+ float theta = line[1];
+ CvPoint pt1, pt2;
+ char tindex[10];
+ double a = cos(theta), b = sin(theta);
+ double x0 = a*rho, y0 = b*rho;
+ pt1.x = cvRound(x0 + 1000*(-b));
+ pt1.y = cvRound(y0 + 1000*(a));
+ pt2.x = cvRound(x0 - 1000*(-b));
+ pt2.y = cvRound(y0 - 1000*(a));
+ cvLine( gray, pt1, pt2, CV_RGB(255,255,255), 3, 8 );
+ SETFLOAT(&x_list[0], i);
+ SETFLOAT(&x_list[1], pt1.x);
+ SETFLOAT(&x_list[2], pt1.y);
+ SETFLOAT(&x_list[3], pt2.x);
+ SETFLOAT(&x_list[4], pt2.y);
+ outlet_list( m_dataout, 0, 5, x_list );
+ pt1.x = (pt1.x+pt2.x)/2;
+ pt1.y = (pt1.y+pt2.y)/2;
+ sprintf( tindex, "%d", i );
+ cvPutText( gray, tindex, pt1, &font, CV_RGB(255,255,255));
+ }
+ }
+ break;
+
+ case CV_HOUGH_PROBABILISTIC:
+
+ x_lines = cvHoughLines2( gray, x_storage, x_mode, 1, CV_PI/180, x_threshold, x_minlength, x_gap );
+
+ if( night_mode )
+ cvZero( gray );
+
+ if ( x_lines )
+ {
+ ulines = ( x_lines->total >= x_maxlines ) ? x_maxlines:x_lines->total;
+ for( i=0; i<ulines; i++ )
+ {
+ CvPoint* line = (CvPoint*)cvGetSeqElem(x_lines,i);
+ char tindex[10];
+ cvLine( gray, line[0], line[1], CV_RGB(255,255,255), 3, 8 );
+ SETFLOAT(&x_list[0], i);
+ SETFLOAT(&x_list[1], line[0].x);
+ SETFLOAT(&x_list[2], line[0].y);
+ SETFLOAT(&x_list[3], line[1].x);
+ SETFLOAT(&x_list[4], line[1].y);
+ outlet_list( m_dataout, 0, 5, x_list );
+ line[0].x = (line[0].x+line[1].x)/2;
+ line[0].y = (line[0].y+line[1].y)/2;
+ sprintf( tindex, "%d", i );
+ cvPutText( gray, tindex, line[0], &font, CV_RGB(255,255,255));
+ }
+ }
+ break;
+
+ case CV_HOUGH_MULTI_SCALE:
+
+ x_lines = cvHoughLines2( gray, x_storage, x_mode, 1, CV_PI/180, x_threshold, x_dresolution, x_aresolution );
+
+ if( night_mode )
+ cvZero( gray );
+
+ if ( x_lines )
+ {
+ ulines = ( x_lines->total >= x_maxlines ) ? x_maxlines:x_lines->total;
+ for( i = 0; i < ulines; i++ )
+ {
+ float* line = (float*)cvGetSeqElem(x_lines,i);
+ float rho = line[0];
+ float theta = line[1];
+ char tindex[10];
+ CvPoint pt1, pt2;
+ double a = cos(theta), b = sin(theta);
+ double x0 = a*rho, y0 = b*rho;
+ pt1.x = cvRound(x0 + 1000*(-b));
+ pt1.y = cvRound(y0 + 1000*(a));
+ pt2.x = cvRound(x0 - 1000*(-b));
+ pt2.y = cvRound(y0 - 1000*(a));
+ cvLine( gray, pt1, pt2, CV_RGB(255,255,255), 3, 8 );
+ SETFLOAT(&x_list[0], i);
+ SETFLOAT(&x_list[1], pt1.x);
+ SETFLOAT(&x_list[2], pt1.y);
+ SETFLOAT(&x_list[3], pt2.x);
+ SETFLOAT(&x_list[4], pt2.y);
+ outlet_list( m_dataout, 0, 5, x_list );
+ pt1.x = (pt1.x+pt2.x)/2;
+ pt1.y = (pt1.y+pt2.y)/2;
+ sprintf( tindex, "%d", i );
+ cvPutText( gray, tindex, pt1, &font, CV_RGB(255,255,255));
+ }
+ }
+ break;
+ }
+
+ cvReleaseMemStorage( &x_storage );
+ memcpy( image.data, gray->imageData, image.xsize*image.ysize );
+
+}
+
+/////////////////////////////////////////////////////////
+// static member function
+//
+/////////////////////////////////////////////////////////
+
+void pix_opencv_hough_lines :: obj_setupCallback(t_class *classPtr)
+{
+ class_addmethod(classPtr, (t_method)&pix_opencv_hough_lines::floatNightModeMessCallback,
+ gensym("nightmode"), A_FLOAT, A_NULL);
+ class_addmethod(classPtr, (t_method)&pix_opencv_hough_lines::floatModeMessCallback,
+ gensym("mode"), A_FLOAT, A_NULL);
+ class_addmethod(classPtr, (t_method)&pix_opencv_hough_lines::floatThresholdMessCallback,
+ gensym("threshold"), A_FLOAT, A_NULL);
+ class_addmethod(classPtr, (t_method)&pix_opencv_hough_lines::floatMinLengthMessCallback,
+ gensym("minlength"), A_FLOAT, A_NULL);
+ class_addmethod(classPtr, (t_method)&pix_opencv_hough_lines::floatGapMessCallback,
+ gensym("gap"), A_FLOAT, A_NULL);
+ class_addmethod(classPtr, (t_method)&pix_opencv_hough_lines::floatAResolutionMessCallback,
+ gensym("aresolution"), A_FLOAT, A_NULL);
+ class_addmethod(classPtr, (t_method)&pix_opencv_hough_lines::floatDResolutionMessCallback,
+ gensym("dresolution"), A_FLOAT, A_NULL);
+ class_addmethod(classPtr, (t_method)&pix_opencv_hough_lines::floatMaxLinesMessCallback,
+ gensym("maxlines"), A_FLOAT, A_NULL);
+}
+
+void pix_opencv_hough_lines :: floatNightModeMessCallback(void *data, t_floatarg nightmode)
+{
+ GetMyClass(data)->floatNightModeMess((float)nightmode);
+}
+
+void pix_opencv_hough_lines :: floatModeMessCallback(void *data, t_floatarg mode)
+{
+ GetMyClass(data)->floatModeMess((float)mode);
+}
+
+void pix_opencv_hough_lines :: floatThresholdMessCallback(void *data, t_floatarg threshold)
+{
+ GetMyClass(data)->floatThresholdMess((float)threshold);
+}
+
+void pix_opencv_hough_lines :: floatMinLengthMessCallback(void *data, t_floatarg minlength)
+{
+ GetMyClass(data)->floatMinLengthMess((float)minlength);
+}
+
+void pix_opencv_hough_lines :: floatGapMessCallback(void *data, t_floatarg gap)
+{
+ GetMyClass(data)->floatGapMess((float)gap);
+}
+
+void pix_opencv_hough_lines :: floatAResolutionMessCallback(void *data, t_floatarg aresolution)
+{
+ GetMyClass(data)->floatAResolutionMess((float)aresolution);
+}
+
+void pix_opencv_hough_lines :: floatDResolutionMessCallback(void *data, t_floatarg dresolution)
+{
+ GetMyClass(data)->floatDResolutionMess((float)dresolution);
+}
+
+void pix_opencv_hough_lines :: floatMaxLinesMessCallback(void *data, t_floatarg maxlines)
+{
+ GetMyClass(data)->floatMaxLinesMess((float)maxlines);
+}
+
+void pix_opencv_hough_lines :: floatNightModeMess(float nightmode)
+{
+ if ((nightmode==0.0)||(nightmode==1.0)) night_mode = (int)nightmode;
+}
+
+void pix_opencv_hough_lines :: floatModeMess(float mode)
+{
+ if ( mode == CV_HOUGH_STANDARD )
+ {
+ x_mode = CV_HOUGH_STANDARD;
+ }
+ if ( mode == CV_HOUGH_PROBABILISTIC )
+ {
+ x_mode = CV_HOUGH_PROBABILISTIC;
+ }
+ if ( mode == CV_HOUGH_MULTI_SCALE )
+ {
+ x_mode = CV_HOUGH_MULTI_SCALE;
+ }
+}
+
+void pix_opencv_hough_lines :: floatThresholdMess(float threshold)
+{
+ if (threshold>0.0) x_threshold = (int)threshold;
+}
+
+void pix_opencv_hough_lines :: floatMinLengthMess(float minlength)
+{
+ if (minlength>0.0) x_minlength = (double)minlength;
+}
+
+void pix_opencv_hough_lines :: floatGapMess(float gap)
+{
+ if (gap>0.0) x_gap = (double)gap;
+}
+
+void pix_opencv_hough_lines :: floatAResolutionMess(float aresolution)
+{
+ if (aresolution>0.0) x_aresolution = (double)aresolution;
+}
+
+void pix_opencv_hough_lines :: floatDResolutionMess(float dresolution)
+{
+ if (dresolution>0.0) x_dresolution = (double)dresolution;
+}
+
+void pix_opencv_hough_lines :: floatMaxLinesMess(float maxlines)
+{
+ if (maxlines>0.0) x_maxlines = (int)maxlines;
+}
+
diff --git a/pix_opencv_hough_lines.h b/pix_opencv_hough_lines.h
new file mode 100755
index 0000000..a0aaef4
--- /dev/null
+++ b/pix_opencv_hough_lines.h
@@ -0,0 +1,110 @@
+/*-----------------------------------------------------------------
+LOG
+ GEM - Graphics Environment for Multimedia
+
+ Hough lines detection algorithm
+
+ Copyright (c) 1997-1999 Mark Danks. mark@danks.org
+ Copyright (c) Günther Geiger. geiger@epy.co.at
+ Copyright (c) 2001-2002 IOhannes m zmoelnig. forum::für::umläute. IEM. zmoelnig@iem.kug.ac.at
+ 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.
+
+-----------------------------------------------------------------*/
+
+#ifndef INCLUDE_PIX_OPENCV_HOUGH_LINES_H_
+#define INCLUDE_PIX_OPENCV_HOUGH_LINES_H_
+
+#include "Base/GemPixObj.h"
+
+#ifndef _EiC
+#include "cv.h"
+#endif
+
+#define MAX_HISTOGRAMS_TO_COMPARE 80
+
+/*-----------------------------------------------------------------
+-------------------------------------------------------------------
+CLASS
+ pix_opencv_hough_lines
+
+ Hough lines detection algorithm
+
+KEYWORDS
+ pix
+
+DESCRIPTION
+
+-----------------------------------------------------------------*/
+
+class GEM_EXTERN pix_opencv_hough_lines : public GemPixObj
+{
+ CPPEXTERN_HEADER(pix_opencv_hough_lines, GemPixObj)
+
+ public:
+
+ //////////
+ // Constructor
+ pix_opencv_hough_lines();
+
+ protected:
+
+ //////////
+ // Destructor
+ virtual ~pix_opencv_hough_lines();
+
+ //////////
+ // Do the processing
+ virtual void processRGBAImage(imageStruct &image);
+ virtual void processRGBImage(imageStruct &image);
+ virtual void processYUVImage(imageStruct &image);
+ virtual void processGrayImage(imageStruct &image);
+
+ int comp_xsize;
+ int comp_ysize;
+
+ void floatNightModeMess(t_float nightmode);
+ void floatModeMess(t_floatarg mode);
+ void floatThresholdMess(t_floatarg threshold);
+ void floatMinLengthMess(t_floatarg minlength);
+ void floatGapMess(t_floatarg gap);
+ void floatAResolutionMess(t_floatarg aresolution);
+ void floatDResolutionMess(t_floatarg dresolution);
+ void floatMaxLinesMess(t_floatarg maxlines);
+
+ t_outlet *m_dataout;
+
+ int x_mode;
+ int x_threshold;
+ int x_maxlines;
+ double x_minlength;
+ double x_gap;
+ double x_aresolution;
+ double x_dresolution;
+ int night_mode;
+
+ private:
+
+ //////////
+ // Static member functions
+ static void floatNightModeMessCallback(void *data, t_float nightmode);
+ static void floatModeMessCallback(void *data, t_floatarg mode);
+ static void floatThresholdMessCallback(void *data, t_floatarg threshold);
+ static void floatMinLengthMessCallback(void *data, t_floatarg minlength);
+ static void floatGapMessCallback(void *data, t_floatarg gap);
+ static void floatAResolutionMessCallback(void *data, t_floatarg aresolution);
+ static void floatDResolutionMessCallback(void *data, t_floatarg dresolution);
+ static void floatMaxLinesMessCallback(void *data, t_floatarg maxlines);
+
+ // The output and temporary images
+ IplImage *rgba, *rgb, *gray;
+ t_atom x_list[5];
+
+ CvFont font;
+ CvMemStorage* x_storage;
+ CvSeq* x_lines;
+
+};
+
+#endif // for header file