From f734109223cbe3d73e1728b4c93f8b4d413995b1 Mon Sep 17 00:00:00 2001 From: "N.N." Date: Sun, 30 Aug 2009 20:39:18 +0000 Subject: added adaptive threshold svn path=/trunk/externals/pix_opencv/; revision=12149 --- pix_opencv_athreshold-help.pd | 122 ++++++++++++++++++++ pix_opencv_athreshold.cc | 258 ++++++++++++++++++++++++++++++++++++++++++ pix_opencv_athreshold.h | 95 ++++++++++++++++ 3 files changed, 475 insertions(+) create mode 100755 pix_opencv_athreshold-help.pd create mode 100644 pix_opencv_athreshold.cc create mode 100644 pix_opencv_athreshold.h diff --git a/pix_opencv_athreshold-help.pd b/pix_opencv_athreshold-help.pd new file mode 100755 index 0000000..7e40898 --- /dev/null +++ b/pix_opencv_athreshold-help.pd @@ -0,0 +1,122 @@ +#N canvas 355 82 925 684 10; +#X obj 277 -24 gemhead; +#X obj 183 555 pix_texture; +#X obj 183 574 square 2; +#X obj 554 196 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 65 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 162 241 gemwin; +#X msg 161 188 create \, 1; +#X msg 237 189 destroy; +#X msg 283 161 frame 15; +#X obj 164 126 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 564 240 pd gemwin; +#X msg 564 222 destroy; +#X obj 29 508 pix_texture; +#X obj 29 536 square 2; +#X obj 158 168 translateXYZ -2 0 0; +#X obj 182 239 separator; +#X obj 170 -57 bng 25 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 337 144 unpack 0 0 0; +#X floatatom 327 167 5 0 0 3 length - -; +#X floatatom 376 167 5 0 0 3 width - -; +#X floatatom 426 167 5 0 0 3 height - -; +#X obj 227 118 bng 15 250 50 0 empty empty end_reached 20 7 0 10 -262144 +-1 -1; +#X floatatom 209 83 5 0 10000 1 frame# - -; +#X obj 170 -28 openpanel; +#X msg 170 -8 open \$1; +#X obj 158 101 pix_film; +#X msg 176 35 auto \$1; +#X obj 176 17 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 181 276 translateXYZ 4 0 0; +#X obj 178 299 cnv 15 600 250 empty empty empty 20 12 0 14 -4034 -66577 +0; +#X text 562 202 Create window and render; +#X msg 187 58 colorspace Grey; +#X obj 183 508 pix_opencv_athreshold; +#X floatatom 360 498 5 0 0 0 - - -; +#X msg 298 405 mode \$1; +#X floatatom 318 472 5 0 0 0 - - -; +#X text 318 458 Max value used in some modes; +#X msg 333 364 0; +#X msg 363 384 1; +#X text 349 405 thresholding mode ( default 0 ); +#X text 365 362 CV_THRESH_BINARY : pixel >= threshold; +#X text 393 384 CV_THRESH_BINARY_INV :pixel <= threshold; +#X text 358 484 blocksize ( 1 \, 3 \, 5 \, 7 \, ... ); +#X text 393 498 ( default 3 ); +#X msg 273 308 0; +#X msg 305 323 1; +#X msg 240 345 method \$1; +#X text 304 344 thresholding method ( default 0 ); +#X text 305 306 CV_ADAPTIVE_THRESH_MEAN_C : mean value; +#X text 337 323 CV_ADAPTIVE_THRESH_GAUSSIAN_C : gaussian mask; +#X msg 319 427 dim \$1; +#X floatatom 370 430 5 0 0 0 - - -; +#X text 410 428 value to correct the theshold; +#X text 399 86 written by Yves Degoyon ( ydegoyon@gmail.com ); +#X text 399 51 use the average of pixels in the block of pixels to +filter only the pixels above or below that threshold \, depending on +the mode BINARY or BINARY:INVERTED; +#X text 400 40 pix_opencv_threshold : adaptive thresholding; +#X connect 0 0 19 0; +#X connect 1 0 2 0; +#X connect 4 0 5 0; +#X connect 5 0 4 0; +#X connect 6 0 7 0; +#X connect 8 0 6 0; +#X connect 8 0 9 0; +#X connect 9 0 22 0; +#X connect 10 0 17 0; +#X connect 11 0 12 0; +#X connect 11 1 13 0; +#X connect 11 2 14 0; +#X connect 15 0 16 0; +#X connect 16 0 19 1; +#X connect 17 0 18 0; +#X connect 18 0 19 0; +#X connect 19 0 8 0; +#X connect 19 1 11 0; +#X connect 19 2 15 0; +#X connect 20 0 19 0; +#X connect 21 0 20 0; +#X connect 22 0 26 0; +#X connect 25 0 19 0; +#X connect 26 0 1 0; +#X connect 27 0 26 2; +#X connect 28 0 26 0; +#X connect 29 0 26 1; +#X connect 31 0 28 0; +#X connect 32 0 28 0; +#X connect 38 0 40 0; +#X connect 39 0 40 0; +#X connect 40 0 26 0; +#X connect 44 0 26 0; +#X connect 45 0 44 0; diff --git a/pix_opencv_athreshold.cc b/pix_opencv_athreshold.cc new file mode 100644 index 0000000..ee819b0 --- /dev/null +++ b/pix_opencv_athreshold.cc @@ -0,0 +1,258 @@ +//////////////////////////////////////////////////////// +// +// 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_athreshold.h" + +CPPEXTERN_NEW(pix_opencv_athreshold) + +///////////////////////////////////////////////////////// +// +// pix_opencv_athreshold +// +///////////////////////////////////////////////////////// +// Constructor +// +///////////////////////////////////////////////////////// +pix_opencv_athreshold :: pix_opencv_athreshold() +{ + inlet_new(this->x_obj, &this->x_obj->ob_pd, gensym("float"), gensym("max_value")); + inlet_new(this->x_obj, &this->x_obj->ob_pd, gensym("float"), gensym("blocksize")); + + max_value = 255; + x_threshold_mode = 0; + x_threshold_method = CV_ADAPTIVE_THRESH_MEAN_C; + x_blocksize = 3; + x_dim = 0; + + comp_xsize=320; + comp_ysize=240; + + 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_athreshold :: ~pix_opencv_athreshold() +{ + //Destroy cv_images to clean memory + cvReleaseImage(&rgba); + cvReleaseImage(&gray); + cvReleaseImage(&rgb); +} + +///////////////////////////////////////////////////////// +// processImage +// +///////////////////////////////////////////////////////// +void pix_opencv_athreshold :: processRGBAImage(imageStruct &image) +{ + unsigned char *pixels = image.data; + + if ((this->comp_xsize!=image.xsize)||(this->comp_ysize!=image.ysize)||(!rgba)) { + + this->comp_xsize = image.xsize; + this->comp_ysize = image.ysize; + + //Destroy cv_images to clean memory + if ( rgba ) + { + cvReleaseImage(&rgba); + cvReleaseImage(&gray); + cvReleaseImage(&rgb); + } + + //create the orig image with new size + rgba = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 4); + rgb = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 3); + gray = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 1); + } + memcpy( rgba->imageData, image.data, image.xsize*image.ysize*4 ); + cvCvtColor(rgba, gray, CV_BGRA2GRAY); + + // Applies fixed-level thresholding to single-channel array. + switch(x_threshold_mode) { + case 0: + cvAdaptiveThreshold(gray, gray, (float)max_value, x_threshold_method, CV_THRESH_BINARY, x_blocksize, x_dim); + break; + case 1: + cvAdaptiveThreshold(gray, gray, (float)max_value, x_threshold_method, CV_THRESH_BINARY_INV, x_blocksize, x_dim); + break; + } + + cvCvtColor(gray, rgba, CV_GRAY2BGRA); + //copy back the processed frame to image + memcpy( image.data, rgba->imageData, image.xsize*image.ysize*4 ); +} + +void pix_opencv_athreshold :: processRGBImage(imageStruct &image) +{ + unsigned char *pixels = image.data; + + if ((this->comp_xsize!=image.xsize)||(this->comp_ysize!=image.ysize)||(!rgb)) { + + this->comp_xsize = image.xsize; + this->comp_ysize = image.ysize; + + //Destroy cv_images to clean memory + if ( rgb ) + { + cvReleaseImage(&rgba); + cvReleaseImage(&gray); + cvReleaseImage(&rgb); + } + + //create the orig image with new size + rgba = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 4); + rgb = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 3); + gray = cvCreateImage(cvSize(rgb->width,rgb->height), IPL_DEPTH_8U, 1); + + } + memcpy( rgb->imageData, image.data, image.xsize*image.ysize*3 ); + cvCvtColor(rgb, gray, CV_RGB2GRAY); + + // Applies fixed-level thresholding to single-channel array. + switch(x_threshold_mode) { + case 0: + cvAdaptiveThreshold(gray, gray, (float)max_value, x_threshold_method, CV_THRESH_BINARY, x_blocksize, x_dim); + break; + case 1: + cvAdaptiveThreshold(gray, gray, (float)max_value, x_threshold_method, CV_THRESH_BINARY_INV, x_blocksize, x_dim); + break; + } + + cvCvtColor(gray, rgb, CV_GRAY2BGR); + memcpy( image.data, rgb->imageData, image.xsize*image.ysize*3 ); +} + +void pix_opencv_athreshold :: processYUVImage(imageStruct &image) +{ + post( "pix_opencv_athreshold : yuv format not supported" ); +} + +void pix_opencv_athreshold :: processGrayImage(imageStruct &image) +{ + unsigned char *pixels = image.data; + + if ((this->comp_xsize!=image.xsize)||(this->comp_ysize!=image.ysize)||(!rgb)) { + + this->comp_xsize = image.xsize; + this->comp_ysize = image.ysize; + + //Destroy cv_images to clean memory + if ( rgb ) + { + cvReleaseImage(&rgba); + cvReleaseImage(&gray); + cvReleaseImage(&rgb); + } + + //create the orig image with new size + rgba = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 4); + rgb = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 3); + gray = cvCreateImage(cvSize(rgb->width,rgb->height), IPL_DEPTH_8U, 1); + + } + memcpy( gray->imageData, image.data, image.xsize*image.ysize ); + + // Applies fixed-level thresholding to single-channel array. + switch(x_threshold_mode) { + case 0: + cvAdaptiveThreshold(gray, gray, (float)max_value, x_threshold_method, CV_THRESH_BINARY, x_blocksize, x_dim); + break; + case 1: + cvAdaptiveThreshold(gray, gray, (float)max_value, x_threshold_method, CV_THRESH_BINARY_INV, x_blocksize, x_dim); + break; + } + + memcpy( image.data, gray->imageData, image.xsize*image.ysize ); +} + +void pix_opencv_athreshold :: floatMaxValueMess (float maxvalue) +{ + if ( (int)maxvalue>0 ) max_value = (int)maxvalue; +} + +void pix_opencv_athreshold :: floatModeMess (float mode) +{ + if ( ( (int)mode==0 ) || ( (int)mode==1 ) ) x_threshold_mode = (int)mode; +} + +void pix_opencv_athreshold :: floatMethodMess (float method) +{ + if ( (int)method==CV_ADAPTIVE_THRESH_MEAN_C ) x_threshold_method = CV_ADAPTIVE_THRESH_MEAN_C; + if ( (int)method==CV_ADAPTIVE_THRESH_GAUSSIAN_C ) x_threshold_method = CV_ADAPTIVE_THRESH_GAUSSIAN_C; +} + +void pix_opencv_athreshold :: floatBlockSizeMess (float blocksize) +{ + if ( ( (int)blocksize>=3 ) && ( (int)(blocksize+1)%2 == 0 ) ) + { + x_blocksize = (int)blocksize; + } +} + +void pix_opencv_athreshold :: floatDimMess (float dim) +{ + if ( (int)dim>0 ) x_dim = (int)dim; +} + +///////////////////////////////////////////////////////// +// static member function +// +///////////////////////////////////////////////////////// +void pix_opencv_athreshold :: obj_setupCallback(t_class *classPtr) +{ + class_addmethod(classPtr, (t_method)&pix_opencv_athreshold::floatModeMessCallback, + gensym("mode"), A_FLOAT, A_NULL); + class_addmethod(classPtr, (t_method)&pix_opencv_athreshold::floatMethodMessCallback, + gensym("method"), A_FLOAT, A_NULL); + class_addmethod(classPtr, (t_method)&pix_opencv_athreshold::floatMaxValueMessCallback, + gensym("max_value"), A_FLOAT, A_NULL); + class_addmethod(classPtr, (t_method)&pix_opencv_athreshold::floatBlockSizeMessCallback, + gensym("blocksize"), A_FLOAT, A_NULL); + class_addmethod(classPtr, (t_method)&pix_opencv_athreshold::floatDimMessCallback, + gensym("dim"), A_FLOAT, A_NULL); +} + +void pix_opencv_athreshold :: floatModeMessCallback(void *data, t_floatarg mode) +{ + GetMyClass(data)->floatModeMess((float)mode); +} + +void pix_opencv_athreshold :: floatMethodMessCallback(void *data, t_floatarg method) +{ + GetMyClass(data)->floatMethodMess((float)method); +} + +void pix_opencv_athreshold :: floatMaxValueMessCallback(void *data, t_floatarg maxvalue) +{ + GetMyClass(data)->floatMaxValueMess((float)maxvalue); +} + +void pix_opencv_athreshold :: floatBlockSizeMessCallback(void *data, t_floatarg blocksize) +{ + GetMyClass(data)->floatBlockSizeMess((float)blocksize); +} + +void pix_opencv_athreshold :: floatDimMessCallback(void *data, t_floatarg dim) +{ + GetMyClass(data)->floatDimMess((float)dim); +} diff --git a/pix_opencv_athreshold.h b/pix_opencv_athreshold.h new file mode 100644 index 0000000..87c8e40 --- /dev/null +++ b/pix_opencv_athreshold.h @@ -0,0 +1,95 @@ +/*----------------------------------------------------------------- +LOG + GEM - Graphics Environment for Multimedia + + Change pix to greyscale + + 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_EDGE_H_ +#define INCLUDE_PIX_OPENCV_EDGE_H_ + +#include "Base/GemPixObj.h" + +#ifndef _EiC +#include "cv.h" +#endif + +/*----------------------------------------------------------------- +------------------------------------------------------------------- +CLASS + pix_opencv_athreshold + + Adapative threshold object + +KEYWORDS + pix + +DESCRIPTION + +-----------------------------------------------------------------*/ +class GEM_EXTERN pix_opencv_athreshold : public GemPixObj +{ + CPPEXTERN_HEADER(pix_opencv_athreshold, GemPixObj) + + public: + + ////////// + // Constructor + pix_opencv_athreshold(); + + protected: + + ////////// + // Destructor + virtual ~pix_opencv_athreshold(); + + ////////// + // Do the processing + virtual void processRGBAImage(imageStruct &image); + virtual void processRGBImage(imageStruct &image); + virtual void processYUVImage(imageStruct &image); + virtual void processGrayImage(imageStruct &image); + + ////////// + // Set the new edge threshold + void floatMaxValueMess(float maxvalue); + void floatModeMess(float mode); + void floatMethodMess(float method); + void floatBlockSizeMess(float blocksize); + void floatDimMess(float dim); + + // The new edge threshold + int max_value; + int x_threshold_mode; + int x_threshold_method; + int x_blocksize; + int x_dim; + + // to detect changes in the image size + int comp_xsize; + int comp_ysize; + + private: + + ////////// + // Static member functions + static void floatMaxValueMessCallback(void *data, float maxvalue); + static void floatModeMessCallback(void *data, float mode); + static void floatMethodMessCallback(void *data, float method); + static void floatBlockSizeMessCallback(void *data, float blocksize); + static void floatDimMessCallback(void *data, float dim); + + ///////// + // IplImage needed + IplImage *rgba, *rgb, *gray; +}; + +#endif // for header file -- cgit v1.2.1