diff options
-rw-r--r-- | Makefile | 2 | ||||
-rwxr-xr-x | pix_opencv_hough_circles.cc | 11 | ||||
-rwxr-xr-x | pix_opencv_hough_lines-help.pd | 163 | ||||
-rwxr-xr-x | pix_opencv_hough_lines.cc | 600 | ||||
-rwxr-xr-x | pix_opencv_hough_lines.h | 110 |
5 files changed, 880 insertions, 6 deletions
@@ -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 |