You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(59) |
Jun
(40) |
Jul
(59) |
Aug
(81) |
Sep
(14) |
Oct
(9) |
Nov
(22) |
Dec
(1) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(25) |
Feb
(3) |
Mar
(27) |
Apr
(14) |
May
(15) |
Jun
(112) |
Jul
(44) |
Aug
(7) |
Sep
(18) |
Oct
(34) |
Nov
(17) |
Dec
(20) |
2006 |
Jan
(12) |
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
(3) |
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
(11) |
From: Pierre M. <sid...@us...> - 2005-06-23 20:59:06
|
Update of /cvsroot/robotflow/RobotFlow/Probes/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25030 Modified Files: Makefile.am Log Message: Added SkinColorGMMTrain.cc to file list and include path for Flowdesigner HMM toolbox. Index: Makefile.am =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Probes/src/Makefile.am,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** Makefile.am 2 Jun 2005 16:59:22 -0000 1.13 --- Makefile.am 23 Jun 2005 20:58:56 -0000 1.14 *************** *** 9,13 **** if WITH_OPENCV ! OPENCV_SOURCES = VisualROISelection.cc else OPENCV_SOURCES = --- 9,14 ---- if WITH_OPENCV ! OPENCV_SOURCES = SkinColorGMMTrain.cc \ ! VisualROISelection.cc else OPENCV_SOURCES = *************** *** 33,37 **** INCLUDES = -I../include $(OVERFLOW_INCLUDE) $(GNOME_INCLUDE) \ ! -I../../Vision/include $(SDL_INCLUDE) $(OPENCV_INCLUDES) LDADD = $(SDL_LIB) --- 34,38 ---- INCLUDES = -I../include $(OVERFLOW_INCLUDE) $(GNOME_INCLUDE) \ ! -I../../Vision/include $(SDL_INCLUDE) -I$(OVERFLOW_DATA)/HMM $(OPENCV_INCLUDES) LDADD = $(SDL_LIB) |
From: Pierre M. <sid...@us...> - 2005-06-23 20:57:41
|
Update of /cvsroot/robotflow/RobotFlow/Probes/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24185 Added Files: SkinColorGMMTrain.cc Log Message: Skin color gaussian mixture models training for skin color segmentation in the r-b color space. --- NEW FILE: SkinColorGMMTrain.cc --- /* Copyright (C) 2004 Pierre Moisan (Pie...@US...) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _SKINCOLORGMMTRAIN_CC_ #define _SKINCOLORGMMTRAIN_CC_ #include "Object.h" #include "ObjectRef.h" #include "Exception.h" #include "Image.h" #include "BufferedNode.h" #include <gnome.h> #include <pthread.h> #include "gdk-pixbuf/gdk-pixbuf.h" #include "libgnomecanvas/gnome-canvas-pixbuf.h" #include "cv.h" #include "gmm.h" using namespace FD; using namespace std; namespace RobotFlow { //forward declaration class SkinColorGMMTrain; DECLARE_NODE(SkinColorGMMTrain) /*Node * @name SkinColorGMMTrain * @category RobotFlow:Probes * @description Manual selection of skin and non skin regions to adapt existing skin color models. * * @parameter_name WIDTH * @parameter_description The width of the video frame * @parameter_type int * @parameter_value 320 * * @parameter_name HEIGHT * @parameter_description The height of the video frame * @parameter_type int * @parameter_value 240 * * @parameter_name NUM_CHANNELS * @parameter_type int * @parameter_value 3 * @parameter_description Number of channels of the video frame. * * @parameter_name OUT_MODEL_FILENAME * @parameter_type string * @parameter_value ./ColorGMM * @parameter_description File basename for the models to be saved. * * @parameter_name NUM_SKIN_GAUSSIANS * @parameter_type int * @parameter_value 3 * @parameter_description Number of gaussians to use in the skin mixture model. * * @parameter_name NUM_NONSKIN_GAUSSIANS * @parameter_type int * @parameter_value 3 * @parameter_description Number of gaussians to use in the non skin mixture model. * * @parameter_name SKIN_LOG_LIKELIHOOD_THRESHOLD * @parameter_type float * @parameter_value 10.0 * @parameter_description Log likelihood threshold to consider a pixel as skin. * * @parameter_name NON_SKIN_LOG_LIKELIHOOD_THRESHOLD * @parameter_type float * @parameter_value 10.0 * @parameter_description Log likelihood threshold to consider a pixel as non skin. * * @input_name IN_IMAGE * @input_type Image * @input_description Current frame * * @output_name SEGMENTED_IMAGE * @output_type Image * @output_description The skin mask image. * END*/ static const char k_SCGMMTP_modelColorName[2][5] = {"blue", "red"}; class SkinColorGMMTrain : public BufferedNode { friend void on_save_button_clicked (GtkButton *button, SkinColorGMMTrain *cSelection); friend void on_add_button_clicked (GtkButton *button, SkinColorGMMTrain *cSelection); friend void on_init_button_clicked (GtkButton *button, SkinColorGMMTrain *cSelection); friend void on_adapt_button_clicked (GtkButton *button, SkinColorGMMTrain *cSelection); friend void on_model_button_clicked (GtkButton *button, SkinColorGMMTrain *cSelection); friend gboolean pixbuf_event_function (GnomeCanvasItem *canvasitem, GdkEvent *event, SkinColorGMMTrain *cSelection); public: SkinColorGMMTrain(string nodeName, ParameterSet params) : BufferedNode(nodeName, params), m_hasInit(false), m_hasSkinGMM(false), m_hasNonSkinGMM(false), m_saving(false), m_adding(false), m_initializing(false), m_adapting(false), m_useSkinModel(true), m_skip(0), m_pixbuf_item(NULL), m_last_count(-1) { try { // Buffered node inputs m_inImageID = addInput("IN_IMAGE"); // Buffered node inputs m_outMaskID = addOutput("SEGMENTED_IMAGE"); m_width = dereference_cast<int>(parameters.get("WIDTH")); m_height = dereference_cast<int>(parameters.get("HEIGHT")); m_numChannels = dereference_cast<int>(parameters.get("NUM_CHANNELS")); m_outModelName = object_cast<string>(parameters.get("OUT_MODEL_FILENAME")); m_numSkinGaussians = dereference_cast<int>(parameters.get("NUM_SKIN_GAUSSIANS")); m_numNonSkinGaussians = dereference_cast<int>(parameters.get("NUM_NONSKIN_GAUSSIANS")); m_skinProbThresh = dereference_cast<float>(parameters.get("SKIN_LOG_LIKELIHOOD_THRESHOLD")); m_nonSkinProbThresh = dereference_cast<float>(parameters.get("NON_SKIN_LOG_LIKELIHOOD_THRESHOLD")); m_numPixels = m_width*m_height; m_numBytesInFrame = m_numPixels*m_numChannels; //create pixbuf m_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, m_width, m_height); CvSize size; size.width = m_width; size.height = m_height; m_curFrame = cvCreateImage(size, IPL_DEPTH_8U, m_numChannels); m_tmpFrame = cvCreateImage(size, IPL_DEPTH_8U, 1); m_maskFrame = cvCreateImage(size, IPL_DEPTH_8U, 1); m_outFrame = cvCreateImage(size, IPL_DEPTH_8U, 1); // Since we are using r-b color space, // there are 2 dimensions in the data space m_numDims = 2; m_skinGMM = RCPtr<GMM>(new GMM(m_numSkinGaussians, m_numDims, NewDiagonalCovariance)); m_nonSkinGMM = RCPtr<GMM>(new GMM(m_numNonSkinGaussians, m_numDims, NewDiagonalCovariance)); m_tmpData = Vector<float>::alloc(2); } catch (BaseException *e) { throw e->add(new GeneralException("Exception in SkinColorGMMTrain::SkinColorGMMTrain:",__FILE__,__LINE__)); } } virtual ~SkinColorGMMTrain() { gdk_threads_enter(); gtk_object_destroy(GTK_OBJECT(window1)); cvReleaseImage(&m_outFrame); cvReleaseImage(&m_tmpFrame); cvReleaseImage(&m_maskFrame); cvReleaseImage(&m_curFrame); gdk_threads_leave(); } void initialize() { BufferedNode::initialize(); gdk_threads_enter(); window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_object_set_data (GTK_OBJECT (window1), "window1", window1); gtk_window_set_title (GTK_WINDOW (window1), _("window1")); vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_ref (vbox1); gtk_object_set_data_full (GTK_OBJECT (window1), "vbox1", vbox1, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (vbox1); gtk_container_add (GTK_CONTAINER (window1), vbox1); vbox2 = gtk_vbox_new (FALSE, 0); gtk_widget_ref (vbox2); gtk_object_set_data_full (GTK_OBJECT (window1), "vbox2", vbox2, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (vbox2); gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0); scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); gtk_widget_ref (scrolledwindow2); gtk_object_set_data_full (GTK_OBJECT (window1), "scrolledwindow2", scrolledwindow2, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (scrolledwindow2); gtk_box_pack_start (GTK_BOX (vbox2), scrolledwindow2, TRUE, TRUE, 0); gtk_widget_push_visual (gdk_rgb_get_visual()); gtk_widget_push_colormap (gdk_rgb_get_cmap()); canvas1 = gnome_canvas_new (); gtk_widget_pop_colormap (); gtk_widget_pop_visual (); gtk_widget_ref (canvas1); gtk_object_set_data_full (GTK_OBJECT (window1), "canvas1", canvas1, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (canvas1); gtk_container_add (GTK_CONTAINER (scrolledwindow2), canvas1); gtk_widget_set_usize (canvas1, 320, 240); gtk_widget_set_events (canvas1, GDK_BUTTON1_MOTION_MASK); gtk_widget_set_extension_events (canvas1, GDK_EXTENSION_EVENTS_CURSOR); gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas1), 0, 0, 100, 100); hbox1 = gtk_hbox_new (FALSE, 0); gtk_widget_ref (hbox1); gtk_object_set_data_full (GTK_OBJECT (window1), "hbox1", hbox1, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (hbox1); gtk_box_pack_start (GTK_BOX (vbox2), hbox1, TRUE, TRUE, 0); //SAVE save_button = gtk_button_new_with_label (_("Save")); gtk_widget_ref (save_button); gtk_object_set_data_full (GTK_OBJECT (window1), "save_button", save_button, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (save_button); gtk_box_pack_start (GTK_BOX (hbox1), save_button, FALSE, FALSE, 0); //ADD BUTTON add_button = gtk_button_new_with_label (_("Add Pixels")); gtk_widget_ref (add_button); gtk_object_set_data_full (GTK_OBJECT (window1), "add_button", add_button, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (add_button); gtk_box_pack_start (GTK_BOX (hbox1), add_button, FALSE, TRUE, 0); //INIT BUTTON init_button = gtk_button_new_with_label (_("Init")); gtk_widget_ref (init_button); gtk_object_set_data_full (GTK_OBJECT (window1), "init_button", init_button, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (init_button); gtk_box_pack_start (GTK_BOX (hbox1), init_button, FALSE, TRUE, 0); //ADAPT BUTTON adapt_button = gtk_button_new_with_label (_("Adapt")); gtk_widget_ref (adapt_button); gtk_object_set_data_full (GTK_OBJECT (window1), "adapt_button", adapt_button, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (adapt_button); gtk_box_pack_start (GTK_BOX (hbox1), adapt_button, FALSE, TRUE, 0); //MODEL BUTTON model_button = gtk_button_new_with_label (_("Switch Model")); gtk_widget_ref (model_button); gtk_object_set_data_full (GTK_OBJECT (window1), "model_button", model_button, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show (model_button); gtk_box_pack_start (GTK_BOX (hbox1), model_button, FALSE, TRUE, 0); //creating pixbuf item m_pixbuf_item = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS(canvas1)), gnome_canvas_pixbuf_get_type(), "pixbuf",m_pixbuf,NULL); //update window size and position gtk_window_set_default_size (GTK_WINDOW(window1),min(m_width + 100,800), min(m_height + 200,600)); gtk_window_set_position (GTK_WINDOW(window1),GTK_WIN_POS_CENTER); //update the scrollbars gnome_canvas_set_scroll_region (GNOME_CANVAS(canvas1),0.0, 0.0, m_width, (double) m_height); //connecting signals gtk_signal_connect (GTK_OBJECT (save_button), "clicked", GTK_SIGNAL_FUNC (on_save_button_clicked), this); gtk_signal_connect (GTK_OBJECT (add_button), "clicked", GTK_SIGNAL_FUNC (on_add_button_clicked), this); gtk_signal_connect (GTK_OBJECT (init_button), "clicked", GTK_SIGNAL_FUNC (on_init_button_clicked), this); gtk_signal_connect (GTK_OBJECT (adapt_button), "clicked", GTK_SIGNAL_FUNC (on_adapt_button_clicked), this); gtk_signal_connect (GTK_OBJECT (model_button), "clicked", GTK_SIGNAL_FUNC (on_model_button_clicked), this); gtk_signal_connect(GTK_OBJECT(m_pixbuf_item), "event", GTK_SIGNAL_FUNC(pixbuf_event_function), this); gtk_widget_show (window1); gdk_threads_leave(); } void display_pixbuf() { gdk_threads_enter(); if (!m_imageRef->isNil()) { // Getting image IplImage *my_image = m_curFrame; unsigned char *image_data = (unsigned char*) my_image->imageData; unsigned char *pixbuf_data = gdk_pixbuf_get_pixels(m_pixbuf); int num_channels = gdk_pixbuf_get_n_channels(m_pixbuf); //copying image data for (int i = 0; i < m_width * m_height; i++) { //RED or HUE pixbuf_data[0] = *image_data++; //GREEN or SATURATION pixbuf_data[1] = *image_data++; //BLUE or VALUE pixbuf_data[2] = *image_data++; //next pixbuf pixel pixbuf_data += num_channels; } //update canvas. gnome_canvas_request_redraw (GNOME_CANVAS(canvas1), 0, 0, m_width, m_height); } gdk_threads_leave(); } void calculate(int output_id, int count, Buffer &out) { try { m_imageRef = getInput(m_inImageID, count); // Verify input image sanity if (object_cast<Image>(m_imageRef).get_width() != m_width || object_cast<Image>(m_imageRef).get_height() != m_height || object_cast<Image>(m_imageRef).get_pixelsize() != m_numChannels) { throw new GeneralException ("SkinColorGMMTrain::calculate : image parameters do not correspond to given input.",__FILE__,__LINE__); } memcpy(m_curFrame->imageData, object_cast<Image>(m_imageRef).get_data(), m_numBytesInFrame); if (m_adding) { cout << "Adding pixels to model " << m_useSkinModel << endl; if (m_useSkinModel) { AddPixelsToGMM((const unsigned char *)(m_curFrame->imageData), &m_skinData); } else { AddPixelsToGMM((const unsigned char *)(m_curFrame->imageData), &m_nonSkinData); } m_adding = false; } if (m_initializing) { cout << "Initializing model " << m_useSkinModel << endl; if (m_useSkinModel) { InitGMM(m_skinGMM.get(), &m_skinData); m_hasSkinGMM = true; } else { InitGMM(m_nonSkinGMM.get(), &m_nonSkinData); m_hasNonSkinGMM = true; } if (m_hasSkinGMM && m_hasNonSkinGMM) { m_hasInit = true; } m_initializing = false; } if (m_adapting) { cout << "Adapting model " << m_useSkinModel << endl; if (m_useSkinModel) { AdaptGMM(m_skinGMM.get(), &m_skinData); } else { AdaptGMM(m_nonSkinGMM.get(), &m_nonSkinData); } m_adapting = false; } if (m_saving) { cout << "Saving models." << endl; SaveModels(); m_saving = false; } display_pixbuf(); if (m_hasInit) { Image *segmented = Image::alloc(m_width, m_height, 1); CvRect roi; m_skinProbThresh = 2.0f; SegmentSkin((const unsigned char *)(m_curFrame->imageData), (unsigned char *)(m_tmpFrame->imageData)); cvSmooth(m_tmpFrame, m_maskFrame, CV_MEDIAN, 3, 0); roi.x = 0; roi.y = 0; roi.width = m_width/3; roi.height = m_height/2; cvSetImageROI(m_outFrame,roi); cvResize(m_maskFrame, m_outFrame, CV_INTER_CUBIC); m_skinProbThresh = 5.0f; SegmentSkin((const unsigned char *)(m_curFrame->imageData), (unsigned char *)(m_tmpFrame->imageData)); cvSmooth(m_tmpFrame, m_maskFrame, CV_MEDIAN, 3, 0); roi.x += roi.width; cvSetImageROI(m_outFrame,roi); cvResize(m_maskFrame, m_outFrame, CV_INTER_CUBIC); m_skinProbThresh = 5.1f; SegmentSkin((const unsigned char *)(m_curFrame->imageData), (unsigned char *)(m_tmpFrame->imageData)); cvSmooth(m_tmpFrame, m_maskFrame, CV_MEDIAN, 3, 0); roi.x += roi.width; cvSetImageROI(m_outFrame,roi); cvResize(m_maskFrame, m_outFrame, CV_INTER_CUBIC); m_skinProbThresh = 5.2f; SegmentSkin((const unsigned char *)(m_curFrame->imageData), (unsigned char *)(m_tmpFrame->imageData)); cvSmooth(m_tmpFrame, m_maskFrame, CV_MEDIAN, 3, 0); roi.x = 0; roi.y += roi.height; cvSetImageROI(m_outFrame,roi); cvResize(m_maskFrame, m_outFrame, CV_INTER_CUBIC); m_skinProbThresh = 5.3f; SegmentSkin((const unsigned char *)(m_curFrame->imageData), (unsigned char *)(m_tmpFrame->imageData)); cvSmooth(m_tmpFrame, m_maskFrame, CV_MEDIAN, 3, 0); roi.x += roi.width; cvSetImageROI(m_outFrame,roi); cvResize(m_maskFrame, m_outFrame, CV_INTER_CUBIC); m_skinProbThresh = 5.4f; SegmentSkin((const unsigned char *)(m_curFrame->imageData), (unsigned char *)(m_tmpFrame->imageData)); cvSmooth(m_tmpFrame, m_maskFrame, CV_MEDIAN, 3, 0); roi.x += roi.width; cvSetImageROI(m_outFrame,roi); cvResize(m_maskFrame, m_outFrame, CV_INTER_CUBIC); roi.x = 0; roi.y = 0; roi.width = m_width; roi.height = m_height; cvSetImageROI(m_outFrame,roi); memcpy(segmented->get_data(), m_outFrame->imageData, m_numPixels); (*outputs[m_outMaskID].buffer)[count] = segmented; } else { (*outputs[m_outMaskID].buffer)[count] = m_imageRef; } }//try catch (BaseException *e) { throw e->add(new GeneralException("Exception in SkinColorGMMTrain::calculate:",__FILE__,__LINE__)); } } void SegmentSkin(const unsigned char *i_srcImg, unsigned char *o_skinMask) { unsigned char val; const unsigned char *p_srcPtr = i_srcImg; unsigned char *p_maskPtr = o_skinMask; int mapIdx; try { for (int p=0; p<m_numPixels; p++) { RGB2rb(p_srcPtr[0], p_srcPtr[1], p_srcPtr[2], (*m_tmpData)[0], (*m_tmpData)[1]); float skinlogLikelihood = -m_skinGMM->score(&((*m_tmpData)[0])).score; //float nonSkinlogLikelihood = -m_nonSkinGMM->score(&((*m_tmpData)[0])).score; //cout << "nonSkinlogLikelihood=" << nonSkinlogLikelihood << endl; //cout << "skinlogLikelihood=" << skinlogLikelihood << " nonSkinlogLikelihood=" << nonSkinlogLikelihood << endl; //float logLikelihood = skinlogLikelihood; if (/*skinlogLikelihood > m_skinProbThresh && nonSkinlogLikelihood < m_nonSkinProbThresh*/ skinlogLikelihood > m_skinProbThresh) { *p_maskPtr++ = 255; } else { *p_maskPtr++ = 0; } p_srcPtr+=m_numChannels; } } catch (BaseException *e) { throw e->add(new GeneralException("Exception in SkinColorGMMTrain::calculate:",__FILE__,__LINE__)); } } void AddPixelsToGMM(const unsigned char *i_srcImg, Vector<Vector<float> > *io_trainData) { try { const unsigned char *p_srcPtr = i_srcImg; for (int y=m_BBy1; y<m_BBy2; y++) { p_srcPtr = i_srcImg + (y*m_width + m_BBx1)*m_numChannels; for (int x=m_BBx1; x<m_BBx2; x++) { RGB2rb(p_srcPtr[0], p_srcPtr[1], p_srcPtr[2], (*m_tmpData)[0], (*m_tmpData)[1]); // Save pixel in training data vector io_trainData->push_back(*m_tmpData); p_srcPtr += m_numChannels; } } } catch (BaseException *e) { throw e->add(new GeneralException("Exception in SkinColorGMMTrain::AddPixelsToGMM:",__FILE__,__LINE__)); } } void InitGMM(GMM *io_gmm, Vector<Vector<float> > *i_trainData) { try { if (i_trainData->size() == 0) { // nothing to do return; } vector<float *> data(i_trainData->size()); for (int i=0;i<i_trainData->size();i++) { data[i]=&((*i_trainData)[i][0]); } io_gmm->init(data); io_gmm->to_real(); io_gmm->kmeans1(data,20); // Reset data to empty vector i_trainData->clear(); } catch (BaseException *e) { throw e->add(new GeneralException("Exception in SkinColorGMMTrain::InitGMM:",__FILE__,__LINE__)); } } void AdaptGMM(GMM *io_gmm, Vector<Vector<float> > *i_trainData) { try { if (i_trainData->size() == 0) { // nothing to do return; } vector<float *> data(i_trainData->size()); for (int i=0;i<i_trainData->size();i++) { data[i]=&((*i_trainData)[i][0]); } io_gmm->adaptMAP(data, io_gmm); // Reset data to empty vector i_trainData->clear(); } catch (BaseException *e) { throw e->add(new GeneralException("Exception in SkinColorGMMTrain::AdaptGMM:",__FILE__,__LINE__)); } } void SaveModels() { try { if (!m_hasInit) { // Do nothing return; } string skinFilename = m_outModelName + "Skin.txt"; ofstream skinModelFile(skinFilename.c_str(), ios::out); if (!skinModelFile) { throw new GeneralException (string("SkinColorGMMTrain::WriteModels : unable to open file: ") + skinFilename,__FILE__,__LINE__); } m_skinGMM->printOn(skinModelFile); skinModelFile.close(); string nonSkinFilename = m_outModelName + "NonSkin.txt"; ofstream nonSkinModelFile(nonSkinFilename.c_str(), ios::out); if (!nonSkinModelFile) { throw new GeneralException (string("SkinColorGMMTrain::WriteModels : unable to open file: ") + nonSkinFilename,__FILE__,__LINE__); } m_skinGMM->printOn(nonSkinModelFile); nonSkinModelFile.close(); } catch (BaseException *e) { throw e->add(new GeneralException("Exception in SkinColorGMMTrain::SaveModels:",__FILE__,__LINE__)); } } inline void RGB2rb( unsigned char i_red, unsigned char i_green, unsigned char i_blue, float &o_r, float &o_b) const { // Conversion from RGB to r-b float intensity = (float)(i_red+i_blue+i_green); if (intensity == 0.f) { o_r = 0.f; o_b = 0.f; return; } intensity = 1.f/intensity; o_r = (float)(i_red)*intensity; o_b = (float)(i_blue)*intensity; } private: int m_inImageID; int m_outMaskID; bool m_hasSkinGMM; bool m_hasNonSkinGMM; bool m_hasInit; bool m_adding; bool m_initializing; bool m_adapting; bool m_saving; bool m_useSkinModel; int m_skip; int m_width; int m_height; int m_numChannels; int m_numPixels; int m_numBytesInFrame; int m_BBx1; int m_BBx2; int m_BBy1; int m_BBy2; GtkWidget *window1; GtkWidget *vbox1; GtkWidget *vbox2; GtkWidget *scrolledwindow2; GtkWidget *canvas1; GtkWidget *hbox1; GtkWidget *save_button; GtkWidget *add_button; GtkWidget *init_button; GtkWidget *adapt_button; GtkWidget *model_button; GnomeCanvasItem *m_pixbuf_item; GdkPixbuf *m_pixbuf; int m_last_count; ObjectRef m_imageRef; IplImage *m_curFrame; IplImage *m_tmpFrame; IplImage *m_maskFrame; IplImage *m_outFrame; string m_outModelName; int m_numSkinGaussians; int m_numNonSkinGaussians; int m_numDims; float m_skinProbThresh; float m_nonSkinProbThresh; RCPtr<GMM> m_skinGMM; RCPtr<GMM> m_nonSkinGMM; Vector<float> *m_tmpData; Vector<Vector<float> > m_skinData; Vector<Vector<float> > m_nonSkinData; }; void on_save_button_clicked (GtkButton *button, SkinColorGMMTrain *cSelection) { cSelection->m_saving = true; } void on_add_button_clicked (GtkButton *button, SkinColorGMMTrain *cSelection) { cSelection->m_adding = !cSelection->m_adding; } void on_init_button_clicked (GtkButton *button, SkinColorGMMTrain *cSelection) { cSelection->m_initializing = !cSelection->m_initializing; } void on_adapt_button_clicked (GtkButton *button, SkinColorGMMTrain *cSelection) { cSelection->m_adapting = !cSelection->m_adapting; } void on_model_button_clicked (GtkButton *button, SkinColorGMMTrain *cSelection) { cSelection->m_useSkinModel = !cSelection->m_useSkinModel; } gboolean pixbuf_event_function( GnomeCanvasItem *canvasitem, GdkEvent *event, SkinColorGMMTrain *cSelection) { static double x,y; static GnomeCanvasItem *item = NULL; double item_x, item_y; double x1,y1,x2,y2; item_x = event->button.x; item_y = event->button.y; switch (event->type) { case GDK_BUTTON_PRESS: if(item) { gtk_object_destroy(GTK_OBJECT(item)); } if (!cSelection->m_imageRef->isNil()) { int colorNameIdx; if (cSelection->m_useSkinModel) { colorNameIdx = 0; } else { colorNameIdx = 1; } item = gnome_canvas_item_new ( gnome_canvas_root(GNOME_CANVAS(cSelection->canvas1)), gnome_canvas_rect_get_type(), "x1",item_x, "y1",item_y, "x2",item_x, "y2",item_y, "outline_color", k_SCGMMTP_modelColorName[colorNameIdx], NULL); x = item_x; y = item_y; } break; case GDK_MOTION_NOTIFY: if (event->motion.state & GDK_BUTTON1_MASK && item) { //resizing if (item_x > x) { gnome_canvas_item_set (item, "x2",item_x,NULL); } else { gnome_canvas_item_set (item, "x1",item_x,"x2",x,NULL); } if (item_y > y) { gnome_canvas_item_set (item, "y2",item_y,NULL); } else { gnome_canvas_item_set (item, "y1",item_y,"y2",y,NULL); } } break; case GDK_BUTTON_RELEASE: //destroying the rectangle if (item) { //getting image Image &my_image = object_cast<Image>(cSelection->m_imageRef); int width = my_image.get_width(); int height = my_image.get_height(); //getting rect boundaries gtk_object_get(GTK_OBJECT(item),"x1",&x1,"y1",&y1,"x2",&x2,"y2",&y2,NULL); cSelection->m_BBx1 = (int)max(x1,0.0); cSelection->m_BBy1 = (int)max(y1,0.0); cSelection->m_BBx2 = (int)min(x2,(double) width); cSelection->m_BBy2 = (int)min(y2,(double) height); gtk_object_destroy(GTK_OBJECT(item)); item = NULL; } break; case GDK_LEAVE_NOTIFY: break; default: break; } return TRUE; } } #endif |
From: Pierre M. <sid...@us...> - 2005-06-23 20:56:17
|
Update of /cvsroot/robotflow/RobotFlow/Probes/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23518 Modified Files: VisualROISelection.cc Log Message: Fixed display of selection of rectangular regions. Index: VisualROISelection.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Probes/src/VisualROISelection.cc,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** VisualROISelection.cc 2 Jun 2005 20:11:02 -0000 1.2 --- VisualROISelection.cc 23 Jun 2005 20:56:07 -0000 1.3 *************** *** 236,244 **** for (int i = 0; i < m_width * m_height; i++) { //RED or HUE ! pixbuf_data[2] = *image_data++; //GREEN or SATURATION pixbuf_data[1] = *image_data++; //BLUE or VALUE ! pixbuf_data[0] = *image_data++; //next pixbuf pixel --- 236,244 ---- for (int i = 0; i < m_width * m_height; i++) { //RED or HUE ! pixbuf_data[0] = *image_data++; //GREEN or SATURATION pixbuf_data[1] = *image_data++; //BLUE or VALUE ! pixbuf_data[2] = *image_data++; //next pixbuf pixel |
From: Pierre M. <sid...@us...> - 2005-06-23 20:50:21
|
Update of /cvsroot/robotflow/RobotFlow/Vision/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19937 Modified Files: Makefile.am Log Message: Added SkinColorGMMSegm to file list and include path for Flowdesigner HMM toolbox. Index: Makefile.am =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/src/Makefile.am,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** Makefile.am 16 Jun 2005 15:17:10 -0000 1.35 --- Makefile.am 23 Jun 2005 20:50:08 -0000 1.36 *************** *** 10,13 **** --- 10,14 ---- CvFaceDetection.cc \ DrawPFParticle.cc \ + GetVisualROIParam.cc \ IntegralColorExtraction.cc \ IntegralEdgesOriExtraction.cc \ *************** *** 89,92 **** --- 90,94 ---- RGB242RGB15.cc \ RGB5552RGB24.cc \ + SkinColorGMMSegm.cc \ SkinColorHistSegm.cc $(OPENCV_SOURCES) *************** *** 96,100 **** libVision_la_LDFLAGS = -release $(LT_RELEASE) $(PIXBUF_LIBS) $(GNOME_LIB) $(JPEG_LIB) $(OPENCV_LIBS) ! INCLUDES = -I../include $(OVERFLOW_INCLUDE) $(PIXBUF_INCLUDE) $(JPEG_INCLUDE) $(OPENCV_INCLUDES) install-data-local: --- 98,102 ---- libVision_la_LDFLAGS = -release $(LT_RELEASE) $(PIXBUF_LIBS) $(GNOME_LIB) $(JPEG_LIB) $(OPENCV_LIBS) ! INCLUDES = -I../include $(OVERFLOW_INCLUDE) $(PIXBUF_INCLUDE) $(JPEG_INCLUDE) $(OPENCV_INCLUDES) -I$(OVERFLOW_DATA)/HMM install-data-local: |
From: Pierre M. <sid...@us...> - 2005-06-23 20:49:00
|
Update of /cvsroot/robotflow/RobotFlow/Vision/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19199 Added Files: SkinColorGMMSegm.cc Log Message: Skin color segmentation using gaussian mixture models in the r-b color space. --- NEW FILE: SkinColorGMMSegm.cc --- #ifndef _SKINCOLORGMMSEGM_CC_ #define _SKINCOLORGMMSEGM_CC_ #include "BufferedNode.h" #include "Image.h" #include "gmm.h" #include <stdlib.h> #include <sys/timeb.h> #include <fstream> using namespace FD; using namespace std; namespace RobotFlow { class SkinColorGMMSegm; DECLARE_NODE(SkinColorGMMSegm) /*Node * * @name SkinColorGMMSegm * @category RobotFlow:Vision:Detection * @description Skin segmentation based on gaussian mixture models in the r-b color space. * * @parameter_name FRAME_WIDTH * @parameter_type int * @parameter_value 320 * @parameter_description Width of video frames. * * @parameter_name FRAME_HEIGHT * @parameter_type int * @parameter_value 240 * @parameter_description Height of video frames. * * @parameter_name SKIN_GMM_FILENAME * @parameter_type string * @parameter_value ./ColorGMMSkin.txt * @parameter_description Filename (including path) of the skin GMM model file. * * @parameter_name SKIN_SCORE_THRESHOLD * @parameter_type float * @parameter_value 5.3 * @parameter_description Threshold for skin model score to consider a pixel as skin. * * @input_name IN_IMAGE * @input_type Image * @input_description Current color frame to process. * * @input_name ACTIVATION * @input_type bool * @input_description Node activation flag. * * @output_name SEGMENTED_IMAGE * @output_type Image * @output_description Segmented image output. * END*/ static const int k_SCGMMS_colorChannelFact = 255; static const int k_SCGMMS_colorChannelSize = k_SCGMMS_colorChannelFact+1; class SkinColorGMMSegm : public BufferedNode { public: SkinColorGMMSegm(string nodeName, ParameterSet params) : BufferedNode(nodeName, params) { try { m_imageInID = addInput("IN_IMAGE"); m_activatedInID = addInput("ACTIVATION"); m_imageOutID = addOutput("SEGMENTED_IMAGE"); m_width = dereference_cast<int>(parameters.get("FRAME_WIDTH")); m_height = dereference_cast<int>(parameters.get("FRAME_HEIGHT")); m_skinModelName = object_cast<string>(parameters.get("SKIN_GMM_FILENAME")); m_skinScoreThresh = dereference_cast<float>(parameters.get("SKIN_SCORE_THRESHOLD")); m_numChannels = 3; m_numPixels = m_width*m_height; m_numBytesInFrame = m_numPixels*m_numChannels; m_skinGMM = RCPtr<FD::GMM>(new FD::GMM()); ifstream modelFile(m_skinModelName.c_str(), ios::in); if (!modelFile) { throw new GeneralException (string("SkinColorGMMSegm::SkinColorGMMSegm : unable to open file: ") + m_skinModelName,__FILE__,__LINE__); } modelFile >> m_skinGMM; modelFile.close(); m_tmpData = Vector<float>::alloc(2); BuildColorTable(); } catch (BaseException *e) { throw e->add(new GeneralException("Exception in SkinColorGMMSegm::SkinColorGMMSegm:",__FILE__,__LINE__)); } } ~SkinColorGMMSegm() { } void calculate(int output_id, int count, Buffer &out) { try { // Get activation flag m_activated = getInput(m_activatedInID, count); if (!(*m_activated)) { // Output nilObjects and return (*outputs[m_imageOutID].buffer)[count] = nilObject; return; } struct timeb t1, t2; RCPtr<Image> imageRef = getInput(m_imageInID, count); // Verify input image sanity if (imageRef->get_width() != m_width || imageRef->get_height() != m_height || imageRef->get_pixelsize() != m_numChannels) { throw new GeneralException ("SkinColorGMMSegm::calculate : image parameters do not correspond to given input.",__FILE__,__LINE__); } Image *segmented = Image::alloc(m_width, m_height, 1); // Start timer ftime(&t1); // Apply skin model SegmentSkin(imageRef->get_data(), segmented->get_data()); // End timer ftime(&t2); // Display time used double timeDiff=(t2.time-t1.time)+((t2.millitm-t1.millitm)/1000.0); cout << "SkinColorGMMSegm::Total run time (sec): " << timeDiff << endl; m_sumMask /= 255; // Ensure that the current mask is applicable if (m_sumMask > (unsigned long)((float)(m_numPixels)*0.05f) && m_sumMask < (unsigned long)((float)(m_numPixels)*0.9f) ) { (*outputs[m_imageOutID].buffer)[count] = ObjectRef(segmented); } else { (*outputs[m_imageOutID].buffer)[count] = ObjectRef(nilObject); } } catch (BaseException *e) { throw e->add(new GeneralException("Exception in SkinColorGMMSegm::calculate:",__FILE__,__LINE__)); } } void SegmentSkin(const unsigned char *i_srcImg, unsigned char *o_skinMask) { const unsigned char *p_srcPtr = i_srcImg; unsigned char *p_maskPtr = o_skinMask; m_sumMask = 0; try { for (int p=0; p<m_numPixels; p++) { float r,b; RGB2rb(p_srcPtr[0], p_srcPtr[1], p_srcPtr[2], r, b); int rIdx = (int)(r*(float)(k_SCGMMS_colorChannelFact)); int bIdx = (int)(b*(float)(k_SCGMMS_colorChannelFact)); *p_maskPtr = m_skinMap[rIdx*k_SCGMMS_colorChannelSize + bIdx]; m_sumMask += *p_maskPtr++; p_srcPtr+=m_numChannels; } } catch (BaseException *e) { throw e->add(new GeneralException("Exception in SkinColorGMMSegm::calculate:",__FILE__,__LINE__)); } } void BuildColorTable() { unsigned char *p_mapPtr = m_skinMap; for (int r=0; r<k_SCGMMS_colorChannelSize; r++) { (*m_tmpData)[0] = (float)(r)/(float)(k_SCGMMS_colorChannelFact); for (int b=0; b<k_SCGMMS_colorChannelSize; b++) { (*m_tmpData)[1] = (float)(b)/(float)(k_SCGMMS_colorChannelFact); float skinlogLikelihood = -m_skinGMM->score(&((*m_tmpData)[0])).score; if (skinlogLikelihood > m_skinScoreThresh) { *p_mapPtr++ = 255; } else { *p_mapPtr++ = 0; } } } } inline void RGB2rb( unsigned char i_red, unsigned char i_green, unsigned char i_blue, float &o_r, float &o_b) const { // Conversion from RGB to r-b float intensity = (float)(i_red+i_blue+i_green); if (intensity == 0.f) { o_r = 0.f; o_b = 0.f; return; } intensity = 1.f/intensity; o_r = (float)(i_red)*intensity; o_b = (float)(i_blue)*intensity; } private: int m_imageInID; int m_activatedInID; int m_imageOutID; int m_width; int m_height; int m_numChannels; int m_numPixels; int m_numBytesInFrame; string m_skinModelName; float m_skinScoreThresh; RCPtr<Bool> m_activated; RCPtr<FD::GMM> m_skinGMM; Vector<float> *m_tmpData; unsigned long m_sumMask; unsigned char m_skinMap[k_SCGMMS_colorChannelSize*k_SCGMMS_colorChannelSize]; }; } #endif |
From: Pierre M. <sid...@us...> - 2005-06-23 20:47:02
|
Update of /cvsroot/robotflow/RobotFlow/Vision/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18217 Modified Files: TextSignDetect.cc Log Message: Added a texture (LBP) measure to remove false detection. Added an input for feedback between detection and tracking. Index: TextSignDetect.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/src/TextSignDetect.cc,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** TextSignDetect.cc 22 Jun 2005 19:38:14 -0000 1.6 --- TextSignDetect.cc 23 Jun 2005 20:46:51 -0000 1.7 *************** *** 6,9 **** --- 6,10 ---- #include "Image.h" #include "VisualROI.h" + #include "IntegralLBPExtraction.h" #include "Vector.h" #include <stdlib.h> *************** *** 29,32 **** --- 30,37 ---- * @input_description Current color frame to process. * + * @input_name IN_TRACKED_ROI + * @input_type VisualROI + * @input_description Region of interest currently tracked. + * * @input_name ACTIVATION * @input_type bool *************** *** 132,137 **** : BufferedNode(nodeName, params) { - m_activationInID = addInput("ACTIVATION"); m_imageInID = addInput("IN_IMAGE"); m_imageOutID = addOutput("TEXT_ROI_IMG"); m_roiOutID = addOutput("OUT_ROI"); --- 137,144 ---- : BufferedNode(nodeName, params) { m_imageInID = addInput("IN_IMAGE"); + m_roiInID = addInput("IN_TRACKED_ROI"); + m_activationInID = addInput("ACTIVATION"); + m_imageOutID = addOutput("TEXT_ROI_IMG"); m_roiOutID = addOutput("OUT_ROI"); *************** *** 195,202 **** --- 202,213 ---- m_outROI = RCPtr<VisualROI>(new VisualROI(e_VISUALROI_rectangular, 1, 1, 1, 1, 0)); + + m_intLBPExtract = new IntegralLBPExtraction(m_width, m_height, + m_numChannels, 1, 1, 8, 1, false, true, 0, 255.0, false); } ~TextSignDetect() { + delete m_intLBPExtract; delete [] m_labels; delete [] m_finalTextROI; *************** *** 397,401 **** } meanBinHeight /= m_numOriBins; - cout << "meanBinHeight=" << meanBinHeight << endl; // Compute local edge orientation histogram bin height standard deviation --- 408,411 ---- *************** *** 405,409 **** } stdBinHeight = sqrt(stdBinHeight); - cout << "stdBinHeight=" << stdBinHeight << endl; // Draw current region (for debug) --- 415,418 ---- *************** *** 419,455 **** // Valid text region m_textROI[curNumTextROI++] = bbox; - /* - // Draw local edge orientation histogram (for debug) - for (b=0; b<m_numOriBins; b++) { - if (m_tmpOriVal[b] > 0.0) { - int height = cvRound((m_tmpOriVal[b]/oriValSum)*20.0); - CvPoint ulc, lrc; - ulc.x = pt1.x+b*deltaX; - ulc.y = pt2.y; - lrc.x = pt1.x+(b+1)*deltaX; - lrc.y = pt2.y-height; - cvRectangle(m_src, ulc, lrc, CV_RGB(255,0,0), 1); - } - } - */ } - /* - else { - // Current region do not seem to correspond to text - // Draw local edge orientation histogram (for debug) - for (b=0; b<m_numOriBins; b++) { - if (m_tmpOriVal[b] > 0.0) { - int height = cvRound((m_tmpOriVal[b]/oriValSum)*20.0); - CvPoint ulc, lrc; - ulc.x = pt1.x+b*deltaX; - ulc.y = pt2.y; - lrc.x = pt1.x+(b+1)*deltaX; - lrc.y = pt2.y-height; - cvRectangle(m_src, ulc, lrc, CV_RGB(0,0,255), 1); - } - - } - } - */ } } --- 428,432 ---- *************** *** 459,473 **** cvClearMemStorage(m_contourStorage); - cout << "Num text region = " << curNumTextROI << endl; double threshold; int numFinalTextROI = 0; for (r=0; r<curNumTextROI; r++) { - /* - CvPoint ulc, lrc; - ulc.x = m_textROI[r].x; - ulc.y = m_textROI[r].y; - lrc.x = ulc.x + m_textROI[r].width; - lrc.y = ulc.y + m_textROI[r].height; - */ if (processRect(m_textROI[r], m_src, NULL, m_maxStd, m_minDist, &threshold )) { --- 436,442 ---- *************** *** 476,485 **** m_finalTextROI[numFinalTextROI++] = m_textROI[r]; } - /* - else { - // Current region do not seem to correspond to text - cvRectangle(m_src, ulc, lrc, CV_RGB(0,0,255), 1); - } - */ } --- 445,448 ---- *************** *** 584,598 **** } int curNumLabels = curLabel-1; int maxRegionSize = 0; int curRegionIdx = -1; for (l=0; l<curNumLabels; l++) { ! int area = m_textROI[l].width*m_textROI[l].height; ! if (area > maxRegionSize) { ! curRegionIdx = l; ! maxRegionSize = area; ! } } //set background (white) memset(m_binarized->imageData,0xFF,m_width * m_height); --- 547,641 ---- } + // See if we are purely detecting or + // if we are validating a tracked ROI + bool pureDetect = true; + ObjectRef roiRef = getInput(m_roiInID, count); + RCPtr<VisualROI> trackedROI; + int trackedXCen; + int trackedYCen; + + if (!roiRef->isNil()) { + pureDetect = false; + trackedROI = roiRef; + trackedXCen = trackedROI->GetXCen(); + trackedYCen = trackedROI->GetYCen(); + } + + // + // Verify texture of region + // int curNumLabels = curLabel-1; int maxRegionSize = 0; int curRegionIdx = -1; + m_intLBPExtract->Preprocess(m_src); for (l=0; l<curNumLabels; l++) { ! CvPoint ulc1, lrc1; ! int hsx = m_textROI[l].width/2; ! int hsy = m_textROI[l].height/2; ! m_outROI->SetXCen(m_textROI[l].x + hsx); ! m_outROI->SetYCen(m_textROI[l].y + hsy); ! m_outROI->Reset(hsx, hsy, 0); ! ! m_intLBPExtract->ExtractFeatures(m_outROI.get()); ! ! double *lbpFeats = m_intLBPExtract->GetDescriptor()->GetFeatures(); ! ! double minLBP = 10000.0; ! double secMinLBP = 10000.0; ! double meanLBP = 0.0; ! for (int i=0; i<9; i++) { ! meanLBP += lbpFeats[i]; ! ! if (minLBP > lbpFeats[i]) { ! secMinLBP = minLBP; ! minLBP = lbpFeats[i]; ! } ! else if (secMinLBP > lbpFeats[i]) { ! secMinLBP = lbpFeats[i]; ! } ! } ! ! meanLBP /= 9.0; ! ! double varLBP = 0.0; ! for (int i=0; i<9; i++) { ! double diff = lbpFeats[i] - meanLBP; ! varLBP += diff*diff; ! } ! ! varLBP = sqrt(varLBP); ! varLBP /= 9.0; ! ! if (varLBP < 4.0 && ! (lbpFeats[2] == minLBP || ! lbpFeats[2] == secMinLBP ) && ! lbpFeats[6] < meanLBP && ! lbpFeats[1] > meanLBP && ! lbpFeats[7] > meanLBP ) { ! // Valid text region ! if (pureDetect) { ! int area = m_textROI[l].width*m_textROI[l].height; ! if (area > maxRegionSize) { ! curRegionIdx = l; ! maxRegionSize = area; ! } ! } ! else { ! ulc1.x = m_textROI[l].x; ! ulc1.y = m_textROI[l].y; ! lrc1.x = ulc1.x + m_textROI[l].width; ! lrc1.y = ulc1.y + m_textROI[l].height; ! ! if (trackedXCen > ulc1.x && trackedXCen < lrc1.x && ! trackedYCen > ulc1.y && trackedYCen < lrc1.y) { ! // Found a face in given ROI ! curRegionIdx = l; ! break; ! } ! } ! } } + //set background (white) memset(m_binarized->imageData,0xFF,m_width * m_height); *************** *** 601,721 **** int hsx = m_textROI[curRegionIdx].width/2; int hsy = m_textROI[curRegionIdx].height/2; ! m_outROI->SetXCen(m_textROI[curRegionIdx].x + hsx); ! m_outROI->SetYCen(m_textROI[curRegionIdx].y + hsy); ! m_outROI->Reset(hsx, hsy, 0); ! ! ! //binarize image ! processRect(m_textROI[curRegionIdx], m_src, NULL, m_maxStd, m_minDist, &threshold); ! ! //set region of interest ! cvSetImageROI(m_gray,m_textROI[curRegionIdx]); ! cvSetImageROI(m_binarized,m_textROI[curRegionIdx]); ! //cvSetImageROI(m_tmpBinarized,m_textROI[curRegionIdx]); ! ! //binarize ! cvThreshold(m_gray,m_binarized,threshold,255,CV_THRESH_BINARY); ! //cvThreshold(m_gray,m_tmpBinarized,threshold,255,CV_THRESH_BINARY); ! ! // cvResize(m_tmpBinarized, m_binarized, CV_INTER_CUBIC); ! //cvDilate(m_binarized, m_binarized, NULL, 2); ! //cvErode(m_binarized, m_binarized, NULL, 2); ! //cvThreshold(m_binarized,m_binarized,250,255,CV_THRESH_BINARY); ! //cvSmooth(m_binarized, m_binarized, CV_GAUSSIAN, 3, 3); ! ! ! (*outputs[m_roiOutID].buffer)[count] = m_outROI; } else { ! (*outputs[m_roiOutID].buffer)[count] = nilObject; ! } ! ! ! // ! // Verify symmetry of region ! // ! #if 0 ! int curNumLabels = curLabel-1; ! for (l=0; l<curNumLabels; l++) { ! int halfWidth = m_textROI[l].width/2; ! int halfHeight = m_textROI[l].height/2; ! double regionSize = (double)(halfWidth*m_textROI[l].height); ! CvPoint ulc1, lrc1, ulc2, lrc2; ! CvPoint ulcV1, lrcV1, ulcV2, lrcV2; ! ! // Horizontal symmetry ! ulc1.x = m_textROI[l].x; ! ulc1.y = m_textROI[l].y; ! lrc1.x = m_textROI[l].x + halfWidth; ! lrc1.y = m_textROI[l].y + m_textROI[l].height; ! ! ulc2.x = lrc1.x + 1; ! ulc2.y = ulc1.y; ! lrc2.x = ulc1.x + m_textROI[l].width; ! lrc2.y = lrc1.y; ! ! // Verical symmetry ! ulcV1.x = m_textROI[l].x; ! ulcV1.y = m_textROI[l].y; ! lrcV1.x = m_textROI[l].x + m_textROI[l].width; ! lrcV1.y = m_textROI[l].y + halfHeight; ! ! ulcV2.x = ulcV1.x; ! ulcV2.y = lrcV1.y+1; ! lrcV2.x = lrcV1.x; ! lrcV2.y = m_textROI[l].y + m_textROI[l].height; ! ! double oriHoriSymSum = 0.0; ! double oriVertSymSum = 0.0; ! double tmpHL, tmpHR, tmpVL, tmpVH; ! for (b=0; b<m_numOriBins; b++) { ! tmpHL = m_edgesOriSumPix[b][lrc1.y*sumWidth+lrc1.x] - m_edgesOriSumPix[b][lrc1.y*sumWidth+ulc1.x] - ! m_edgesOriSumPix[b][ulc1.y*sumWidth+lrc1.x] + m_edgesOriSumPix[b][ulc1.y*sumWidth+ulc1.x]; ! tmpHR = m_edgesOriSumPix[b][lrc2.y*sumWidth+lrc2.x] - m_edgesOriSumPix[b][lrc2.y*sumWidth+ulc2.x] - ! m_edgesOriSumPix[b][ulc2.y*sumWidth+lrc2.x] + m_edgesOriSumPix[b][ulc2.y*sumWidth+ulc2.x]; ! ! tmpVL = m_edgesOriSumPix[b][lrcV1.y*sumWidth+lrcV1.x] - m_edgesOriSumPix[b][lrcV1.y*sumWidth+ulcV1.x] - ! m_edgesOriSumPix[b][ulcV1.y*sumWidth+lrcV1.x] + m_edgesOriSumPix[b][ulcV1.y*sumWidth+ulcV1.x]; ! tmpVH = m_edgesOriSumPix[b][lrcV2.y*sumWidth+lrcV2.x] - m_edgesOriSumPix[b][lrcV2.y*sumWidth+ulcV2.x] - ! m_edgesOriSumPix[b][ulcV2.y*sumWidth+lrcV2.x] + m_edgesOriSumPix[b][ulcV2.y*sumWidth+ulcV2.x]; ! ! oriHoriSymSum += abs(tmpHL-tmpHR); ! oriVertSymSum += abs(tmpVL-tmpVH); ! } ! ! oriHoriSymSum /= regionSize; ! oriVertSymSum /= regionSize; ! ! lrc1.x = ulc1.x + m_textROI[l].width; ! cout << "Symmetry for region " << l << " horizontal=" << oriHoriSymSum << " vertical=" << oriVertSymSum << endl; ! /* ! double vertClr = oriVertSymSum/200.0; ! double horiClr = oriHoriSymSum/200.0; ! unsigned char clr1, clr2; ! if (vertClr > 1.0) { ! clr1 = 255; ! } ! else { ! clr1 = (unsigned char)(vertClr*255.0); ! } ! if (horiClr > 1.0) { ! clr2 = 255; ! } ! else { ! clr2 = (unsigned char)(horiClr*255.0); ! } ! */ ! ! if (oriVertSymSum < m_vertSymThresh && ! oriHoriSymSum < m_horiSymThresh) { ! cvRectangle(m_src, ulc1, lrc1, CV_RGB(255,0,0), 1); ! } ! else { ! cvRectangle(m_src, ulc1, lrc1, CV_RGB(0,0,255), 1); ! } ! ! //cvRectangle(m_src, ulc1, lrc1, CV_RGB(clr1,0,clr2), 1); } - #endif // End timer --- 644,668 ---- int hsx = m_textROI[curRegionIdx].width/2; int hsy = m_textROI[curRegionIdx].height/2; ! m_outROI->SetXCen(m_textROI[curRegionIdx].x + hsx); ! m_outROI->SetYCen(m_textROI[curRegionIdx].y + hsy); ! m_outROI->Reset(hsx, hsy, 0); ! ! ! //binarize image ! processRect(m_textROI[curRegionIdx], m_src, NULL, m_maxStd, m_minDist, &threshold); ! ! //set region of interest ! cvSetImageROI(m_gray,m_textROI[curRegionIdx]); ! cvSetImageROI(m_binarized,m_textROI[curRegionIdx]); ! ! //binarize ! cvThreshold(m_gray,m_binarized,threshold,255,CV_THRESH_BINARY); ! ! ! (*outputs[m_roiOutID].buffer)[count] = m_outROI; } else { ! (*outputs[m_roiOutID].buffer)[count] = nilObject; } // End timer *************** *** 731,740 **** // Allocate output image Image *outImg = Image::alloc(m_width, m_height, 1); - - // Copy image pixels ! memcpy(outImg->get_data(), m_binarized->imageData, m_width * m_height); // Produce output reference (*outputs[m_imageOutID].buffer)[count] = ObjectRef(outImg); --- 678,686 ---- // Allocate output image + Image *outImg = Image::alloc(m_width, m_height, 1); // Copy image pixels ! memcpy(outImg->get_data(), m_binarized->imageData, m_numPixels); // Produce output reference (*outputs[m_imageOutID].buffer)[count] = ObjectRef(outImg); *************** *** 896,899 **** --- 842,846 ---- // Node inputs int m_imageInID; + int m_roiInID; int m_activationInID; *************** *** 952,955 **** --- 899,904 ---- RCPtr<VisualROI> m_outROI; RCPtr<Vector<double *> > m_edgesOriSumRef; + + IntegralLBPExtraction *m_intLBPExtract; }; |
From: Pierre M. <sid...@us...> - 2005-06-23 20:44:32
|
Update of /cvsroot/robotflow/RobotFlow/Vision/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17088 Modified Files: RGB5552RGB24.cc Log Message: Changed the output from BGR to RGB. Index: RGB5552RGB24.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/src/RGB5552RGB24.cc,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** RGB5552RGB24.cc 1 Jun 2005 03:23:34 -0000 1.1 --- RGB5552RGB24.cc 23 Jun 2005 20:44:24 -0000 1.2 *************** *** 77,83 **** //copying data for (unsigned int i = 0; i < width * height; i++) { - *output_data++ = m_blue_conversion_table[*input_data]; - *output_data++ = m_green_conversion_table[*input_data]; *output_data++ = m_red_conversion_table[*input_data]; *input_data++; } --- 77,83 ---- //copying data for (unsigned int i = 0; i < width * height; i++) { *output_data++ = m_red_conversion_table[*input_data]; + *output_data++ = m_green_conversion_table[*input_data]; + *output_data++ = m_blue_conversion_table[*input_data]; *input_data++; } |
From: Pierre M. <sid...@us...> - 2005-06-23 20:43:55
|
Update of /cvsroot/robotflow/RobotFlow/Vision/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16652 Modified Files: MultiIntegralCuesPFTracker.cc Log Message: Removed deleting of a temporary particle that was already deleted by the particle filter. Index: MultiIntegralCuesPFTracker.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/src/MultiIntegralCuesPFTracker.cc,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** MultiIntegralCuesPFTracker.cc 22 Jun 2005 19:39:36 -0000 1.3 --- MultiIntegralCuesPFTracker.cc 23 Jun 2005 20:43:40 -0000 1.4 *************** *** 316,320 **** delete m_intClrExtract; ! delete m_tmpSample; cvReleaseImage(&m_curImage); --- 316,321 ---- delete m_intClrExtract; ! // This should be deleted by the particle filter ! //delete m_tmpSample; cvReleaseImage(&m_curImage); |
From: Pierre M. <sid...@us...> - 2005-06-23 20:42:26
|
Update of /cvsroot/robotflow/RobotFlow/Vision/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16050 Modified Files: CvFaceDetection.cc Log Message: Added an offset to ROI's center position since OpenCV gives relative positions when setting the image ROI. Index: CvFaceDetection.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/src/CvFaceDetection.cc,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** CvFaceDetection.cc 17 Jun 2005 21:15:49 -0000 1.3 --- CvFaceDetection.cc 23 Jun 2005 20:42:15 -0000 1.4 *************** *** 104,107 **** --- 104,108 ---- m_curImage = cvCreateImage(imgSize, IPL_DEPTH_8U, m_numChannels); m_skinMask = cvCreateImage(imgSize, IPL_DEPTH_8U, 1); + m_filtMask = cvCreateImage(imgSize, IPL_DEPTH_8U, 1); m_storage1 = cvCreateMemStorage(0); *************** *** 121,124 **** --- 122,126 ---- { delete [] m_curSkinROI; + cvReleaseImage(&m_filtMask); cvReleaseImage(&m_skinMask); cvReleaseImage(&m_curImage); *************** *** 197,200 **** --- 199,203 ---- cout << "Total run time (sec): " << timeDiff << " found face=" << foundFace << endl; + if (foundFace) { (*outputs[m_roiOutID].buffer)[count] = m_faceROI; *************** *** 203,220 **** (*outputs[m_roiOutID].buffer)[count] = nilObject; } - - /* - Image *outImg = Image::alloc(m_width, m_height, m_numChannels); - - if (foundFace) { - unsigned char color[3] = {255, 0 ,0}; - m_faceROI->DrawROI(m_curImage, color); - } - - memcpy(outImg->get_data(), m_curImage->imageData, m_numBytesInFrame); - - (*outputs[m_roiOutID].buffer)[count] = ObjectRef(outImg); - */ - } catch (BaseException *e) { --- 206,209 ---- *************** *** 269,272 **** --- 258,263 ---- curHSX = hsX; curHSY = hsY; + isFrontFace = true; + isProfileFace = false; } } *************** *** 295,298 **** --- 286,291 ---- curHSX = hsX; curHSY = hsY; + isFrontFace = false; + isProfileFace = true; } } *************** *** 333,338 **** CvRect *p_regions = m_curSkinROI; // Find connected components contours using a simple chain code approximation ! cvFindContours(m_skinMask, m_contourStorage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); // Process each contour to determine if it is a potential face region of interest --- 326,334 ---- CvRect *p_regions = m_curSkinROI; + // Smooth mask + cvSmooth(m_skinMask, m_filtMask, CV_MEDIAN, 3, 0); + // Find connected components contours using a simple chain code approximation ! cvFindContours(m_filtMask, m_contourStorage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); // Process each contour to determine if it is a potential face region of interest *************** *** 346,350 **** // Copy current region information // but increase its size to be sure to fit all the head ! (*p_regions).x = bbox.x - (int)((float)(bbox.width)*0.1f); if ((*p_regions).x < 0) { (*p_regions).x = 0; --- 342,346 ---- // Copy current region information // but increase its size to be sure to fit all the head ! (*p_regions).x = bbox.x - (int)((float)(bbox.width)*0.2f); if ((*p_regions).x < 0) { (*p_regions).x = 0; *************** *** 356,360 **** } ! (*p_regions).width = (int)((float)(bbox.width)*1.2f); (*p_regions).height = (int)((float)(bbox.height)*1.2f); --- 352,356 ---- } ! (*p_regions).width = (int)((float)(bbox.width)*1.4f); (*p_regions).height = (int)((float)(bbox.height)*1.2f); *************** *** 369,374 **** } - cout << "Current number of skin regions: " << curNumSkinRegions << endl; - for (r=0; r<curNumSkinRegions; r++) { // Apply Haar cascade face detection only on selected ROIs --- 365,368 ---- *************** *** 376,379 **** --- 370,378 ---- cvSetImageROI(m_curImage, m_curSkinROI[r]); + // Since we are setting ROI with the OpenCV image + // we need to add an offset to the returned position + int xOffset = m_curSkinROI[r].x; + int yOffset = m_curSkinROI[r].y; + cvClearMemStorage(m_storage1); *************** *** 398,403 **** hsX = r->width/2; hsY = r->height/2; ! xCen = r->x + hsX; ! yCen = r->y + hsY; hsX = (int)((float)(hsX)*0.7f); xDist = xCen-m_imgXCen; --- 397,404 ---- hsX = r->width/2; hsY = r->height/2; ! // Since we are setting ROI with the OpenCV image ! // we need to add an offset to the returned position ! xCen = r->x + hsX + xOffset; ! yCen = r->y + hsY + yOffset; hsX = (int)((float)(hsX)*0.7f); xDist = xCen-m_imgXCen; *************** *** 411,414 **** --- 412,417 ---- curHSX = hsX; curHSY = hsY; + isFrontFace = true; + isProfileFace = false; } } *************** *** 423,428 **** hsX = r->width/2; hsY = r->height/2; ! xCen = r->x + hsX; ! yCen = r->y + hsY; hsX = (int)((float)(hsX)*0.6f); hsY = (int)((float)(hsY)*0.9f); --- 426,433 ---- hsX = r->width/2; hsY = r->height/2; ! // Since we are setting ROI with the OpenCV image ! // we need to add an offset to the returned position ! xCen = r->x + hsX + xOffset; ! yCen = r->y + hsY + yOffset; hsX = (int)((float)(hsX)*0.6f); hsY = (int)((float)(hsY)*0.9f); *************** *** 437,440 **** --- 442,447 ---- curHSX = hsX; curHSY = hsY; + isFrontFace = false; + isProfileFace = true; } } *************** *** 505,508 **** --- 512,517 ---- m_faceROI->SetYCen(curYCen); m_faceROI->Reset(curHSX, curHSY, 0); + isFrontFace = true; + isProfileFace = false; return true; *************** *** 527,530 **** --- 536,541 ---- m_faceROI->SetYCen(curYCen); m_faceROI->Reset(curHSX, curHSY, 0); + isFrontFace = false; + isProfileFace = true; return true; *************** *** 570,573 **** --- 581,585 ---- IplImage *m_curImage; IplImage *m_skinMask; + IplImage *m_filtMask; // Internal contour memory storage *************** *** 575,578 **** --- 587,592 ---- RCPtr<VisualROI> m_faceROI; + bool isFrontFace; + bool isProfileFace; }; |
From: Dominic L. <ma...@us...> - 2005-06-23 20:01:07
|
Update of /cvsroot/robotflow/RobotFlow/MARIE/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26867 Modified Files: newMarieDataOdometry.cpp Log Message: updated odometry to float values Index: newMarieDataOdometry.cpp =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/MARIE/src/newMarieDataOdometry.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** newMarieDataOdometry.cpp 29 Mar 2005 15:20:43 -0000 1.3 --- newMarieDataOdometry.cpp 23 Jun 2005 20:00:44 -0000 1.4 *************** *** 45,81 **** * @input_name XPOS * @input_description X axis position ! * @input_type int * * @input_name YPOS * @input_description Y axis position ! * @input_type int * * @input_name ZPOS * @input_description Z axis position ! * @input_type int * * @input_name YAW * @input_description YAW angle ! * @input_type int * * @input_name PITCH * @input_description PITCH angle ! * @input_type int * * @input_name ROLL * @input_description ROLL angle ! * @input_type int * * @input_name LINEAR_SPEED * @input_description linear speed (X-Y) ! * @input_type int * * @input_name SIDE_SPEED * @input_description translational speed (X-Y) ! * @input_type int * * @input_name ROTATION_SPEED * @input_description rotation speed (X-Y) ! * @input_type int * * @output_name DATA_ODOMETRY --- 45,81 ---- * @input_name XPOS * @input_description X axis position ! * @input_type float * * @input_name YPOS * @input_description Y axis position ! * @input_type float * * @input_name ZPOS * @input_description Z axis position ! * @input_type float * * @input_name YAW * @input_description YAW angle ! * @input_type float * * @input_name PITCH * @input_description PITCH angle ! * @input_type float * * @input_name ROLL * @input_description ROLL angle ! * @input_type float * * @input_name LINEAR_SPEED * @input_description linear speed (X-Y) ! * @input_type float * * @input_name SIDE_SPEED * @input_description translational speed (X-Y) ! * @input_type float * * @input_name ROTATION_SPEED * @input_description rotation speed (X-Y) ! * @input_type float * * @output_name DATA_ODOMETRY *************** *** 135,151 **** //get all inputs ! RCPtr<Int> xpos = getInput(m_XposID,count); ! RCPtr<Int> ypos = getInput(m_YposID,count); ! RCPtr<Int> zpos = getInput(m_ZposID,count); ! RCPtr<Int> yaw = getInput(m_yawID,count); ! RCPtr<Int> pitch = getInput(m_pitchID,count); ! RCPtr<Int> roll = getInput(m_rollID,count); ! RCPtr<Int> linSpeed = getInput(m_linSpeedID,count); ! RCPtr<Int> sideSpeed = getInput(m_sideSpeedID,count); ! RCPtr<Int> rotSpeed = getInput(m_rotSpeedID,count); ! data->setPosition(*xpos,*ypos,*zpos); ! data->setOrientation(*yaw,*pitch,*roll); ! data->setSpeed(*linSpeed,*sideSpeed,*rotSpeed); //output result --- 135,151 ---- //get all inputs ! RCPtr<Float> xpos = getInput(m_XposID,count); ! RCPtr<Float> ypos = getInput(m_YposID,count); ! RCPtr<Float> zpos = getInput(m_ZposID,count); ! RCPtr<Float> yaw = getInput(m_yawID,count); ! RCPtr<Float> pitch = getInput(m_pitchID,count); ! RCPtr<Float> roll = getInput(m_rollID,count); ! RCPtr<Float> linSpeed = getInput(m_linSpeedID,count); ! RCPtr<Float> sideSpeed = getInput(m_sideSpeedID,count); ! RCPtr<Float> rotSpeed = getInput(m_rotSpeedID,count); ! data->setPositionf(*xpos,*ypos,*zpos); ! data->setOrientationf(*yaw,*pitch,*roll); ! data->setSpeedf(*linSpeed,*sideSpeed,*rotSpeed); //output result |
From: Pierre M. <sid...@us...> - 2005-06-22 19:39:46
|
Update of /cvsroot/robotflow/RobotFlow/Vision/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29236 Modified Files: MultiIntegralCuesPFTracker.cc Log Message: Added an input for edges orientation integral images. Added options to produce filenames for frames to save. Added an option to let the user choose to draw ROI in output frame or not. Index: MultiIntegralCuesPFTracker.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/src/MultiIntegralCuesPFTracker.cc,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** MultiIntegralCuesPFTracker.cc 17 Jun 2005 21:15:49 -0000 1.2 --- MultiIntegralCuesPFTracker.cc 22 Jun 2005 19:39:36 -0000 1.3 *************** *** 170,173 **** --- 170,185 ---- * @input_description A region of interest detected as a potential target region. * + * @input_name EDGES_ORI_SUM_IMG + * @input_type Vector<double *> + * @input_description Reference to edges orientation integral images. While reference is not null, no edges preprocessing will be done. + * + * @input_name SHOW_TRACKED_ROI + * @input_type bool + * @input_description Flag indicating to show the current tracked region. + * + * @input_name FRAME_BASENAME + * @input_type string + * @input_description Path and basename for the frames filename that will be produced as an output. + * * @input_name ACTIVATION * @input_type bool *************** *** 194,197 **** --- 206,213 ---- * @output_description Current region of interest corresponding to the tracked target. IMPORTANT NOTE: Do not pull ROI_FOR_DETECTION output first since this will result in the output to be not synchoronized with the frames and the tracking process. * + * @output_name FRAME_FILENAME + * @output_type string + * @output_description Filename for the current frame to save. + * END*/ *************** *** 218,221 **** --- 234,240 ---- m_imageInID = addInput("IMAGE_IN"); m_roiInID = addInput("DETECTED_ROI"); + m_edgesOriInID = addInput("EDGES_ORI_SUM_IMG"); + m_showROIInID = addInput("SHOW_TRACKED_ROI"); + m_baseNameInID = addInput("FRAME_BASENAME"); m_activatedInID = addInput("ACTIVATION"); *************** *** 225,228 **** --- 244,248 ---- m_targetProbOutID = addOutput("TARGET_PROB"); m_detectROIOutID = addOutput("ROI_FOR_DETECTION"); + m_frameNameOutID = addOutput("FRAME_FILENAME"); m_width = dereference_cast<int>(parameters.get("FRAME_WIDTH")); *************** *** 338,346 **** return; } else if (output_id == m_imageOutID || output_id == m_roiOutID || output_id == m_targetOutID || output_id == m_targetProbOutID) { ! ParameterSet myReq, myReq2, myReq3; myReq.add("LOOKAHEAD", ObjectRef(Int::alloc(inputsCache[m_initVarianceInID].lookAhead+outputLookAhead))); myReq.add("LOOKBACK", ObjectRef(Int::alloc(inputsCache[m_initVarianceInID].lookBack+outputLookBack))); --- 358,372 ---- return; } + else if (output_id == m_frameNameOutID) { + ParameterSet myReq; + myReq.add("LOOKAHEAD", ObjectRef(Int::alloc(inputsCache[m_baseNameInID].lookAhead+outputLookAhead))); + myReq.add("LOOKBACK", ObjectRef(Int::alloc(inputsCache[m_baseNameInID].lookBack+outputLookBack))); + inputs[m_baseNameInID].node->request(inputs[m_baseNameInID].outputID,myReq); + } else if (output_id == m_imageOutID || output_id == m_roiOutID || output_id == m_targetOutID || output_id == m_targetProbOutID) { ! ParameterSet myReq, myReq2, myReq3, myReq4, myReq5; myReq.add("LOOKAHEAD", ObjectRef(Int::alloc(inputsCache[m_initVarianceInID].lookAhead+outputLookAhead))); myReq.add("LOOKBACK", ObjectRef(Int::alloc(inputsCache[m_initVarianceInID].lookBack+outputLookBack))); *************** *** 354,357 **** --- 380,392 ---- myReq3.add("LOOKBACK", ObjectRef(Int::alloc(inputsCache[m_roiInID].lookBack+outputLookBack))); inputs[m_roiInID].node->request(inputs[m_roiInID].outputID,myReq3); + + myReq4.add("LOOKAHEAD", ObjectRef(Int::alloc(inputsCache[m_edgesOriInID].lookAhead+outputLookAhead))); + myReq4.add("LOOKBACK", ObjectRef(Int::alloc(inputsCache[m_edgesOriInID].lookBack+outputLookBack))); + inputs[m_edgesOriInID].node->request(inputs[m_edgesOriInID].outputID,myReq4); + + myReq5.add("LOOKAHEAD", ObjectRef(Int::alloc(inputsCache[m_showROIInID].lookAhead+outputLookAhead))); + myReq5.add("LOOKBACK", ObjectRef(Int::alloc(inputsCache[m_showROIInID].lookBack+outputLookBack))); + inputs[m_showROIInID].node->request(inputs[m_showROIInID].outputID,myReq5); + } else { *************** *** 376,382 **** --- 411,433 ---- (*outputs[m_targetOutID].buffer)[count] = nilObject; (*outputs[m_targetProbOutID].buffer)[count] = ObjectRef(Float::alloc(0.0)); + (*outputs[m_detectROIOutID].buffer)[count] = nilObject; + (*outputs[m_frameNameOutID].buffer)[count] = nilObject; return; } + if (output_id == m_frameNameOutID) { + // Get frame basename + RCPtr<String> baseName = getInput(m_baseNameInID, count); + String *frameName = new String(); + (*frameName) += (*baseName); + const int strSize = 12; + char idx[strSize]; + snprintf(idx, strSize, "%011d", count); + (*frameName) += idx; + (*frameName) += ".jpg"; + + (*outputs[m_frameNameOutID].buffer)[count] = ObjectRef(frameName); + } + if (output_id == m_detectROIOutID) { if (m_refTarget->IsValid() && m_numSkipForRedetect < m_redetectFreq) { *************** *** 407,410 **** --- 458,472 ---- } + // Try to get edges orientation integral images + ObjectRef edgesIntObjRef = getInput(m_edgesOriInID, count); + + if (!edgesIntObjRef->isNil()) { + // Set new reference + m_intEdgExtract->SetEdgesOriSumRef(edgesIntObjRef); + } + else { + m_intEdgExtract->SetEdgesOriSumRef(nilObject); + } + // Get current image RCPtr<Image> imageRef = getInput(m_imageInID, count); *************** *** 595,601 **** --- 657,668 ---- // Produce outputs // + // See if we need to draw ROI in image + RCPtr<Bool> showROI = getInput(m_showROIInID, count); if (m_numInitFrames < 10) { m_numSkipForRedetect = 0; + if (*showROI) { + m_refTarget->GetCstROI()->DrawROI(m_curImage, (const unsigned char *)m_roiColor); + } memcpy(outImage->get_data(), m_curImage->imageData, m_numBytesInFrame); *************** *** 610,614 **** // Check if target is still valid if (m_refTarget->GetCurrentAge() > -10) { ! m_refTarget->GetCstROI()->DrawROI(m_curImage, (const unsigned char *)m_roiColor); memcpy(outImage->get_data(), m_curImage->imageData, m_numBytesInFrame); --- 677,684 ---- // Check if target is still valid if (m_refTarget->GetCurrentAge() > -10) { ! if (*showROI) { ! m_refTarget->GetCstROI()->DrawROI(m_curImage, (const unsigned char *)m_roiColor); ! } ! memcpy(outImage->get_data(), m_curImage->imageData, m_numBytesInFrame); *************** *** 680,683 **** --- 750,756 ---- int m_imageInID; int m_roiInID; + int m_edgesOriInID; + int m_showROIInID; + int m_baseNameInID; int m_activatedInID; *************** *** 688,691 **** --- 761,765 ---- int m_targetProbOutID; int m_detectROIOutID; + int m_frameNameOutID; RCPtr<Bool> m_activated; |
From: Pierre M. <sid...@us...> - 2005-06-22 19:38:24
|
Update of /cvsroot/robotflow/RobotFlow/Vision/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28659 Modified Files: TextSignDetect.cc Log Message: Added an output for edges orientation integral images. Index: TextSignDetect.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/src/TextSignDetect.cc,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** TextSignDetect.cc 16 Jun 2005 21:03:57 -0000 1.5 --- TextSignDetect.cc 22 Jun 2005 19:38:14 -0000 1.6 *************** *** 6,9 **** --- 6,10 ---- #include "Image.h" #include "VisualROI.h" + #include "Vector.h" #include <stdlib.h> #include <sys/timeb.h> *************** *** 115,118 **** --- 116,123 ---- * @output_description Region of interest corresponding to largest region of text. * + * @output_name EDGES_ORI_SUM_IMG + * @output_type Vector<double *> + * @output_description Reference to edges orientation integral images. + * END*/ *************** *** 131,134 **** --- 136,140 ---- m_imageOutID = addOutput("TEXT_ROI_IMG"); m_roiOutID = addOutput("OUT_ROI"); + m_edgesOriOutID = addOutput("EDGES_ORI_SUM_IMG"); m_width = dereference_cast<int>(parameters.get("FRAME_WIDTH")); *************** *** 173,179 **** --- 179,189 ---- m_tmpOriVal = new double[m_numOriBins]; + + m_edgesOriSumRef = RCPtr<Vector<double *> >(Vector<double *>::alloc(m_numOriBins)); + for (int b=0; b<m_numOriBins; b++) { m_edgesOri[b] = cvCreateImage( imgSize, IPL_DEPTH_32F, 1 ); m_edgesOriSum[b] = cvCreateImage( sumImgSize, IPL_DEPTH_64F, 1 ); + (*m_edgesOriSumRef)[b] = (double *)(m_edgesOriSum[b]->imageData); } *************** *** 601,614 **** //set region of interest cvSetImageROI(m_gray,m_textROI[curRegionIdx]); ! //cvSetImageROI(m_binarized,m_textROI[curRegionIdx]); ! cvSetImageROI(m_tmpBinarized,m_textROI[curRegionIdx]); //binarize ! //cvThreshold(m_gray,m_binarized,threshold,255,CV_THRESH_BINARY); ! cvThreshold(m_gray,m_tmpBinarized,threshold,255,CV_THRESH_BINARY); ! ! cvResize(m_tmpBinarized, m_binarized, CV_INTER_LINEAR); ! cvErode(m_binarized, m_binarized, NULL, 2); ! cvSmooth(m_binarized, m_binarized, CV_GAUSSIAN, 3, 3); --- 611,626 ---- //set region of interest cvSetImageROI(m_gray,m_textROI[curRegionIdx]); ! cvSetImageROI(m_binarized,m_textROI[curRegionIdx]); ! //cvSetImageROI(m_tmpBinarized,m_textROI[curRegionIdx]); //binarize ! cvThreshold(m_gray,m_binarized,threshold,255,CV_THRESH_BINARY); ! //cvThreshold(m_gray,m_tmpBinarized,threshold,255,CV_THRESH_BINARY); ! ! // cvResize(m_tmpBinarized, m_binarized, CV_INTER_CUBIC); ! //cvDilate(m_binarized, m_binarized, NULL, 2); ! //cvErode(m_binarized, m_binarized, NULL, 2); ! //cvThreshold(m_binarized,m_binarized,250,255,CV_THRESH_BINARY); ! //cvSmooth(m_binarized, m_binarized, CV_GAUSSIAN, 3, 3); *************** *** 727,730 **** --- 739,745 ---- // Produce output reference (*outputs[m_imageOutID].buffer)[count] = ObjectRef(outImg); + + // Output edges orientations + (*outputs[m_edgesOriOutID].buffer)[count] = m_edgesOriSumRef; } *************** *** 886,889 **** --- 901,905 ---- int m_imageOutID; int m_roiOutID; + int m_edgesOriOutID; // Image parameters *************** *** 935,939 **** RCPtr<VisualROI> m_outROI; ! }; --- 951,955 ---- RCPtr<VisualROI> m_outROI; ! RCPtr<Vector<double *> > m_edgesOriSumRef; }; |
From: Pierre M. <sid...@us...> - 2005-06-22 19:37:19
|
Update of /cvsroot/robotflow/RobotFlow/Vision/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28203 Modified Files: IntegralEdgesOriExtraction.cc Log Message: Added an option to use external edges orientation integral images. Index: IntegralEdgesOriExtraction.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/src/IntegralEdgesOriExtraction.cc,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** IntegralEdgesOriExtraction.cc 16 Jun 2005 18:33:24 -0000 1.4 --- IntegralEdgesOriExtraction.cc 22 Jun 2005 19:37:11 -0000 1.5 *************** *** 226,230 **** if (output_id == m_featuresOutID) { ! ParameterSet myReq; myReq.add("LOOKAHEAD", ObjectRef(Int::alloc(inputsCache[m_roiInID].lookAhead+outputLookAhead))); myReq.add("LOOKBACK", ObjectRef(Int::alloc(inputsCache[m_roiInID].lookBack+outputLookBack))); --- 226,230 ---- if (output_id == m_featuresOutID) { ! ParameterSet myReq, myReq2; myReq.add("LOOKAHEAD", ObjectRef(Int::alloc(inputsCache[m_roiInID].lookAhead+outputLookAhead))); myReq.add("LOOKBACK", ObjectRef(Int::alloc(inputsCache[m_roiInID].lookBack+outputLookBack))); *************** *** 479,482 **** --- 479,492 ---- int b, p; + if (!m_edgesOriSumRef->isNil()) { + FD::RCPtr<FD::Vector<double *> > imgVecRef = m_edgesOriSumRef; + // Edges orientation integral images are already computed + for (b=0; b<m_numOriBins; b++) { + m_edgesOriSumPix[b] = (*imgVecRef)[b]; + } + + return; + } + // Convert to graysacle if (m_numChannels == 3) { |
From: Pierre M. <sid...@us...> - 2005-06-22 19:36:50
|
Update of /cvsroot/robotflow/RobotFlow/Vision/include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28033 Modified Files: IntegralEdgesOriExtraction.h Log Message: Added an option to use external edges orientation integral images. Index: IntegralEdgesOriExtraction.h =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/include/IntegralEdgesOriExtraction.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** IntegralEdgesOriExtraction.h 9 Jun 2005 17:08:38 -0000 1.2 --- IntegralEdgesOriExtraction.h 22 Jun 2005 19:36:41 -0000 1.3 *************** *** 90,93 **** --- 90,110 ---- return (const VisualIntegralDesc<double> *)(*m_featVect)[0]; } + + FD::ObjectRef GetEdgesOriSumRef() + { + return m_edgesOriSumRef; + } + + void SetEdgesOriSumRef(FD::ObjectRef i_ref) + { + m_edgesOriSumRef = i_ref; + + if (!m_edgesOriSumRef->isNil()) { + FD::RCPtr<FD::Vector<double *> > imgVecRef = m_edgesOriSumRef; + if (imgVecRef->size() != m_numOriBins) { + throw new FD::GeneralException("Exception in IntegralEdgesOriExtraction::SetEdgesOriSumRef: given reference does not seem to have the same number of orientations.",__FILE__,__LINE__); + } + } + } private: *************** *** 148,151 **** --- 165,170 ---- IplImage **m_edgesOriSum; + FD::ObjectRef m_edgesOriSumRef; + // Pixel/value pointers float **m_edgesOriPix; |
From: Fernyqc <fe...@us...> - 2005-06-18 19:42:43
|
Update of /cvsroot/robotflow/RobotFlow/Behaviors/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4186 Modified Files: GotoPat.cc Log Message: Change in parameters description Index: GotoPat.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Behaviors/src/GotoPat.cc,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** GotoPat.cc 18 Jun 2005 16:32:17 -0000 1.2 --- GotoPat.cc 18 Jun 2005 19:42:34 -0000 1.3 *************** *** 40,44 **** * @input_name PARAMS * @input_type String ! * @input_description absolute target X and Y position (mm) in String format * * @input_name HEADING_POS --- 40,44 ---- * @input_name PARAMS * @input_type String ! * @input_description Absolute target (X, Y) position (mm) and bool value indicating if the waypoint is a goal or an intermidate in String format * * @input_name HEADING_POS |
From: Fernyqc <fe...@us...> - 2005-06-18 16:32:25
|
Update of /cvsroot/robotflow/RobotFlow/Behaviors/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11977 Modified Files: GotoPat.cc Log Message: 1) Correction of the heading in GotoPat.cc Index: GotoPat.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Behaviors/src/GotoPat.cc,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** GotoPat.cc 18 Jun 2005 15:08:20 -0000 1.1 --- GotoPat.cc 18 Jun 2005 16:32:17 -0000 1.2 *************** *** 108,113 **** * @parameter_value 3 * ! * @parameter_name MIN_DISTANCE_INTERMEDIATE_GOAL ! * @parameter_description Minimum distance to consider an intermediate goal (mm) * @parameter_type int * @parameter_value 1000 --- 108,114 ---- * @parameter_value 3 * ! * ! * @parameter_name DISCARD_DIST_INTER_GOAL ! * @parameter_description Distance to discard intermediate goal * @parameter_type int * @parameter_value 1000 *************** *** 143,147 **** std::vector<int> m_angle_chart; // Not an actual parameter ! // angularCorrection in degrees int speedValue(float angularCorrection) { --- 144,148 ---- std::vector<int> m_angle_chart; // Not an actual parameter ! // speed indice according to the angularCorrection to apply int speedValue(float angularCorrection) { *************** *** 183,187 **** m_heading_offset = dereference_cast<int> (parameters.get("HEADING_OFFSET")); m_goal_tol = dereference_cast<int> (parameters.get("GOAL_TOLERANCE")); ! m_discard_distance = dereference_cast<int> (parameters.get("MIN_DISTANCE_INTERMEDIATE_GOAL")); // Calculate speed lookup table --- 184,188 ---- m_heading_offset = dereference_cast<int> (parameters.get("HEADING_OFFSET")); m_goal_tol = dereference_cast<int> (parameters.get("GOAL_TOLERANCE")); ! m_discard_distance = dereference_cast<int> (parameters.get("DISCARD_DIST_INTER_GOAL")); // Calculate speed lookup table *************** *** 225,228 **** --- 226,230 ---- sstr >> y; sstr >> intermediate; + intermediate = !intermediate; double xpos = (double)(dereference_cast<int>(xPosValue)); *************** *** 230,236 **** double heading = (double)(dereference_cast<int>(headingValue)); - //if(heading < 0) - // heading = 360.0 + heading; - std::cout << "intermediate: " << intermediate << std::endl; std::cout << "x: " << x << std::endl; --- 232,235 ---- *************** *** 244,248 **** float distance = sqrt((x-xpos)*(x-xpos) + (y-ypos)*(y-ypos)); ! if (intermediate==false && distance < m_discard_distance){ // Discard the goal because it's too close of the robot (*outputs[rotationID].buffer)[count] = ObjectRef(Int::alloc(0)); --- 243,247 ---- float distance = sqrt((x-xpos)*(x-xpos) + (y-ypos)*(y-ypos)); ! if (intermediate && distance < m_discard_distance){ // Discard the goal because it's too close of the robot (*outputs[rotationID].buffer)[count] = ObjectRef(Int::alloc(0)); *************** *** 256,259 **** --- 255,267 ---- double diffHeading = newHeading*57.2958 - heading; + std::cout << "newHeading: " << newHeading*57.2958 << std::endl; + std::cout << "diffHeading: " << diffHeading << std::endl; + + // Prevent over 180 degrees correction + if(fabs(diffHeading) > 180){ + if(diffHeading<0) diffHeading += 360; + else diffHeading -= 360; + } + // Compute motor command int sign = (diffHeading < 0)?-1:1; *************** *** 262,265 **** --- 270,279 ---- int rotation = sign * m_rotation_chart.at(speedInd); + // Decrease speed if near goal + if(!intermediate && distance<m_discard_distance) { + velocity /= 2; + rotation /= 2; + } + // Send motor command (*outputs[rotationID].buffer)[count] = ObjectRef(Int::alloc(rotation)); *************** *** 271,279 **** (*outputs[rotationID].buffer)[count] = ObjectRef(Int::alloc(0)); (*outputs[velocityID].buffer)[count] = ObjectRef(Int::alloc(0)); std::cout << "onGoal" << std::endl; std::cout << "rotation: " << (*outputs[rotationID].buffer)[count] << std::endl; std::cout << "velocity: " << (*outputs[velocityID].buffer)[count] << std::endl; std::cout << std::endl; - (*outputs[completedID].buffer)[count] = ObjectRef(Bool::alloc(true)); } --- 285,293 ---- (*outputs[rotationID].buffer)[count] = ObjectRef(Int::alloc(0)); (*outputs[velocityID].buffer)[count] = ObjectRef(Int::alloc(0)); + (*outputs[completedID].buffer)[count] = ObjectRef(Bool::alloc(true)); std::cout << "onGoal" << std::endl; std::cout << "rotation: " << (*outputs[rotationID].buffer)[count] << std::endl; std::cout << "velocity: " << (*outputs[velocityID].buffer)[count] << std::endl; std::cout << std::endl; } |
From: Fernyqc <fe...@us...> - 2005-06-18 15:08:29
|
Update of /cvsroot/robotflow/RobotFlow/Behaviors/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6096 Modified Files: FollowWall.cc Makefile.am Added Files: GotoPat.cc Log Message: 1) GotoPat behavior 2) Makefile.am Index: FollowWall.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Behaviors/src/FollowWall.cc,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** FollowWall.cc 16 Jun 2005 20:57:13 -0000 1.3 --- FollowWall.cc 18 Jun 2005 15:08:20 -0000 1.4 *************** *** 113,129 **** * * @parameter_name SCANNING_RANGE_BEGIN ! * @parameter_description Angle beginning the scanning range (degrees) * @parameter_type int * @parameter_value 10 * * @parameter_name SCANNING_RANGE_END ! * @parameter_description Angle ending the scanning range (degrees) * @parameter_type int ! * @parameter_value 45 * ! * @parameter_name SCANNING_RANGE_INCREMENT ! * @parameter_description Angle increment in the scanning range (multiple of the laser resolution) * @parameter_type int ! * @parameter_value 1 * * @parameter_name LASER_INCREMENT --- 113,129 ---- * * @parameter_name SCANNING_RANGE_BEGIN ! * @parameter_description Scan angle beginning (degrees) * @parameter_type int * @parameter_value 10 * * @parameter_name SCANNING_RANGE_END ! * @parameter_description Scan angle ending (degrees) * @parameter_type int ! * @parameter_value 60 * ! * @parameter_name NB_SCANNING_RANGE_SAMPLES ! * @parameter_description Numbers of laser samples to use between the scanning range * @parameter_type int ! * @parameter_value 10 * * @parameter_name LASER_INCREMENT *************** *** 195,202 **** int m_range_begin; int m_range_end; ! int m_range_increment; float m_laser_increment; int m_laser_range; ! int m_nbLaserSample; // Not an actual parameter int m_begin_right; // Not an actual parameter int m_end_right; // Not an actual parameter --- 195,202 ---- int m_range_begin; int m_range_end; ! int m_nbLaserSample; float m_laser_increment; int m_laser_range; ! int m_range_increment; // Not an actual parameter int m_begin_right; // Not an actual parameter int m_end_right; // Not an actual parameter *************** *** 212,216 **** // Evaluate the mean of a vector ! float meanValue(vector<float>data) { float sum=0; --- 212,216 ---- // Evaluate the mean of a vector ! float computeMeanValue(vector<float>data) { float sum=0; *************** *** 222,226 **** // Evaluate the std.deviation of a vector ! float stdDeviation(vector<float>data) { float sumSquare=0; --- 222,226 ---- // Evaluate the std.deviation of a vector ! float computeVariance(vector<float>data) { float sumSquare=0; *************** *** 235,251 **** } ! // Compute std.deviation ! return sqrt((sumSquare-(sumXi*sumXi/n))/(n-1)); } ! bool detectWallCommunComputation(std::vector<float> angleBeta, float gamma, float b, float &distWall, float &angularCorrection){ // Compute mean and std.deviation ! float meanBeta = meanValue(angleBeta); ! float stdDevBeta = stdDeviation(angleBeta) * RAD_DEGREE; // Compute angular correction and the distance to the wall distWall = 0; angularCorrection = 0; ! bool wall = (stdDevBeta <= m_maxStdDevBeta); // Wall detection if (wall){ // Distance to the wall and angular correction --- 235,251 ---- } ! // Compute variance ! return (sumSquare-(sumXi*sumXi/n))/(n-1); } ! bool findWallInData(std::vector<float> angleBeta, float gamma, float b, float &distWall, float &angularCorrection){ // Compute mean and std.deviation ! float meanBeta = computeMeanValue(angleBeta); ! float varianceBeta = computeVariance(angleBeta) * RAD_DEGREE; // Compute angular correction and the distance to the wall distWall = 0; angularCorrection = 0; ! bool wall = (varianceBeta <= m_maxStdDevBeta); // Wall detection if (wall){ // Distance to the wall and angular correction *************** *** 263,383 **** } ! // Evaluate if a wall is present to the right in the laser readings ! bool detectRightWall(std::vector<int>laserReading, float &distWall, float &angularCorrection, bool toLog) ! { ! // Storage of angleBeta ! std::vector<float> angleBeta(m_nbLaserSample); ! ! // Triangle components ! float beta=0, gamma=0; ! float a=0, b=0, c=0; ! ! // Initial distance to the wall int nbA=5; ! while(m_begin_right+nbA > laserReading.size()) ! { ! --nbA; ! } if(nbA<1) nbA = 1; std::vector<float>laserReadingFloat(nbA); for(int i=0;i<nbA;++i) ! laserReadingFloat[i]=1.0*laserReading[m_begin_right+i]; ! a = meanValue(laserReadingFloat); ! // Compute beta angles ! int j = 0; ! for(int i=m_begin_right; i<m_end_right; i+=m_range_increment, ++j) ! { ! // Sinus and Cosinus rule ! gamma = i * m_laser_increment / RAD_DEGREE; ! b = laserReading[i]; ! c = sqrt(a*a + b*b - 2*a*b*cos(gamma)); ! beta = acos(-1*(b*b-a*a-c*c)/(2*a*c)); ! ! // Save result ! angleBeta[j] = beta; ! } ! bool wall = detectWallCommunComputation(angleBeta, gamma, b, distWall, angularCorrection); ! ! // Logging ! static std::ofstream laser("laserRight.txt"); ! static std::ofstream cmd1("cmdRight.txt"); ! static int logNumber = 0; ! if(toLog){ ! laser << "log" << logNumber << " "; ! for(int i=0; i<laserReading.size(); ++i) ! { ! laser << laserReading[i] << " "; ! } ! laser << std::endl; ! ! // Compute mean and std.deviation ! float meanBeta = meanValue(angleBeta) * RAD_DEGREE; ! float stdDevBeta = stdDeviation(angleBeta) * RAD_DEGREE; ! cmd1 << "log" << logNumber << "\t" << meanBeta << "\t" << stdDevBeta << "\t" << a << "\t" << distWall << "\t" << angularCorrection << "\t" << "wall" << std::endl; ! ++logNumber; ! } ! return wall; } ! // Evaluate if a wall is present to the left in the laser readings ! bool detectLeftWall(std::vector<int>laserReading, float &distWall, float &angularCorrection, bool toLog) { // Storage of angleBeta ! std::vector<float> angleBeta(m_nbLaserSample); // Triangle components float beta=0, gamma=0; ! float a=0, b=0, c=0; ! // Initial distance to the wall ! int nbA=5; ! while(m_begin_left-nbA < 0) ! { ! --nbA; ! } ! if(nbA<1) nbA = 1; ! std::vector<float>laserReadingFloat(nbA); ! for(int i=0;i<nbA;++i) ! laserReadingFloat[i]=1.0*laserReading[m_begin_left-i]; ! a = meanValue(laserReadingFloat); // Compute beta angles ! int j = 0; ! for(int i=m_begin_left; i>m_end_left; i-=m_range_increment, ++j) { // Sinus and Cosinus rule ! gamma = PI - (i * m_laser_increment / RAD_DEGREE); ! b = laserReading[i]; ! c = sqrt(a*a + b*b - 2*a*b*cos(gamma)); ! beta = acos(-1*(b*b-a*a-c*c)/(2*a*c)); // Save result ! angleBeta[j] = beta; } ! bool wall = detectWallCommunComputation(angleBeta, gamma, b, distWall, angularCorrection); ! angularCorrection *= -1; // Logging ! static std::ofstream laser("laserLeft.txt"); ! static std::ofstream cmd1("cmdLeft.txt"); static int logNumber = 0; if(toLog){ ! laser << "log" << logNumber << " "; for(int i=0; i<laserReading.size(); ++i) { ! laser << laserReading[i] << " "; } ! laser << std::endl; // Compute mean and std.deviation ! float meanBeta = meanValue(angleBeta)*RAD_DEGREE; ! float stdDevBeta = stdDeviation(angleBeta) * RAD_DEGREE; ! cmd1 << "log" << logNumber << "\t" << meanBeta << "\t" << stdDevBeta << "\t" << a << "\t" << distWall << "\t" << angularCorrection << "\t" << wall << std::endl; ++logNumber; } - - return wall; } --- 263,367 ---- } ! ! void getInitialDistWalls(std::vector<int>laserReading, float &aLeft, float &aRight){ ! // Left wall int nbA=5; ! while(m_begin_left-nbA < 0) --nbA; if(nbA<1) nbA = 1; + std::vector<float>laserReadingFloat(nbA); for(int i=0;i<nbA;++i) ! laserReadingFloat[i]=1.0*laserReading[m_begin_left-i]; ! aLeft = computeMeanValue(laserReadingFloat); ! // Right wall ! nbA = 5; ! while(m_begin_right+nbA > laserReading.size()) --nbA; ! if(nbA<1) nbA = 1; ! laserReading.clear(); ! laserReading.reserve(nbA); ! for(int i=0;i<nbA;++i) ! laserReadingFloat[i]=1.0*laserReading[m_begin_right+i]; ! aRight = computeMeanValue(laserReadingFloat); ! return; } ! void detectWalls(std::vector<int>laserReading, ! bool &wallLeft, float &distWallLeft, float &angularCorrectionLeft, ! bool &wallRight, float &distWallRight, float &angularCorrectionRight, ! bool toLog) { // Storage of angleBeta ! std::vector<float> angleBetaLeft(m_nbLaserSample); ! std::vector<float> angleBetaRight(m_nbLaserSample); // Triangle components float beta=0, gamma=0; ! float aLeft=0, aRight=0, b=0, c=0; ! float gammaLeft=0, gammaRight=0, bLeft=0, bRight=0; ! // Initial distance to the wall ! getInitialDistWalls(laserReading, aLeft, aRight); // Compute beta angles ! for(int i=0; i<m_nbLaserSample; ++i) { + // Left wall + // Cosine rule + gamma = PI - ((m_begin_left-i*m_range_increment) * m_laser_increment / RAD_DEGREE); + b = laserReading[m_begin_left-i*m_range_increment]; + c = sqrt(aLeft*aLeft + b*b - 2*aLeft*b*cos(gamma)); + beta = acos(-1*(b*b-aLeft*aLeft-c*c)/(2*aLeft*c)); + + // Save result + angleBetaLeft[i] = beta; + gammaLeft = gamma; + bLeft = b; + + // Right wall // Sinus and Cosinus rule ! gamma = (m_begin_right+i*m_range_increment) * m_laser_increment / RAD_DEGREE; ! b = laserReading[m_begin_right+i*m_range_increment]; ! c = sqrt(aRight*aRight + b*b - 2*aRight*b*cos(gamma)); ! beta = acos(-1*(b*b-aRight*aRight-c*c)/(2*aRight*c)); // Save result ! angleBetaRight[i] = beta; ! gammaRight = gamma; ! bRight = b; } ! ! // Detect walls ! wallLeft = findWallInData(angleBetaLeft, gammaLeft, bLeft, distWallLeft, angularCorrectionLeft); ! angularCorrectionLeft *= -1; ! wallRight = findWallInData(angleBetaRight, gammaRight, bRight, distWallRight, angularCorrectionRight); // Logging ! static std::ofstream laserL("laserLeft.txt"); ! static std::ofstream cmdL("cmdLeft.txt"); ! static std::ofstream laserR("laserRight.txt"); ! static std::ofstream cmdR("cmdRight.txt"); static int logNumber = 0; if(toLog){ ! laserL << "#" << logNumber << " "; ! laserR << "#" << logNumber << " "; for(int i=0; i<laserReading.size(); ++i) { ! laserL << laserReading[i] << " "; ! laserR << laserReading[i] << " "; } ! laserL << std::endl; ! laserR << std::endl; // Compute mean and std.deviation ! float meanBeta = computeMeanValue(angleBetaLeft)*RAD_DEGREE; ! float varianceBeta = computeVariance(angleBetaLeft); ! cmdL << "log" << logNumber << "\t" << meanBeta << "\t" << varianceBeta << "\t" << aLeft << "\t" << distWallLeft << "\t" << angularCorrectionLeft << "\t" << wallLeft << std::endl; ! meanBeta = computeMeanValue(angleBetaRight)*RAD_DEGREE; ! varianceBeta = computeVariance(angleBetaRight); ! cmdR << "log" << logNumber << "\t" << meanBeta << "\t" << varianceBeta << "\t" << aRight << "\t" << distWallRight << "\t" << angularCorrectionLeft << "\t" << wallRight << std::endl; ++logNumber; } } *************** *** 387,393 **** degreeConfidence = degreeConfidence/100; - // Unilateral test to the right of the Gauss distribution - degreeConfidence = 1 - ((1 - degreeConfidence) / 2); - // zValue if (degreeConfidence <= 0.90001) --- 371,374 ---- *************** *** 409,418 **** int speedValue(float angularCorrection) { ! int i = 0; angularCorrection = fabs(angularCorrection); while((i<m_angle_chart.size()) && (angularCorrection < m_angle_chart[i+1])) ++i; return i; } public: --- 390,404 ---- int speedValue(float angularCorrection) { ! // Saturate the angularCorrection to 90 degrees angularCorrection = fabs(angularCorrection); + if (angularCorrection >= 90) angularCorrection = 89; + + // Get speed indice in the lookup table + int i = 0; while((i<m_angle_chart.size()) && (angularCorrection < m_angle_chart[i+1])) ++i; return i; } + public: *************** *** 465,472 **** m_range_begin = dereference_cast<int> (parameters.get("SCANNING_RANGE_BEGIN")); m_range_end = dereference_cast<int> (parameters.get("SCANNING_RANGE_END")); ! m_range_increment = dereference_cast<int> (parameters.get("SCANNING_RANGE_INCREMENT")); m_laser_increment = dereference_cast<float> (parameters.get("LASER_INCREMENT")); m_laser_range = dereference_cast<int> (parameters.get("LASER_RANGE")); ! m_nbLaserSample = static_cast<int>(((m_range_end-m_range_begin) / (m_laser_increment)) / m_range_increment); m_begin_right = static_cast<int>(m_range_begin / m_laser_increment); m_end_right = m_begin_right + m_nbLaserSample * m_range_increment; --- 451,458 ---- m_range_begin = dereference_cast<int> (parameters.get("SCANNING_RANGE_BEGIN")); m_range_end = dereference_cast<int> (parameters.get("SCANNING_RANGE_END")); ! m_nbLaserSample = dereference_cast<int> (parameters.get("NB_SCANNING_RANGE_SAMPLES")); m_laser_increment = dereference_cast<float> (parameters.get("LASER_INCREMENT")); m_laser_range = dereference_cast<int> (parameters.get("LASER_RANGE")); ! m_range_increment = static_cast<int>(((m_range_end-m_range_begin) / (m_laser_increment)) / m_nbLaserSample); m_begin_right = static_cast<int>(m_range_begin / m_laser_increment); m_end_right = m_begin_right + m_nbLaserSample * m_range_increment; *************** *** 556,561 **** // Walls detection ! rightWall = detectRightWall(laserReading, distRightWall, angularCorrectionRight, toLog); ! leftWall = detectLeftWall(laserReading, distLeftWall, angularCorrectionLeft, toLog); // Ignore walls too far --- 542,549 ---- // Walls detection ! detectWalls(laserReading, ! leftWall, distLeftWall, angularCorrectionLeft, ! rightWall, distRightWall, angularCorrectionRight, ! toLog); // Ignore walls too far Index: Makefile.am =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Behaviors/src/Makefile.am,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** Makefile.am 10 Jun 2005 04:25:32 -0000 1.14 --- Makefile.am 18 Jun 2005 15:08:20 -0000 1.15 *************** *** 31,34 **** --- 31,35 ---- MultiSignTracking.cc \ Goto.cc \ + GotoPat.cc \ FollowWall.cc --- NEW FILE: GotoPat.cc --- /* Copyright (C) 2002 Dominic Letourneau (dom...@co...) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _GOTOPAT_CC_ #define _GOTOPAT_CC_ #include "Behavior.h" #include <sstream> #include <Vector.h> using namespace std; using namespace FD; namespace RobotFlow { class GotoPat; DECLARE_NODE(GotoPat) REGISTER_BEHAVIOR(GotoPat) /*Node * @name GotoPat * @category RobotFlow:Behaviors * @description No description available * * @input_name PARAMS * @input_type String * @input_description absolute target X and Y position (mm) in String format * * @input_name HEADING_POS * @input_type int * @input_description robot actual heading (degrees) * * @input_name X_POS * @input_type int * @input_description robot actual x position (mm) * * @input_name Y_POS * @input_type int * @input_description robot actual y position (mm) * * @input_name ACTIVATED * @input_type bool * @input_description Behavior activation * * @output_name VELOCITY * @output_type int * @output_description Robot Velocity (mm/s) * * @output_name ROTATION * @output_type int * @output_description Robot Rotation value (degrees/s) * * @output_name COMPLETED * @output_type bool * @output_description Goto completion state * * @output_name EXPLOITATION * @output_description Behavior exploitation * * @parameter_name MAX_VELOCITY * @parameter_description Velocity max (mm/s) * @parameter_type int * @parameter_value 200 * * @parameter_name MIN_VELOCITY * @parameter_description Velocity min (mm/s) * @parameter_type int * @parameter_value 50 * * @parameter_name MAX_ROTATION * @parameter_description Rotation speed max (degrees/s) * @parameter_type int * @parameter_value 20 * * @parameter_name NB_SPEED_VALUE * @parameter_description Number of values to spread the speed * @parameter_type int * @parameter_value 4 * * @parameter_name HEADING_OFFSET * @parameter_description Offset of the heading value with the map orientation(degrees) * @parameter_type int * @parameter_value 0 * * @parameter_name GOAL_TOLERANCE * @parameter_description X and Y tolerance to consider position on goal (mm) * @parameter_type int * @parameter_value 50 * * @parameter_name HEADING_TOLERANCE * @parameter_description heading tolerance to consider heading to goal (degrees) * @parameter_type int * @parameter_value 3 * * @parameter_name MIN_DISTANCE_INTERMEDIATE_GOAL * @parameter_description Minimum distance to consider an intermediate goal (mm) * @parameter_type int * @parameter_value 1000 * END*/ class GotoPat : public Behavior { //inputs int paramsID; int headingID; int xPosID; int yPosID; //outputs int rotationID; int velocityID; int completedID; //parameters int m_max_velocity; int m_min_velocity; int m_max_rotation; int m_nb_speed_value; int m_heading_tol; int m_heading_offset; int m_goal_tol; int m_discard_distance; std::vector<int> m_velocity_chart; // Not an actual parameter std::vector<int> m_rotation_chart; // Not an actual parameter std::vector<int> m_angle_chart; // Not an actual parameter // angularCorrection in degrees int speedValue(float angularCorrection) { // Saturate the angularCorrection to 90 degrees angularCorrection = fabs(angularCorrection); if (angularCorrection >= 90) angularCorrection = 89; // Get speed indice in the lookup table int i = 0; while((i<m_angle_chart.size()) && (angularCorrection < m_angle_chart[i+1])) ++i; return i; } public: GotoPat(string nodeName, ParameterSet params) : Behavior(nodeName, params, "Goto") { //inputs paramsID = addInput("PARAMS"); headingID = addInput("HEADING_POS"); xPosID = addInput("X_POS"); yPosID = addInput("Y_POS"); //outputs rotationID = addOutput("ROTATION"); velocityID = addOutput("VELOCITY"); completedID = addOutput("COMPLETED"); //Motor command parameters m_max_velocity = dereference_cast<int> (parameters.get("MAX_VELOCITY")); m_min_velocity = dereference_cast<int> (parameters.get("MIN_VELOCITY")); m_max_rotation = dereference_cast<int> (parameters.get("MAX_ROTATION")); m_nb_speed_value = dereference_cast<int> (parameters.get("NB_SPEED_VALUE")); m_heading_tol = dereference_cast<int> (parameters.get("HEADING_TOLERANCE")); m_heading_offset = dereference_cast<int> (parameters.get("HEADING_OFFSET")); m_goal_tol = dereference_cast<int> (parameters.get("GOAL_TOLERANCE")); m_discard_distance = dereference_cast<int> (parameters.get("MIN_DISTANCE_INTERMEDIATE_GOAL")); // Calculate speed lookup table m_velocity_chart.reserve(m_nb_speed_value); m_rotation_chart.reserve(m_nb_speed_value); m_angle_chart.reserve(m_nb_speed_value+1); int vel_increase = (m_max_velocity-m_min_velocity)/(m_nb_speed_value-1); int rot_increase = (m_max_rotation-0)/(m_nb_speed_value-1); int angle_increase = (90-m_heading_tol)/(m_nb_speed_value-1); for(int i=0; i<m_nb_speed_value-1; ++i) { m_velocity_chart.push_back(m_min_velocity + i*vel_increase); m_rotation_chart.push_back(m_max_rotation - i*rot_increase); m_angle_chart.push_back(90-i*angle_increase); } m_velocity_chart.push_back(m_max_velocity); m_rotation_chart.push_back(0); m_angle_chart.push_back(m_heading_tol); m_angle_chart.push_back(0); } void calculate_behavior(int output_id, int count, Buffer &out) { //cerr<<"goto activated"<<endl; ObjectRef paramsValue = getInput(paramsID,count); ObjectRef headingValue = getInput(headingID,count); ObjectRef xPosValue = getInput(xPosID,count); ObjectRef yPosValue = getInput(yPosID,count); if (!paramsValue->isNil() && !headingValue->isNil() && !xPosValue->isNil() && !yPosValue->isNil()) { RCPtr<String> params = paramsValue; std::stringstream sstr(params->val()); double x; double y; bool intermediate; sstr >> x; sstr >> y; sstr >> intermediate; double xpos = (double)(dereference_cast<int>(xPosValue)); double ypos = (double)(dereference_cast<int>(yPosValue)); double heading = (double)(dereference_cast<int>(headingValue)); //if(heading < 0) // heading = 360.0 + heading; std::cout << "intermediate: " << intermediate << std::endl; std::cout << "x: " << x << std::endl; std::cout << "y: " << y << std::endl; std::cout << "xpos: " << xpos << std::endl; std::cout << "ypos: " << ypos << std::endl; std::cout << "heading: " << heading << std::endl; // Distance to the desired position float distance = sqrt((x-xpos)*(x-xpos) + (y-ypos)*(y-ypos)); if (intermediate==false && distance < m_discard_distance){ // Discard the goal because it's too close of the robot (*outputs[rotationID].buffer)[count] = ObjectRef(Int::alloc(0)); (*outputs[velocityID].buffer)[count] = ObjectRef(Int::alloc(m_max_velocity)); (*outputs[completedID].buffer)[count] = ObjectRef(Bool::alloc(true)); } else if (xpos < x - m_goal_tol || xpos > x + m_goal_tol || ypos < y - m_goal_tol || ypos > y + m_goal_tol) { // Heading correction double newHeading = atan2(y-ypos, x-xpos); double diffHeading = newHeading*57.2958 - heading; // Compute motor command int sign = (diffHeading < 0)?-1:1; int speedInd = speedValue(diffHeading); int velocity = m_velocity_chart.at(speedInd); int rotation = sign * m_rotation_chart.at(speedInd); // Send motor command (*outputs[rotationID].buffer)[count] = ObjectRef(Int::alloc(rotation)); (*outputs[velocityID].buffer)[count] = ObjectRef(Int::alloc(velocity)); (*outputs[completedID].buffer)[count] = ObjectRef(Bool::alloc(false)); } else { (*outputs[rotationID].buffer)[count] = ObjectRef(Int::alloc(0)); (*outputs[velocityID].buffer)[count] = ObjectRef(Int::alloc(0)); std::cout << "onGoal" << std::endl; std::cout << "rotation: " << (*outputs[rotationID].buffer)[count] << std::endl; std::cout << "velocity: " << (*outputs[velocityID].buffer)[count] << std::endl; std::cout << std::endl; (*outputs[completedID].buffer)[count] = ObjectRef(Bool::alloc(true)); } }//object valid else { (*outputs[rotationID].buffer)[count] = nilObject; (*outputs[velocityID].buffer)[count] = nilObject; (*outputs[completedID].buffer)[count] = nilObject; std::cout << "COMPLETED = NILOBJECT" << std::endl; } }//calculate_behavior }; }//namespace RobotFlow #endif |
From: Pierre M. <sid...@us...> - 2005-06-17 21:16:43
|
Update of /cvsroot/robotflow/RobotFlow/Vision/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4759 Modified Files: VisualROI.cc Log Message: Added temporary printOn method. Index: VisualROI.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/src/VisualROI.cc,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** VisualROI.cc 2 Jun 2005 20:07:26 -0000 1.6 --- VisualROI.cc 17 Jun 2005 21:16:33 -0000 1.7 *************** *** 95,99 **** void VisualROI::printOn(ostream &out) const { ! throw new GeneralException ("VisualROI::printOn : routine not implemented yet",__FILE__,__LINE__); } --- 95,100 ---- void VisualROI::printOn(ostream &out) const { ! //throw new GeneralException ("VisualROI::printOn : routine not implemented yet",__FILE__,__LINE__); ! out << "VisualROI: centerX=" << m_xCen << " centerY=" << m_yCen << " half width=" << m_hsX << " half height=" << m_hsY << endl; } |
From: Pierre M. <sid...@us...> - 2005-06-17 21:15:59
|
Update of /cvsroot/robotflow/RobotFlow/Vision/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4392 Modified Files: MultiIntegralCuesPFTracker.cc CvFaceDetection.cc Log Message: Added feedback from detection to update tracked ROI. Index: CvFaceDetection.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/src/CvFaceDetection.cc,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** CvFaceDetection.cc 16 Jun 2005 15:15:08 -0000 1.2 --- CvFaceDetection.cc 17 Jun 2005 21:15:49 -0000 1.3 *************** *** 58,61 **** --- 58,65 ---- * @input_description Current skin color segmentation result. * + * @input_name IN_TRACKED_ROI + * @input_type VisualROI + * @input_description Region of interest currently tracked. + * * @input_name ACTIVATION * @input_type bool *************** *** 78,82 **** --- 82,88 ---- m_imageInID = addInput("IN_IMAGE"); m_maskInID = addInput("IN_SKIN_MASK"); + m_roiInID = addInput("IN_TRACKED_ROI"); m_activatedInID = addInput("ACTIVATION"); + m_roiOutID = addOutput("OUT_ROI"); *************** *** 131,134 **** --- 137,141 ---- } + struct timeb t1, t2; bool foundFace = false; *************** *** 148,174 **** ftime(&t1); ! // Try to get a skin mask ! ObjectRef maskRef = getInput(m_maskInID, count); ! if (!maskRef->isNil()) { ! // Initialize target at current ROI ! RCPtr<Image> skinMaskImgRef = maskRef; ! // Verify input image sanity ! if (skinMaskImgRef->get_width() != m_width || ! skinMaskImgRef->get_height() != m_height || ! skinMaskImgRef->get_pixelsize() != 1) { ! throw new GeneralException ("CvFaceDetection::calculate : skin mask image parameters do not correspond to given input.",__FILE__,__LINE__); } - - // Copy input image - memcpy(m_skinMask->imageData, skinMaskImgRef->get_data(), m_numPixels); - - foundFace = FaceDetectionWSkin(); } else { ! foundFace = FaceDetectionStd(); ! } ! // End timer ftime(&t2); --- 155,193 ---- ftime(&t1); ! // Get IN_TRACKED_ROI ! ObjectRef roiRef = getInput(m_roiInID, count); ! if (roiRef->isNil()) { ! // No tracked target, so do standard detection ! // Try to get a skin mask ! ObjectRef maskRef = getInput(m_maskInID, count); ! ! if (!maskRef->isNil()) { ! // Initialize target at current ROI ! RCPtr<Image> skinMaskImgRef = maskRef; ! ! // Verify input image sanity ! if (skinMaskImgRef->get_width() != m_width || ! skinMaskImgRef->get_height() != m_height || ! skinMaskImgRef->get_pixelsize() != 1) { ! throw new GeneralException ("CvFaceDetection::calculate : skin mask image parameters do not correspond to given input.",__FILE__,__LINE__); ! } ! ! // Copy input image ! memcpy(m_skinMask->imageData, skinMaskImgRef->get_data(), m_numPixels); ! ! foundFace = FaceDetectionWSkin(); ! } ! else { ! foundFace = FaceDetectionStd(); } } else { ! // Need to validate tracked ROI ! RCPtr<VisualROI> roiRefPtr = roiRef; ! ! foundFace = FaceDetectionWROI(roiRefPtr.get()); ! } // End timer ftime(&t2); *************** *** 197,200 **** --- 216,220 ---- (*outputs[m_roiOutID].buffer)[count] = ObjectRef(outImg); */ + } catch (BaseException *e) { *************** *** 442,449 **** --- 462,547 ---- } } + + bool FaceDetectionWROI(VisualROI *i_trackedROI) + { + try { + int trackedXCen = i_trackedROI->GetXCen(); + int trackedYCen = i_trackedROI->GetYCen(); + + cvClearMemStorage(m_storage1); + + // Detect upperbodies + CvSeq* faces = cvHaarDetectObjects( m_curImage, m_haarClassifier1, m_storage1, + 1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(0,0) ); + + cvClearMemStorage(m_storage2); + + CvSeq* profiles = cvHaarDetectObjects( m_curImage, m_haarClassifier2, m_storage2, + 1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(0,0) ); + + int curXCen = 0; + int curYCen = 0; + int curHSX = 0; + int curHSY = 0; + int i; + CvPoint pt1, pt2; + + // Find a face near the given ROI + for(i = 0; i < (faces ? faces->total : 0); i++ ) { + CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); + pt1.x = r->x; + pt2.x = (r->x+r->width); + pt1.y = r->y; + pt2.y = (r->y+r->height); + + if (trackedXCen > pt1.x && trackedXCen < pt2.x && + trackedYCen > pt1.y && trackedYCen < pt2.y) { + // Found a face in given ROI + curHSX = r->width/2; + curHSY = r->height/2; + curXCen = r->x + curHSX; + curYCen = r->y + curHSY; + m_faceROI->SetXCen(curXCen); + m_faceROI->SetYCen(curYCen); + m_faceROI->Reset(curHSX, curHSY, 0); + + return true; + } + } + + for(i = 0; i < (profiles ? profiles->total : 0); i++ ) { + CvRect* r = (CvRect*)cvGetSeqElem( profiles, i ); + pt1.x = r->x; + pt2.x = (r->x+r->width); + pt1.y = r->y; + pt2.y = (r->y+r->height); + + if (trackedXCen > pt1.x && trackedXCen < pt2.x && + trackedYCen > pt1.y && trackedYCen < pt2.y) { + // Found a face in given ROI + curHSX = r->width/2; + curHSY = r->height/2; + curXCen = r->x + curHSX; + curYCen = r->y + curHSY; + m_faceROI->SetXCen(curXCen); + m_faceROI->SetYCen(curYCen); + m_faceROI->Reset(curHSX, curHSY, 0); + + return true; + } + } + + // If we get here, there were no face detected near the given ROI + return false; + } + catch (BaseException *e) { + throw e->add(new GeneralException("Exception in CvFaceDetection::FaceDetectionStd:",__FILE__,__LINE__)); + } + } private: int m_imageInID; int m_maskInID; + int m_roiInID; int m_activatedInID; int m_roiOutID; Index: MultiIntegralCuesPFTracker.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/src/MultiIntegralCuesPFTracker.cc,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** MultiIntegralCuesPFTracker.cc 16 Jun 2005 15:13:56 -0000 1.1 --- MultiIntegralCuesPFTracker.cc 17 Jun 2005 21:15:49 -0000 1.2 *************** *** 149,152 **** --- 149,157 ---- * @parameter_description Color features weight. * + * @parameter_name REDETECTION_FREQUENCY + * @parameter_type int + * @parameter_value 30 + * @parameter_description Frequency of application of redetection of current tracked region (in number of frames). + * * @input_name INIT_VARIANCE * @input_type Vector<float> *************** *** 185,188 **** --- 190,197 ---- * @output_description Current target likelihood at current tracked position. * + * @output_name ROI_FOR_DETECTION + * @output_type VisualROI + * @output_description Current region of interest corresponding to the tracked target. IMPORTANT NOTE: Do not pull ROI_FOR_DETECTION output first since this will result in the output to be not synchoronized with the frames and the tracking process. + * END*/ *************** *** 215,218 **** --- 224,228 ---- m_targetOutID = addOutput("CURRENT_TARGET"); m_targetProbOutID = addOutput("TARGET_PROB"); + m_detectROIOutID = addOutput("ROI_FOR_DETECTION"); m_width = dereference_cast<int>(parameters.get("FRAME_WIDTH")); *************** *** 237,240 **** --- 247,251 ---- m_edgesCueWeight = dereference_cast<float>(parameters.get("EDGES_CUE_WEIGHT")); m_LBPCueWeight = dereference_cast<float>(parameters.get("LBP_CUE_WEIGHT")); + m_redetectFreq = dereference_cast<int>(parameters.get("REDETECTION_FREQUENCY")); m_numPixels = m_width*m_height; *************** *** 268,271 **** --- 279,284 ---- m_roiColor[1] = 0; m_roiColor[2] = 0; + + m_numSkipForRedetect = 0; } catch (BaseException *e) { *************** *** 274,278 **** } ! ~MultiIntegralCuesPFTracker() { delete m_predModel; --- 287,291 ---- } ! virtual ~MultiIntegralCuesPFTracker() { delete m_predModel; *************** *** 288,291 **** --- 301,364 ---- } + // Modified BufferedNode request method to support cyclic node connection + virtual void request(int output_id, const ParameterSet &req) + { + if (req.exist("LOOKAHEAD")) { + outputs[output_id].lookAhead = max(outputs[output_id].lookAhead,dereference_cast<int> (req.get("LOOKAHEAD"))); + } + + if (req.exist("LOOKBACK")) { + outputs[output_id].lookBack = max(outputs[output_id].lookBack,dereference_cast<int> (req.get("LOOKBACK"))); + } + + if (req.exist("INORDER")) { + inOrder = true; + } + + int outputLookAhead=0, outputLookBack=0; + + outputLookAhead=max(outputLookAhead, outputs[output_id].lookAhead); + outputLookBack =max(outputLookBack, outputs[output_id].lookBack); + + // Always request every inputs except CURRENT_ROI + // for feedback between tracking and detection. + ParameterSet actReq; + actReq.add("LOOKAHEAD", ObjectRef(Int::alloc(inputsCache[m_activatedInID].lookAhead+outputLookAhead))); + actReq.add("LOOKBACK", ObjectRef(Int::alloc(inputsCache[m_activatedInID].lookBack+outputLookBack))); + inputs[m_activatedInID].node->request(inputs[m_activatedInID].outputID,actReq); + + if (output_id == m_detectROIOutID) { + // ROI_FOR_DETECTION output does not required any inputs + // for feedback between tracking and detection. + + // IMPORTANT NOTE: + // Do not pull CURRENT_ROI output first since this + // will result in the output to be not synchoronized + // with the frames and the tracking process. + return; + } + else if (output_id == m_imageOutID || + output_id == m_roiOutID || + output_id == m_targetOutID || + output_id == m_targetProbOutID) { + ParameterSet myReq, myReq2, myReq3; + myReq.add("LOOKAHEAD", ObjectRef(Int::alloc(inputsCache[m_initVarianceInID].lookAhead+outputLookAhead))); + myReq.add("LOOKBACK", ObjectRef(Int::alloc(inputsCache[m_initVarianceInID].lookBack+outputLookBack))); + inputs[m_initVarianceInID].node->request(inputs[m_initVarianceInID].outputID,myReq); + + myReq2.add("LOOKAHEAD", ObjectRef(Int::alloc(inputsCache[m_imageInID].lookAhead+outputLookAhead))); + myReq2.add("LOOKBACK", ObjectRef(Int::alloc(inputsCache[m_imageInID].lookBack+outputLookBack))); + inputs[m_imageInID].node->request(inputs[m_imageInID].outputID,myReq2); + + myReq3.add("LOOKAHEAD", ObjectRef(Int::alloc(inputsCache[m_roiInID].lookAhead+outputLookAhead))); + myReq3.add("LOOKBACK", ObjectRef(Int::alloc(inputsCache[m_roiInID].lookBack+outputLookBack))); + inputs[m_roiInID].node->request(inputs[m_roiInID].outputID,myReq3); + } + else { + throw new GeneralException ("MultiIntegralCuesPFTracker::request : unknown output ID.",__FILE__,__LINE__); + } + + } + void calculate(int output_id, int count, Buffer &out) { *************** *** 306,309 **** --- 379,394 ---- } + if (output_id == m_detectROIOutID) { + if (m_refTarget->IsValid() && m_numSkipForRedetect < m_redetectFreq) { + // Output current tracked ROI + (*outputs[m_detectROIOutID].buffer)[count] = m_refTarget->GetROIRCPtr();; + } + else { + // Not a valid target, so output nilObject + (*outputs[m_detectROIOutID].buffer)[count] = nilObject; + } + return; + } + if (!m_initDone) { // Get variances only once for intialization *************** *** 362,365 **** --- 447,451 ---- m_particleFilter->InitSamples(); m_needInitTargetFeat = true; + m_numInitFrames = 0; } else { *************** *** 396,399 **** --- 482,486 ---- m_refTarget->InitAges(); m_needInitTargetFeat = false; + m_numSkipForRedetect = 0; } *************** *** 462,465 **** --- 549,590 ---- bool targetMatch = (sim >= m_targetMatchThres); + if (targetMatch) { + m_numSkipForRedetect++; + if (m_numSkipForRedetect >= m_redetectFreq) { + // Ask for redetection in current ROI + ObjectRef roiRef = getInput(m_roiInID, count); + + if (!roiRef->isNil()) { + // Detection found target + // Fully adapt target to given detection + RCPtr<VisualROI> roiRefPtr = roiRef; + m_refTarget->SetROI(roiRefPtr.get()); + + // Initialize PF samples + float *p_state = m_tmpSample->GetState(); + // Set position + *p_state++ = (float)(roiRefPtr->GetXCen()); + *p_state++ = (float)(roiRefPtr->GetYCen()); + // Add scale state + *p_state++ = (float)(roiRefPtr->GetHSX()); + *p_state++ = (float)(roiRefPtr->GetHSY()); + m_particleFilter->SetRefMeanSample(m_tmpSample); + m_particleFilter->InitSamples(); + + // Set features to given ROI + m_curSampleROIRef = m_refTarget->GetROIRCPtr(); + m_intClrExtract->ExtractFeatures(m_curSampleROIRef.get()); + m_intEdgExtract->ExtractFeatures(m_curSampleROIRef.get()); + m_intLBPExtract->ExtractFeatures(m_curSampleROIRef.get()); + (*m_featVecRef)[0] = m_intClrExtract->GetDescriptor(); + (*m_featVecRef)[1] = m_intEdgExtract->GetDescriptor(); + (*m_featVecRef)[2] = m_intLBPExtract->GetDescriptor(); + m_refTarget->SetDescriptorsVec(m_featVecRef.get()); + + m_numSkipForRedetect = 0; + } + } + } + m_refTarget->AgeTarget(targetMatch); if (sim > m_targetAdaptThres) { *************** *** 467,481 **** } - // End timer - ftime(&m_t2); - - // Display time used - double timeDiff=(m_t2.time-m_t1.time)+((m_t2.millitm-m_t1.millitm)/1000.0); - cout << "Total run time (sec): " << timeDiff << endl; - // // Produce outputs // // Check if target is still valid if (m_refTarget->GetCurrentAge() > -10) { --- 592,611 ---- } // // Produce outputs // + if (m_numInitFrames < 10) { + m_numSkipForRedetect = 0; + memcpy(outImage->get_data(), m_curImage->imageData, m_numBytesInFrame); + + (*outputs[m_imageOutID].buffer)[count] = ObjectRef(outImage); + (*outputs[m_roiOutID].buffer)[count] = ObjectRef(nilObject); + (*outputs[m_targetOutID].buffer)[count] = ObjectRef(nilObject); + (*outputs[m_targetProbOutID].buffer)[count] = ObjectRef(Float::alloc(0.0)); + m_numInitFrames++; + return; + } + // Check if target is still valid if (m_refTarget->GetCurrentAge() > -10) { *************** *** 492,495 **** --- 622,626 ---- // Invalidate it m_refTarget->SetValidity(false); + m_numSkipForRedetect = 0; memcpy(outImage->get_data(), m_curImage->imageData, m_numBytesInFrame); *************** *** 499,502 **** --- 630,640 ---- (*outputs[m_targetProbOutID].buffer)[count] = ObjectRef(Float::alloc(0.0)); } + + // End timer + ftime(&m_t2); + + // Display time used + double timeDiff=(m_t2.time-m_t1.time)+((m_t2.millitm-m_t1.millitm)/1000.0); + cout << "Total run time (sec): " << timeDiff << endl; } catch (BaseException *e) { *************** *** 549,552 **** --- 687,691 ---- int m_targetOutID; int m_targetProbOutID; + int m_detectROIOutID; RCPtr<Bool> m_activated; *************** *** 580,583 **** --- 719,726 ---- double m_LBPCueWeight; + int m_numInitFrames; + int m_numSkipForRedetect; + int m_redetectFreq; + int m_numSamples; int m_sampleStateSize; |
From: Pierre M. <sid...@us...> - 2005-06-16 21:04:06
|
Update of /cvsroot/robotflow/RobotFlow/Vision/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8395 Modified Files: TextSignDetect.cc Log Message: Fixed output ROI position to center of ROI which was originally the upper left corner position. Index: TextSignDetect.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/src/TextSignDetect.cc,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** TextSignDetect.cc 16 Jun 2005 18:18:30 -0000 1.4 --- TextSignDetect.cc 16 Jun 2005 21:03:57 -0000 1.5 *************** *** 159,162 **** --- 159,163 ---- m_edges = cvCreateImage( imgSize, IPL_DEPTH_8U, 1 ); m_binarized = cvCreateImage( imgSize, IPL_DEPTH_8U, 1 ); + m_tmpBinarized = cvCreateImage( imgSize, IPL_DEPTH_8U, 1 ); m_oriXImage = cvCreateImage( imgSize, IPL_DEPTH_16S, 1 ); m_oriYImage = cvCreateImage( imgSize, IPL_DEPTH_16S, 1 ); *************** *** 209,212 **** --- 210,214 ---- cvReleaseImage(&m_edges); cvReleaseImage(&m_binarized); + cvReleaseImage(&m_tmpBinarized); } *************** *** 587,593 **** if (curRegionIdx != -1) { ! m_outROI->SetXCen(m_textROI[curRegionIdx].x); ! m_outROI->SetYCen(m_textROI[curRegionIdx].y); ! m_outROI->Reset(m_textROI[curRegionIdx].width/2, m_textROI[curRegionIdx].height/2, 0); --- 589,597 ---- if (curRegionIdx != -1) { ! int hsx = m_textROI[curRegionIdx].width/2; ! int hsy = m_textROI[curRegionIdx].height/2; ! m_outROI->SetXCen(m_textROI[curRegionIdx].x + hsx); ! m_outROI->SetYCen(m_textROI[curRegionIdx].y + hsy); ! m_outROI->Reset(hsx, hsy, 0); *************** *** 597,604 **** //set region of interest cvSetImageROI(m_gray,m_textROI[curRegionIdx]); ! cvSetImageROI(m_binarized,m_textROI[curRegionIdx]); //binarize ! cvThreshold(m_gray,m_binarized,threshold,255,CV_THRESH_BINARY); --- 601,614 ---- //set region of interest cvSetImageROI(m_gray,m_textROI[curRegionIdx]); ! //cvSetImageROI(m_binarized,m_textROI[curRegionIdx]); ! cvSetImageROI(m_tmpBinarized,m_textROI[curRegionIdx]); //binarize ! //cvThreshold(m_gray,m_binarized,threshold,255,CV_THRESH_BINARY); ! cvThreshold(m_gray,m_tmpBinarized,threshold,255,CV_THRESH_BINARY); ! ! cvResize(m_tmpBinarized, m_binarized, CV_INTER_LINEAR); ! cvErode(m_binarized, m_binarized, NULL, 2); ! cvSmooth(m_binarized, m_binarized, CV_GAUSSIAN, 3, 3); *************** *** 898,901 **** --- 908,912 ---- IplImage *m_edges; IplImage *m_binarized; + IplImage *m_tmpBinarized; IplImage *m_oriXImage; IplImage *m_oriYImage; |
From: Fernyqc <fe...@us...> - 2005-06-16 20:57:21
|
Update of /cvsroot/robotflow/RobotFlow/Behaviors/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4460 Modified Files: FollowWall.cc Log Message: 1) Correction of the sign of the angular correction; 2) Parameters modification Index: FollowWall.cc =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Behaviors/src/FollowWall.cc,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** FollowWall.cc 10 Jun 2005 19:33:33 -0000 1.2 --- FollowWall.cc 16 Jun 2005 20:57:13 -0000 1.3 *************** *** 62,73 **** * @output_description Robot Rotation value (degrees/s) * - * @output_name RIGHTWALL - * @output_type bool - * @output_description Wall to the right? - * - * @output_name LEFTWALL - * @output_type bool - * @output_description Wall to the left? - * * @parameter_name MAX_VELOCITY * @parameter_description Velocity max (mm/s) --- 62,65 ---- *************** *** 91,97 **** * * @parameter_name MAX_DIST_WALL ! * @parameter_description Distance max to look for a wall (mm) * @parameter_type int ! * @parameter_value 5000 * * @parameter_name MIN_DIST_WALL --- 83,89 ---- * * @parameter_name MAX_DIST_WALL ! * @parameter_description Distance max to be away from the wall * @parameter_type int ! * @parameter_value 3000 * * @parameter_name MIN_DIST_WALL *************** *** 100,112 **** * @parameter_value 1000 * ! * @parameter_name DIST_TOLERANCE ! * @parameter_description Distance tolerance (mm) * @parameter_type int * @parameter_value 500 * * @parameter_name ANGULAR_CORRECTION * @parameter_description Extra correction to apply in the heading (degrees) * @parameter_type int ! * @parameter_value 10 * * @parameter_name ANGULAR_TRESHOLD --- 92,109 ---- * @parameter_value 1000 * ! * @parameter_name DIST_TOL_CENTER ! * @parameter_description Distance tolerance to the center (mm). Used only when two walls are present * @parameter_type int * @parameter_value 500 * + * @parameter_name MAX_DIST_DETECTION + * @parameter_description Maximum distance to look for a wall (mm) + * @parameter_type int + * @parameter_value 5000 + * * @parameter_name ANGULAR_CORRECTION * @parameter_description Extra correction to apply in the heading (degrees) * @parameter_type int ! * @parameter_value 5 * * @parameter_name ANGULAR_TRESHOLD *************** *** 148,157 **** * @parameter_description Value of the estimator for the test of confidence * @parameter_type float ! * @parameter_value 8 * * @parameter_name STD_DEVIATION * @parameter_description Std.dev of the estimator for the test of confidence * @parameter_type float ! * @parameter_value 2 * * @parameter_name NB_SAMPLE_STD_DEVIATION --- 145,154 ---- * @parameter_description Value of the estimator for the test of confidence * @parameter_type float ! * @parameter_value 5 * * @parameter_name STD_DEVIATION * @parameter_description Std.dev of the estimator for the test of confidence * @parameter_type float ! * @parameter_value 3 * * @parameter_name NB_SAMPLE_STD_DEVIATION *************** *** 177,183 **** int rotationID; int velocityID; ! int rightwallID; ! int leftwallID; ! // Motor command parameters int m_max_velocity; --- 174,178 ---- int rotationID; int velocityID; ! // Motor command parameters int m_max_velocity; *************** *** 192,196 **** int m_max_dist_wall; int m_min_dist_wall; ! int m_dist_tolerance; int m_angular_correction; int m_angular_treshold; --- 187,192 ---- int m_max_dist_wall; int m_min_dist_wall; ! int m_dist_center; ! int m_dist_detection; int m_angular_correction; int m_angular_treshold; *************** *** 305,310 **** // Logging ! static std::ofstream laser("/home/marie/laserRight.txt"); ! static std::ofstream cmd1("/home/marie/cmdRight.txt"); static int logNumber = 0; if(toLog){ --- 301,306 ---- // Logging ! static std::ofstream laser("laserRight.txt"); ! static std::ofstream cmd1("cmdRight.txt"); static int logNumber = 0; if(toLog){ *************** *** 365,370 **** // Logging ! static std::ofstream laser("/home/marie/laserLeft.txt"); ! static std::ofstream cmd1("/home/marie/cmdLeft.txt"); static int logNumber = 0; if(toLog){ --- 361,366 ---- // Logging ! static std::ofstream laser("laserLeft.txt"); ! static std::ofstream cmd1("cmdLeft.txt"); static int logNumber = 0; if(toLog){ *************** *** 433,438 **** rotationID = addOutput("ROTATION"); velocityID = addOutput("VELOCITY"); - rightwallID = addOutput("RIGHTWALL"); - leftwallID = addOutput("LEFTWALL"); //Motor command parameters --- 429,432 ---- *************** *** 464,468 **** m_max_dist_wall = dereference_cast<int> (parameters.get("MAX_DIST_WALL")); m_min_dist_wall = dereference_cast<int> (parameters.get("MIN_DIST_WALL")); ! m_dist_tolerance = dereference_cast<int> (parameters.get("DIST_TOLERANCE")); m_angular_correction = dereference_cast<int> (parameters.get("ANGULAR_CORRECTION")); --- 458,463 ---- m_max_dist_wall = dereference_cast<int> (parameters.get("MAX_DIST_WALL")); m_min_dist_wall = dereference_cast<int> (parameters.get("MIN_DIST_WALL")); ! m_dist_center = dereference_cast<int> (parameters.get("DIST_TOL_CENTER")); ! m_dist_detection = dereference_cast<int> (parameters.get("MAX_DIST_DETECTION")); m_angular_correction = dereference_cast<int> (parameters.get("ANGULAR_CORRECTION")); *************** *** 479,489 **** m_end_left = m_begin_left - m_nbLaserSample * m_range_increment; - //Reajusting to avoid array overflow - //while(m_end_left > (m_laser_range/m_laser_increment)) - // m_end_left = m_end_left - 1; - //m_nbLaserSample = static_cast<int>(((m_begin_left - m_end_left) / m_range_increment)/m_range_increment); - //m_end_right = m_begin_right + m_nbLaserSample * m_range_increment; - //m_begin_left = m_end_left - m_nbLaserSample * m_range_increment; - //Interval of confidence parameters m_degree_confidence = dereference_cast<float> (parameters.get("DEGREE_CONFIDENCE")); --- 474,477 ---- *************** *** 494,498 **** //Log file to validate calculation ! std::ofstream cfg("/home/marie/config.txt"); cfg << "Motor command parameters " << std::endl; cfg << "m_max_velocity -> " << m_max_velocity << std::endl; --- 482,486 ---- //Log file to validate calculation ! /*std::ofstream cfg("config.txt"); cfg << "Motor command parameters " << std::endl; cfg << "m_max_velocity -> " << m_max_velocity << std::endl; *************** *** 515,519 **** cfg << "m_max_dist_wall -> " << m_max_dist_wall << std::endl; cfg << "m_min_dist_wall -> " << m_min_dist_wall << std::endl; ! cfg << "m_dist_tolerance -> " << m_dist_tolerance << std::endl; cfg << "m_angular_correction -> " << m_angular_correction << std::endl; cfg << "m_angular_treshold -> " << m_angular_treshold << std::endl; --- 503,508 ---- cfg << "m_max_dist_wall -> " << m_max_dist_wall << std::endl; cfg << "m_min_dist_wall -> " << m_min_dist_wall << std::endl; ! cfg << "m_dist_center -> " << m_dist_center << std::endl; ! cfg << "m_dist_detection -> " << m_dist_detection << std::endl; cfg << "m_angular_correction -> " << m_angular_correction << std::endl; cfg << "m_angular_treshold -> " << m_angular_treshold << std::endl; *************** *** 538,542 **** cfg << "zValue -> " << lookupZValue(m_degree_confidence) << std::endl; cfg << "m_maxStdDevBeta -> " << m_maxStdDevBeta << std::endl; ! cfg.close(); } --- 527,531 ---- cfg << "zValue -> " << lookupZValue(m_degree_confidence) << std::endl; cfg << "m_maxStdDevBeta -> " << m_maxStdDevBeta << std::endl; ! cfg.close();*/ } *************** *** 570,578 **** leftWall = detectLeftWall(laserReading, distLeftWall, angularCorrectionLeft, toLog); ! (*outputs[rightwallID].buffer)[count] = ObjectRef(Bool::alloc(rightWall)); ! (*outputs[leftwallID].buffer)[count] = ObjectRef(Bool::alloc(leftWall)); // Compute motor command float angularCorrection=0; if (rightWall || leftWall) { --- 559,577 ---- leftWall = detectLeftWall(laserReading, distLeftWall, angularCorrectionLeft, toLog); ! // Ignore walls too far ! if(distRightWall > m_dist_detection){ ! rightWall = false; ! distRightWall = 0; ! angularCorrectionRight = 0; ! } ! if(distLeftWall > m_dist_detection){ ! leftWall = false; ! distLeftWall = 0; ! angularCorrectionLeft = 0; ! } // Compute motor command float angularCorrection=0; + int sign=1; if (rightWall || leftWall) { *************** *** 585,605 **** // Closest dist to the wall if(distRightWall < distLeftWall) ! distWall = distRightWall; ! else distWall = distLeftWall; // Angular correction ! angularCorrection = (angularCorrectionLeft+angularCorrectionRight)/2; ! if(distCenter - distWall > m_dist_tolerance) ! angularCorrection += m_angular_correction; } else{ // Wall to the left or the right ! distWall = distRightWall + distLeftWall; // One will be 0 angularCorrection = angularCorrectionRight + angularCorrectionLeft; // One will be 0 ! // Angular correction if(distWall < m_min_dist_wall) ! angularCorrection += m_angular_correction; ! else if(distWall > m_max_dist_wall-m_dist_tolerance) ! angularCorrection -= m_angular_correction; } --- 584,611 ---- // Closest dist to the wall if(distRightWall < distLeftWall) ! distWall = distLeftWall; ! else distWall = distRightWall; // Angular correction ! angularCorrection = (fabs(angularCorrectionLeft)+fabs(angularCorrectionRight))/2; ! if(fabs(angularCorrectionRight) > fabs(angularCorrectionLeft)) ! sign = (angularCorrectionRight<0)?-1:1; ! else ! sign = (angularCorrectionLeft<0)?-1:1; ! ! // To stay between the walls ! if(distCenter - distWall > m_dist_center) ! angularCorrection += sign*m_angular_correction; } else{ // Wall to the left or the right ! distWall = distRightWall + distLeftWall; // One will be 0 angularCorrection = angularCorrectionRight + angularCorrectionLeft; // One will be 0 + sign = (angularCorrection<0)?-1:1; ! // Angular correction to stay between at a proper distance from the wall if(distWall < m_min_dist_wall) ! angularCorrection += sign*m_angular_correction; ! else if(distWall > m_max_dist_wall) ! angularCorrection -= sign*m_angular_correction; } *************** *** 607,623 **** int speedInd = speedValue(angularCorrection); int velocity = m_velocity_chart.at(speedInd); ! int rotation = m_rotation_chart.at(speedInd); // Motor cmd debug ! static std::ofstream cmdMotor("/home/marie/motorCmd.txt"); static int logNb = 0; ! if(toLog){ ! cmdMotor << "logNb -> " << logNb << std::endl; ! cmdMotor << "angularCorrection -> " << angularCorrection << std::endl; ! cmdMotor << "speedInd -> " << speedInd << std::endl; ! cmdMotor << "velocity -> " << velocity << std::endl; ! cmdMotor << "rotation -> " << rotation << std::endl; ! ++logNb; ! } // Send motor command (*outputs[rotationID].buffer)[count] = ObjectRef(Int::alloc(rotation)); --- 613,631 ---- int speedInd = speedValue(angularCorrection); int velocity = m_velocity_chart.at(speedInd); ! int rotation = sign * m_rotation_chart.at(speedInd); // Motor cmd debug ! static std::ofstream cmdMotor("motorCmd.txt"); static int logNb = 0; ! static int header=1; ! if(header){ ! header = 0; ! cmdMotor << "Log\tAngleCorr\tspeedInd\tvel\trotation" << std::endl; ! } ! if (toLog){ ! cmdMotor << "log" << logNb << "\t" << angularCorrection << "\t" << speedInd << "\t" << velocity << "\t" << rotation << std::endl; ! ++logNb; ! } ! // Send motor command (*outputs[rotationID].buffer)[count] = ObjectRef(Int::alloc(rotation)); |
From: Pierre M. <sid...@us...> - 2005-06-16 19:38:46
|
Update of /cvsroot/robotflow/RobotFlow/Vision/include In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28246 Modified Files: VisualIntegralDesc.h Log Message: Fixed some division by zero cases. Index: VisualIntegralDesc.h =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/Vision/include/VisualIntegralDesc.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** VisualIntegralDesc.h 9 Jun 2005 17:12:08 -0000 1.3 --- VisualIntegralDesc.h 16 Jun 2005 19:38:38 -0000 1.4 *************** *** 358,361 **** --- 358,362 ---- diff = ((*p_curFeat) - (*p_candFeat))/m_maxDiffValue; clrDist += (double)(diff*diff); + p_curFeat++; p_candFeat++; |
From: Dominic L. <ma...@us...> - 2005-06-16 19:01:01
|
Update of /cvsroot/robotflow/RobotFlow/demo/SymbolRecog/color_lookup In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6383/color_lookup Modified Files: black_orange.data Log Message: recog tests Index: black_orange.data =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/demo/SymbolRecog/color_lookup/black_orange.data,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** black_orange.data 2 Jan 2005 14:44:01 -0000 1.2 --- black_orange.data 16 Jun 2005 19:00:39 -0000 1.3 *************** *** 1,4 **** <ColorLookup ! <Data 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 3 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 3 2 3 3 3 3 3 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 3 3 3 3 3 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 3 3 3 3 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 3 3 3 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 3 3 3 3 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 3 3 3 3 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 3 3 2 3 3 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 3 3 3 3 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 3 2 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 2 2 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 2 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 2 3 3 3 3 3 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 3 3 3 3 3 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 3 3 3 3 3 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 3 3 3 3 3 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 3 3 3 3 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 3 3 3 3 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 3 3 3 3 3 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 1 1 1 1 1 3 3 2 3 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 3 3 3 2 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 3 3 3 2 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 3 3 3 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 3 3 3 3 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 3 3 3 3 3 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 3 3 3 3 3 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 3 3 3 3 3 3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 3 3 3 3 3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 3 3 3 3 3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 3 3 3 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 3 3 3 3 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 3 3 3 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 3 3 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 3 2 3 3 3 3 3 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 1 2 3 3 3 3 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 3 3 3 3 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 3 3 3 3 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 3 1 1 1 1 2 3 3 3 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 1 1 1 1 1 0 3 3 3 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 2 3 3 3 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 2 3 3 3 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 3 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 2 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 2 2 3 3 3 3 3 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 3 2 3 3 3 3 3 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 3 3 2 3 3 3 3 3 3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 3 2 3 3 3 3 3 3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 3 1 1 1 3 2 3 3 3 3 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 3 1 1 1 1 2 3 3 3 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 1 1 1 1 2 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 3 3 3 3 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 3 3 3 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 1 1 1 1 3 1 3 3 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 3 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 3 3 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 3 3 3 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 3 2 2 3 3 3 3 3 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 3 3 2 3 3 3 3 3 3 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 3 3 2 3 3 3 3 3 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 3 3 3 3 2 3 3 3 3 3 3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 3 3 3 3 2 3 3 3 3 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 3 1 3 3 1 2 3 3 3 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 3 3 3 1 2 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 1 1 1 3 2 3 3 3 3 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 3 2 1 3 3 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 3 3 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 3 1 1 3 3 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 3 2 2 3 3 3 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 3 3 2 2 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 3 3 3 2 3 3 3 3 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 3 3 3 3 2 3 3 3 3 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 3 3 3 3 3 2 3 3 3 3 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 3 3 3 3 1 2 3 3 3 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 3 3 3 1 2 3 3 3 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 1 3 1 3 2 3 3 3 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 1 1 3 3 2 3 3 3 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 1 1 1 3 0 3 3 3 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 1 1 1 1 1 3 3 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 3 3 1 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... [truncated message content] |
From: Dominic L. <ma...@us...> - 2005-06-16 19:01:01
|
Update of /cvsroot/robotflow/RobotFlow/demo/SymbolRecog/n-files In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6383/n-files Modified Files: Recog.n Log Message: recog tests Index: Recog.n =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/demo/SymbolRecog/n-files/Recog.n,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Recog.n 8 Jun 2005 14:48:02 -0000 1.1 --- Recog.n 16 Jun 2005 19:00:52 -0000 1.2 *************** *** 7,11 **** </Node> <Node name="node_LoadFile_1" type="LoadFile" x="-695.000000" y="-97.000000"> ! <Parameter name="FILENAME" type="string" value="../color_lookup/black_white.data" description="No description available"/> </Node> <Node name="node_LoadFile_2" type="LoadFile" x="-694.000000" y="-123.000000"> --- 7,11 ---- </Node> <Node name="node_LoadFile_1" type="LoadFile" x="-695.000000" y="-97.000000"> ! <Parameter name="FILENAME" type="string" value="../color_lookup/black_white_gs.data" description="No description available"/> </Node> <Node name="node_LoadFile_2" type="LoadFile" x="-694.000000" y="-123.000000"> *************** *** 19,22 **** --- 19,23 ---- <Link from="node_LoadFile_3" output="OUTPUT" to="node_MAIN_LOOP_1" input="NNET"/> <NetOutput name="SENTENCE" node="node_MAIN_LOOP_1" terminal="SENTENCE" object_type="" description="Pass through"/> + <NetOutput name="BIN_IMAGE" node="node_MAIN_LOOP_1" terminal="BIN_IMAGE" object_type="any" description="No description available"/> <Note x="0" y="0" visible="0" text="Created with FlowDesigner 0.9.0"/> </Network> *************** *** 24,28 **** <Node name="node_READv2_1" type="READv2" x="-51.000000" y="162.000000"> <Parameter name="MIN_SYMBOL_HEIGHT" type="int" value="30" description="No description available"/> ! <Parameter name="MIN_SYMBOL_WIDTH" type="int" value="15" description="No description available"/> </Node> <Node name="node_SNCRZ30_1" type="SNCRZ30" x="-1451.000000" y="160.000000"> --- 25,34 ---- <Node name="node_READv2_1" type="READv2" x="-51.000000" y="162.000000"> <Parameter name="MIN_SYMBOL_HEIGHT" type="int" value="30" description="No description available"/> ! <Parameter name="MIN_SYMBOL_WIDTH" type="int" value="5" description="No description available"/> ! <Parameter name="MIN_DICT_SCORE" type="float" value="0.5" description="No description available"/> ! <Parameter name="MIN_DIGIT_SCORE" type="float" value="0.8" description="No description available"/> ! <Parameter name="DICT_ONLY" type="bool" value="true" description="No description available"/> ! <Parameter name="VERTICAL_TOLERANCE" type="float" value="0.8" description="No description available"/> ! <Parameter name="HORIZONTAL_TOLERANCE" type="float" value="0.8" description="No description available"/> </Node> <Node name="node_SNCRZ30_1" type="SNCRZ30" x="-1451.000000" y="160.000000"> *************** *** 36,40 **** </Node> <Node name="node_NilObject_1" type="NilObject" x="-1709.000000" y="122.000000"/> ! <Node name="node_TextProbe_1" type="TextProbe" x="65.000000" y="161.000000"> <Parameter name="BREAK_AT" type="int" value="-1" description="If set, the probe runs until (count = BREAK_AT)"/> <Parameter name="SHOW" type="bool" value="true" description="Whether or not to show the the data by default"/> --- 42,46 ---- </Node> <Node name="node_NilObject_1" type="NilObject" x="-1709.000000" y="122.000000"/> ! <Node name="node_TextProbe_1" type="TextProbe" x="194.000000" y="156.000000"> <Parameter name="BREAK_AT" type="int" value="-1" description="If set, the probe runs until (count = BREAK_AT)"/> <Parameter name="SHOW" type="bool" value="true" description="Whether or not to show the the data by default"/> *************** *** 48,83 **** <Parameter name="VALUE" type="bool" value="true" description="The value"/> </Node> ! <Node name="node_ImageProbeSDL_1" type="ImageProbeSDL" x="-373.000000" y="210.000000"> <Parameter name="HEIGHT" type="int" value="240" description="The height of the image"/> <Parameter name="WIDTH" type="int" value="320" description="The width of the image"/> </Node> ! <Node name="node_Binarize_1" type="Binarize" x="-531.000000" y="209.000000"/> ! <Node name="node_RGB242RGB15_1" type="RGB242RGB15" x="-1200.000000" y="182.000000"/> ! <Node name="node_StatIntensityAnalyser_1" type="StatIntensityAnalyser" x="-1035.000000" y="182.000000"> ! <Parameter name="FRACTION_ANALYSED" type="float" value="0.1" description="Fraction of pixels to analyse (on a 0-1 scale)"/> </Node> ! <Node name="node_Add_1" type="Add" x="-749.000000" y="169.000000"/> ! <Node name="node_Div_1" type="Div" x="-927.000000" y="271.000000"/> ! <Node name="node_Constant_1" type="Constant" x="-1108.000000" y="386.000000"> ! <Parameter name="VALUE" type="float" value="2" description="The value"/> </Node> - <Link from="node_NilObject_1" output="VALUE" to="node_SNCRZ30_1" input="PAN_ABS_POS"/> <Link from="node_NilObject_1" output="VALUE" to="node_SNCRZ30_1" input="TILT_ABS_POS"/> - <Link from="node_NilObject_1" output="VALUE" to="node_SNCRZ30_1" input="PAN_REL_POS"/> - <Link from="node_NilObject_1" output="VALUE" to="node_SNCRZ30_1" input="TILT_REL_POS"/> - <Link from="node_NilObject_1" output="VALUE" to="node_SNCRZ30_1" input="ZOOM_ABS_POS"/> <Link from="node_NilObject_1" output="VALUE" to="node_SNCRZ30_1" input="ZOOM_REL_POS"/> <Link from="node_READv2_1" output="SENTENCE" to="node_TextProbe_1" input="INPUT"/> <Link from="node_Constant_2" output="VALUE" to="node_READv2_1" input="SIGN_TRACKING_ACTIVATED"/> ! <Link from="node_ImageProbeSDL_1" output="OUTPUT" to="node_READv2_1" input="RGB15_BINARIZED"/> ! <Link from="node_Binarize_1" output="IMAGE_OUT" to="node_ImageProbeSDL_1" input="INPUT"/> ! <Link from="node_SNCRZ30_1" output="IMAGE" to="node_Binarize_1" input="IMAGE_IN">-1306 182.5 -1019 300 -766 301 -644.5 216.5 </Link> ! <Link from="node_SNCRZ30_1" output="IMAGE" to="node_RGB242RGB15_1" input="RGB24_IMAGE"/> ! <Link from="node_RGB242RGB15_1" output="RGB15_IMAGE" to="node_StatIntensityAnalyser_1" input="IMAGE_IN"/> ! <Link from="node_StatIntensityAnalyser_1" output="MAX_INTENSITY" to="node_Add_1" input="INPUT1"/> ! <Link from="node_StatIntensityAnalyser_1" output="MIN_INTENSITY" to="node_Add_1" input="INPUT2"/> ! <Link from="node_Add_1" output="OUTPUT" to="node_Div_1" input="NUM"/> ! <Link from="node_Constant_1" output="VALUE" to="node_Div_1" input="DEN"/> ! <Link from="node_Div_1" output="OUTPUT" to="node_Binarize_1" input="THRESHOLD"/> <NetOutput name="SENTENCE" node="node_TextProbe_1" terminal="OUTPUT" object_type="any" description="Pass through"/> <NetInput name="NNET" node="node_READv2_1" terminal="NNET" object_type="any" description="No description available"/> --- 54,93 ---- <Parameter name="VALUE" type="bool" value="true" description="The value"/> </Node> ! <Node name="node_ImageProbeSDL_1" type="ImageProbeSDL" x="-524.000000" y="347.000000"> <Parameter name="HEIGHT" type="int" value="240" description="The height of the image"/> <Parameter name="WIDTH" type="int" value="320" description="The width of the image"/> </Node> ! <Node name="node_TextSignDetect_1" type="TextSignDetect" x="-961.000000" y="368.000000"> ! <Parameter name="FRAME_WIDTH" type="int" value="320" description="Video frame width."/> ! <Parameter name="FRAME_HEIGHT" type="int" value="240" description="Video frame height."/> ! <Parameter name="NUM_CHANNELS" type="int" value="3" description="Video frame number of channels."/> ! <Parameter name="NUM_ORIENTATIONS" type="int" value="6" description="Number of bins for the local edge histogram."/> ! <Parameter name="EDGES_STRENGTH_THRESHOLD" type="float" value="50.0" description="Threshold to remove noisy/weak edges."/> ! <Parameter name="TEXT_ROI_MIN_WIDTH" type="int" value="10" description="Minimal width of a potential region of interest to consider it as text."/> ! <Parameter name="TEXT_ROI_MIN_HEIGHT" type="int" value="4" description="Minimal height of a potential region of interest to consider it as text."/> ! <Parameter name="TEXT_ROI_MAX_WIDTH" type="int" value="320" description="Maximal width of a potential region of interest to consider it as text."/> ! <Parameter name="TEXT_ROI_MAX_HEIGHT" type="int" value="80" description="Maximal height of a potential region of interest to consider it as text."/> ! <Parameter name="MAX_STD_ORIENTATION_BINS" type="float" value="0.75" description="Maximal standard deviation of the local edge orientation histogram bins heightEdges orientation histogram of a potential region of interest to consider it as text."/> ! <Parameter name="MAX_NUM_TEXT_ROI" type="int" value="100" description="Maximum number of text region of interest to use."/> ! <Parameter name="MAX_STD" type="float" value="0" description="Low threshold used for edge searching."/> ! <Parameter name="MIN_DIST" type="float" value="60" description="High threshold used for edge searching."/> ! <Parameter name="HORIZONTAL_SYMMETRY_THRESHOLD" type="float" value="80.0" description="Horizontal edge orientation symmetry treshold. Text region should have lower values than threshold."/> ! <Parameter name="VERTICAL_SYMMETRY_THRESHOLD" type="float" value="80.0" description="Vertical edge orientation symmetry treshold. Text region should have lower values than threshold."/> </Node> ! <Node name="node_Constant_4" type="Constant" x="-1311.000000" y="436.000000"> ! <Parameter name="VALUE" type="bool" value="true" description="The value"/> </Node> <Link from="node_NilObject_1" output="VALUE" to="node_SNCRZ30_1" input="TILT_ABS_POS"/> <Link from="node_NilObject_1" output="VALUE" to="node_SNCRZ30_1" input="ZOOM_REL_POS"/> <Link from="node_READv2_1" output="SENTENCE" to="node_TextProbe_1" input="INPUT"/> <Link from="node_Constant_2" output="VALUE" to="node_READv2_1" input="SIGN_TRACKING_ACTIVATED"/> ! <Link from="node_NilObject_1" output="VALUE" to="node_SNCRZ30_1" input="PAN_ABS_POS"/> ! <Link from="node_NilObject_1" output="VALUE" to="node_SNCRZ30_1" input="PAN_REL_POS"/> ! <Link from="node_NilObject_1" output="VALUE" to="node_SNCRZ30_1" input="TILT_REL_POS"/> ! <Link from="node_NilObject_1" output="VALUE" to="node_SNCRZ30_1" input="ZOOM_ABS_POS"/> ! <Link from="node_TextSignDetect_1" output="TEXT_ROI_IMG" to="node_ImageProbeSDL_1" input="INPUT"/> ! <Link from="node_SNCRZ30_1" output="IMAGE" to="node_TextSignDetect_1" input="IN_IMAGE"/> ! <Link from="node_Constant_4" output="VALUE" to="node_TextSignDetect_1" input="ACTIVATION"/> ! <Link from="node_TextSignDetect_1" output="TEXT_ROI_IMG" to="node_READv2_1" input="RGB15_BINARIZED"/> <NetOutput name="SENTENCE" node="node_TextProbe_1" terminal="OUTPUT" object_type="any" description="Pass through"/> <NetInput name="NNET" node="node_READv2_1" terminal="NNET" object_type="any" description="No description available"/> *************** *** 85,88 **** --- 95,99 ---- <NetInput name="BLACK_WHITE_LOOKUP" node="node_READv2_1" terminal="BLACK_WHITE_LOOKUP" object_type="any" description="No description available"/> <NetCondition name="CONDITION" node="node_Constant_3" terminal="VALUE"/> + <NetOutput name="BIN_IMAGE" node="node_ImageProbeSDL_1" terminal="OUTPUT" object_type="any" description="No description available"/> <Note x="0" y="0" visible="0" text="Created with FlowDesigner 0.9.0"/> </Network> |
From: Dominic L. <ma...@us...> - 2005-06-16 19:01:00
|
Update of /cvsroot/robotflow/RobotFlow/demo/SymbolRecog/dict In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6383/dict Modified Files: fox.dict Log Message: recog tests Index: fox.dict =================================================================== RCS file: /cvsroot/robotflow/RobotFlow/demo/SymbolRecog/dict/fox.dict,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** fox.dict 8 Jun 2005 13:18:39 -0000 1.2 --- fox.dict 16 Jun 2005 19:00:52 -0000 1.3 *************** *** 1,2 **** ! <Vector<String> <String A> <String BROWN> <String DOG> <String FOX> <String JUMPS> <String LAZY> <String OVER> <String QUICK> <String THE> <String SERVICE> <String EXIT> <String PROJECT> <String URBAN> <String TU> <String ES> <String UN> <String ROBOT> > --- 1,20 ---- ! <Vector<String> ! <String A> ! <String BROWN> ! <String DOG> ! <String FOX> ! <String JUMPS> ! <String LAZY> ! <String OVER> ! <String QUICK> ! <String THE> ! <String SERVICE> ! <String EXIT> ! <String PROJECT> ! <String URBAN> ! <String TU> ! <String ES> ! <String UN> ! <String ROBOT> ! > |