float PerformanceUtils::NrTrueNegatives(IplImage* image, IplImage* ground_truth, bool debug)
{
  float nTN = 0.0;

  unsigned char *pixelGT = (unsigned char *)malloc(1*sizeof(unsigned char));
  unsigned char *pixelI = (unsigned char *)malloc(1*sizeof(unsigned char));

  IplImage *TNimage = 0;

  if(debug)
  {
    TNimage = cvCreateImage(cvSize(image->width,image->height),image->depth,image->nChannels);
    cvFillImage(TNimage, 0.0);
  }

  PixelUtils p;

  for(int y = 0; y < image->height; y++) 
  {
    for(int x = 0; x < image->width; x++) 
    {
      p.GetGrayPixel(ground_truth,x,y,pixelGT);                
      p.GetGrayPixel(image,x,y,pixelI);

      if((pixelGT[0] == 0) && (pixelI[0] == 0.0))
      {
        *pixelI = 255;

        if(debug)
          p.PutGrayPixel(TNimage,x,y,*pixelI);

        nTN++;
      }				
    }
  }

  if(debug)
  {
    cvNamedWindow("TNImage", 0);
    cvShowImage("TNImage", TNimage);
    //std::cout << "True Negatives: " << nTN << std::endl;
    //<< " press ENTER to continue" << std::endl;
    //cvWaitKey(0);
    cvReleaseImage(&TNimage);
  }

  free(pixelGT);
  free(pixelI);

  return nTN;
}
//----------------------------------------------------
void ofxCvMaskImageGui::setup(string _quadName, int _width, int _height){
	quadName = _quadName;
	bAdjustedView = false;	
	width = _width;
	height = _height;
	penDiameter = 30.0;
	
	maskFile.allocate(_width, _height, OF_IMAGE_GRAYSCALE);
	cvTempImage.allocate( maskFile.getWidth(), maskFile.getHeight() );
	cvMaskImage.allocate( maskFile.getWidth(), maskFile.getHeight() );
	
	cvFillImage(cvMaskImage.getCvImage(), 255.0);
	cvZero(cvTempImage.getCvImage());
	
	cvMaskImage.flagImageChanged();
	cvTempImage.flagImageChanged();
	
	cvMaskImage.setFromPixels( maskFile.getPixelsRef() );
}
Example #3
0
void VisionPipeLine::draw_markBlobs()
{
    // draw founded blobs
    for (int pos = 0; pos < _bloblist.size() && pos < MAX_TRACKED_BLOB_CNT; ++pos)
    {
        if (pos == _hoveredBlobID) {
            cvDrawRect(_rectified, cvPoint(_bloblist[pos]._box.x, _bloblist[pos]._box.y), 
            cvPoint(_bloblist[pos]._box.x+_bloblist[pos]._box.width, _bloblist[pos]._box.y+_bloblist[pos]._box.height), 
            cvScalar(0,0,255), 3);
        } else {
            cvDrawRect(_rectified, cvPoint(_bloblist[pos]._box.x, _bloblist[pos]._box.y), 
            cvPoint(_bloblist[pos]._box.x+_bloblist[pos]._box.width, _bloblist[pos]._box.y+_bloblist[pos]._box.height), 
            cvScalar(0,255,255));
        }

        

        cvDrawCircle(_rectified, cvPoint(_bloblist[pos]._center.x, _bloblist[pos]._center.y), 
            2, cvScalar(255,255,0));

        char msg[100];
        sprintf(msg, "%d: (%.2f, %.2f)", pos, _bloblist[pos]._center.x, _bloblist[pos]._center.y);
        cv_textOut(_rectified, _bloblist[pos]._box.x, _bloblist[pos]._box.y+_bloblist[pos]._box.height+10, msg);
    }

    // draw blob marks on the rectified projection plane
    cvFillImage(_projected, 0);

    char msg[100];

    for (int pos =0; pos<_trackpoints.size(); ++pos)
    {        
        CvPoint2D32f posInWindow = _layout_provider.keyboardPosToWindowPos(cvPoint2D32f(_trackpoints[pos].x, _trackpoints[pos].y));
        posInWindow.x *= (float)PROJECTED_WIDTH/_layout_provider.getLayoutSize().width ;
        posInWindow.y *= (float)PROJECTED_WIDTH/_layout_provider.getLayoutSize().width ;
        
        posInWindow.y += (PROJECTED_HEIGHT-_layout_provider.getLayoutSize().height)/2;
        cvDrawCircle(_projected, cvPoint(posInWindow.x, posInWindow.y), _trackpoints[pos].pressure, cvScalar(255,255,0));
        sprintf(msg, "%d:(%.2f,%.2f)", pos, posInWindow.x, posInWindow.y);
        cv_textOut(_projected, posInWindow.x,posInWindow.y+20, msg);
    }
}
void FuzzyChoquetIntegral::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
{
  if(img_input.empty())
    return;

  cv::Mat img_input_f3(img_input.size(), CV_32F);
  img_input.convertTo(img_input_f3, CV_32F, 1./255.);

  loadConfig();

  if(firstTime)
  {
    std::cout << "FuzzyChoquetIntegral parameters:" << std::endl;
      
    std::string colorSpaceName = "";
    switch(colorSpace)
    {
      case 1: colorSpaceName = "RGB";  break;
      case 2: colorSpaceName = "OHTA"; break;
      case 3: colorSpaceName = "HSV";  break;
      case 4: colorSpaceName = "YCrCb"; break;
    }
    std::cout << "Color space: " << colorSpaceName << std::endl;

    if(option == 1)
      std::cout << "Fuzzing by 3 color components" << std::endl;
    if(option == 2)
      std::cout << "Fuzzing by 2 color components + 1 texture component" << std::endl;
    
    saveConfig();
  }

  if(frameNumber <= framesToLearn)
  {
    if(frameNumber == 0)
      std::cout << "FuzzyChoquetIntegral initializing background model by adaptive learning..." << std::endl;

    if(img_background_f3.empty())
      img_input_f3.copyTo(img_background_f3);
    else
      img_background_f3 = alphaLearn*img_input_f3 + (1-alphaLearn)*img_background_f3;

    if(showOutput)
      cv::imshow("CI BG Model", img_background_f3);
  }
  else
  {
    cv::Mat img_input_f1;
    cv::cvtColor(img_input_f3, img_input_f1, CV_BGR2GRAY);

    cv::Mat img_background_f1;
    cv::cvtColor(img_background_f3, img_background_f1, CV_BGR2GRAY);

    IplImage* input_f3 = new IplImage(img_input_f3);
    IplImage* input_f1 = new IplImage(img_input_f1);
    IplImage* background_f3 = new IplImage(img_background_f3);
    IplImage* background_f1 = new IplImage(img_background_f1);

    IplImage* lbp_input_f1 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 1);
    cvFillImage(lbp_input_f1, 0.0);
    fu.LBP(input_f1, lbp_input_f1);

    IplImage* lbp_background_f1 = cvCreateImage(cvSize(background_f1->width, background_f1->height), IPL_DEPTH_32F , 1);
    cvFillImage(lbp_background_f1, 0.0);
    fu.LBP(background_f1, lbp_background_f1);

    IplImage* sim_texture_f1 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 1);
    fu.SimilarityDegreesImage(lbp_input_f1, lbp_background_f1, sim_texture_f1, 1, colorSpace);

    IplImage* sim_color_f3 = cvCreateImage(cvSize(input_f3->width, input_f3->height), IPL_DEPTH_32F, 3);
    fu.SimilarityDegreesImage(input_f3, background_f3, sim_color_f3, 3, colorSpace);	

    float* measureG = (float*) malloc(3*(sizeof(float)));
    IplImage* integral_choquet_f1 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 1);

    // 3 color components
    if(option == 1)
    {
      fu.FuzzyMeasureG(0.4f, 0.3f, 0.3f, measureG);
      fu.getFuzzyIntegralChoquet(sim_texture_f1, sim_color_f3, option, measureG, integral_choquet_f1);
    }

    // 2 color components + 1 texture component
    if(option == 2)
    {
      fu.FuzzyMeasureG(0.6f, 0.3f, 0.1f, measureG);
      fu.getFuzzyIntegralChoquet(sim_texture_f1, sim_color_f3, option, measureG, integral_choquet_f1);
    }

    free(measureG);
    cv::Mat img_integral_choquet_f1(integral_choquet_f1);

    if(smooth)
      cv::medianBlur(img_integral_choquet_f1, img_integral_choquet_f1, 3);

    cv::Mat img_foreground_f1(img_input.size(), CV_32F);
    cv::threshold(img_integral_choquet_f1, img_foreground_f1, threshold, 255, cv::THRESH_BINARY_INV);

    cv::Mat img_foreground_u1(img_input.size(), CV_8U);
    double minVal = 0., maxVal = 1.;
    img_foreground_f1.convertTo(img_foreground_u1, CV_8U, 255.0/(maxVal - minVal), -minVal);
    img_foreground_u1.copyTo(img_output);

    cv::Mat img_background_u3(img_input.size(), CV_8U);
    //double minVal = 0., maxVal = 1.;
    img_background_f3.convertTo(img_background_u3, CV_8U, 255.0/(maxVal - minVal), -minVal);
    img_background_u3.copyTo(img_bgmodel);

    if(showOutput)
    {
      cvShowImage("CI LBP Input", lbp_input_f1);
      cvShowImage("CI LBP Background", lbp_background_f1);
      cvShowImage("CI Prob FG Mask", integral_choquet_f1);

      cv::imshow("CI BG Model", img_background_f3);
      cv::imshow("CI FG Mask", img_foreground_u1);
    }

    if(frameNumber == (framesToLearn + 1))
      std::cout << "FuzzyChoquetIntegral updating background model by adaptive-selective learning..." << std::endl;

    IplImage* updated_background_f3 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 3);
    cvFillImage(updated_background_f3, 0.0);
    fu.AdaptativeSelectiveBackgroundModelUpdate(input_f3, background_f3, updated_background_f3, integral_choquet_f1, threshold, alphaUpdate);
    cv::Mat img_updated_background_f3(updated_background_f3);
    img_updated_background_f3.copyTo(img_background_f3);

    cvReleaseImage(&lbp_input_f1);
    cvReleaseImage(&lbp_background_f1);
    cvReleaseImage(&sim_texture_f1);
    cvReleaseImage(&sim_color_f3);
    cvReleaseImage(&integral_choquet_f1);
    cvReleaseImage(&updated_background_f3);
    
    delete background_f1;
    delete background_f3;
    delete input_f1;
    delete input_f3;
  }

  firstTime = false;
  frameNumber++;
}
void PerformanceUtils::ImageROC(IplImage *image, IplImage* ground_truth, bool saveResults, char* filename)
{
  unsigned char *pixelGT = (unsigned char*) malloc(1*sizeof(unsigned char));
  unsigned char *pixelI = (unsigned char*) malloc(1*sizeof(unsigned char));

  IplImage *ROCimage = cvCreateImage(cvSize(image->width,image->height),image->depth,image->nChannels);
  cvFillImage(ROCimage, 0.0);

  PixelUtils p;

  for(int y = 0; y < image->height; y++) 
  {
    for(int x = 0; x < image->width; x++) 
    {
      p.GetGrayPixel(ground_truth,x,y,pixelGT);                
      p.GetGrayPixel(image,x,y,pixelI);

      if((pixelGT[0] != 0) && (pixelI[0] != 0)) // TP
      {
        *pixelI = 30;
        p.PutGrayPixel(ROCimage,x,y,*pixelI);
      }

      if((pixelGT[0] == 0) && (pixelI[0] == 0.0)) // TN
      {
        *pixelI = 0;
        p.PutGrayPixel(ROCimage,x,y,*pixelI);
      }	

      if((pixelGT[0] == 0) && (pixelI[0] != 0)) // FP
      {
        *pixelI = 255;
        p.PutGrayPixel(ROCimage,x,y,*pixelI);
      }

      if((pixelGT[0] != 0) && (pixelI[0] == 0)) // FN
      {
        *pixelI = 100;
        p.PutGrayPixel(ROCimage,x,y,*pixelI);
      }
    }
  }

  cvNamedWindow("ROC image", 0);
  cvShowImage("ROC image", ROCimage);

  if(saveResults)
  {
    unsigned char *pixelOI = (unsigned char*) malloc(1*sizeof(unsigned char));
    unsigned char *pixelROC = (unsigned char*) malloc(1*sizeof(unsigned char));

    float** freq;
    float nTP = 0.0;
    float nTN = 0.0;
    float nFP = 0.0;
    float nFN = 0.0;

    freq = (float**) malloc(256*(sizeof(float*)));
    for(int i = 0; i < 256; i++)
      freq[i] = (float*) malloc(7 * (sizeof(float)));

    for(int i = 0; i < 256; i++)
      for(int j = 0; j < 6; j++) 
        freq[i][j] = 0.0;

    for(int y = 0; y < image->height; y++)
    {
      for(int x = 0; x < image->width; x++) 
      {
        for(int i = 0; i < 256; i++)
        {
          p.GetGrayPixel(image,x,y,pixelOI);                
          p.GetGrayPixel(ROCimage,x,y,pixelROC);

          if((pixelOI[0] == i) && (pixelROC[0] == 30.0)) // TP
          {
            nTP++;
            freq[i][0] = nTP;
            break;
          }

          if((pixelOI[0] == i) && (pixelROC[0] == 0.0)) // TN
          {
            nTN++;
            freq[i][1] = nTN;
            break;
          }

          if((pixelOI[0] == i) && (pixelROC[0] == 255.0)) // FP
          {
            nFP++;
            freq[i][2] = nFP;
            break;
          }

          if((pixelOI[0] == i) && (pixelROC[0] == 100)) // FN
          {
            nFN++;
            freq[i][3] = nFN;
            break;
          }
        }
      }
    }

    //freq[i][0] = TP
    //freq[i][1] = TN
    //freq[i][2] = FP
    //freq[i][3] = FN
    //freq[i][4] = FNR
    //freq[i][5] = FPR

    std::ofstream f(filename);

    if(!f.is_open())
      std::cout << "Failed to open file " << filename << " for writing!" << std::endl;
    else
    {
      f << "  I     TP     TN     FP     FN    FPR      FNR      DR   \n" << std::endl;
      
      for(int i = 0; i < 256; i++)
      {
        //printf("%4d - TP:%5.0f, TN:%5.0f, FP:%5.0f, FN:%5.0f,", i, freq[i][0], freq[i][1], freq[i][2], freq[i][3]);

        if((freq[i][3] + freq[i][0] != 0.0) && (freq[i][2] + freq[i][1] != 0.0))
        {
          freq[i][4] = freq[i][3] / (freq[i][3] + freq[i][0]);  // FNR = FN / (TP + FN);
          freq[i][5] = freq[i][2] / (freq[i][2] + freq[i][1]);	// FPR = FP / (FP + TN);
          freq[i][6] = freq[i][0] / (freq[i][0] + freq[i][3]);	// DR = TP / (TP+FN);

          //printf(" FPR:%1.5f, FNR:%1.5f, D:%1.5f\n", freq[i][5], freq[i][4], freq[i][6]);
          ////fprintf(f," %4d     %1.6f     %1.6f\n",i,freq[i][5],freq[i][4]);
          ////fprintf(f,"  %1.6f     %1.6f\n",freq[i][5],freq[i][4]);
          char line[255];
          sprintf(line,"%3d %6.0f %6.0f %6.0f %6.0f %1.6f %1.6f %1.6f\n", 
            i, freq[i][0], freq[i][1], freq[i][2], freq[i][3], freq[i][5], freq[i][4], freq[i][6]);
          f << line;
        }
        //else
          //printf("\n");
      }

      std::cout << "Results saved in " << filename << std::endl;
      f.close();
    }

    free(freq);
    free(pixelOI);
    free(pixelROC);
  }

  //std::cout << "press ENTER to continue" << std::endl;
  //cvWaitKey(0);
  cvReleaseImage(&ROCimage);

  free(pixelGT);
  free(pixelI);
}
void ofxCvMaskImageGui::clearMask() {
	cvFillImage( cvMaskImage.getCvImage(), 0.0 );
}
Example #7
0
// Заполнение src->edgeA, src->edgeB src->inCont src->centLine
int correctContour(frGeomStrip* src){
	if(!src->isStrip()){
		return -1;
	}

	src->minX = src->maxX = src->minY = src->maxY = -1;

	// до начала имнимум-максимум - первая точка
	src->minX = src->maxX = ((CvPoint*) cvGetSeqElem(src->stripCont, 0))->x;
	src->minY = src->maxY = ((CvPoint*) cvGetSeqElem(src->stripCont, 0))->y;

	// ищем координаты прямоугольника, описывающего контур
	for( int i=0; i<src->stripCont->total; ++i ) {
		CvPoint* t = (CvPoint*)cvGetSeqElem ( src->stripCont, i );
		src->minX = (t->x < src->minX) ? t->x : src->minX;
		src->maxX = (t->x > src->maxX) ? t->x : src->maxX;
		src->minY = (t->y < src->minY) ? t->y : src->minY;
		src->maxY = (t->y > src->maxY) ? t->y : src->maxY;
	}

	// creating black image with contour highlited with white pixels
	// вспомогательное изображение для отрисовки и "прострела" контура
	IplImage* auxiliaryImage = cvCreateImage( cvSize(src->stripFrame->width, src->stripFrame->height), IPL_DEPTH_8U, 1);
	cvFillImage(auxiliaryImage, 0.0);

	CvRect myROI = src->getROI();

	/*
	if( myROI.x > 0)
		printf("*");
		*/
	// изображение для визуализации работы с гранями
	IplImage* visualImage = cvCreateImage( cvSize(myROI.width , myROI.height), IPL_DEPTH_8U, 3);
	cvFillImage(visualImage, -10.0);

	//сохранили оригинальное РОИ
	CvRect origROI = cvGetImageROI(src->stripFrame );

	// назначаем новое РОИ, чтобы скопировалась только нужная область в картинку visualImage
	cvSetImageROI(src->stripFrame, myROI);
	//	cvCopy(src->stripFrame, visualImage, 0);
	
	//cvShowImage("visual", visualImage);

	// восстановили оригинаьное РОИ
	cvSetImageROI(src->stripFrame, origROI);

	cvDrawContours(auxiliaryImage, src->stripCont, CVX_WHITE, CVX_WHITE, 0, 1);
	
	
	vector<CvPoint> APoints, BPoints, middlePoints; // левые и правые (иногда верхние и нижние) точки границы. заполняются сверху-вниз полосы

	int start = (vertical) ? src->minY + (src->maxY - src->minY) * ((float)HEAD_TAIL_PERCENT/100) : 
							 src->minX + (src->maxX - src->minX) * ((float)HEAD_TAIL_PERCENT/100) ;
	int finish =(vertical) ? src->minY + (src->maxY - src->minY) * (1 - (float)HEAD_TAIL_PERCENT/100) :
							 src->minX + (src->maxX - src->minX) * (1 - (float)HEAD_TAIL_PERCENT/100) ;
	int begin = (vertical) ? src->minX - 1 : src->minY - 1;
	int end	=	(vertical) ? src->maxX + 1 : src->maxY + 1;

	for( int i = start; i < finish; i++){		// Обходим сверху вниз (л-п)	

		for( int j = begin; j < end; j++){		// "стреляем" слева (сверху) до первого не чёрного пикселя
			uchar pix =  (vertical) ? px(auxiliaryImage, j /*- myROI.x*/, i /*- myROI.y*/) : px(auxiliaryImage, i /*- myROI.x*/, j /*- myROI.y*/);
			if( 0 != pix ){	// Первая не чёрная точка в этой строке пикселов
				CvPoint t;
				t.x = (vertical) ? j : i;
				t.y = (vertical) ? i : j;
				APoints.push_back( t );
				break;
			}// if 
		}// for j
		
		for( int j = end; j > begin; j--){ // "стреляем" справа (снизу) до первого не чёрного пикселя
			uchar pix =  (vertical) ? px(auxiliaryImage, j /*- myROI.x*/, i /*- myROI.y*/) : px(auxiliaryImage, i /*- myROI.x*/, j /*- myROI.y*/);
			if( 0 != pix ){	// Первая не чёрная точка в этой строке пикселов
				CvPoint t;
				t.x = (vertical) ? j : i;
				t.y = (vertical) ? i : j;
				BPoints.push_back( t );
				break;
			}// if 
		}// for j
		
		CvPoint t;
		t.x = (vertical) ? (APoints.back().x + BPoints.back().x) / 2 : i;
		t.y = (vertical) ? i : (APoints.back().y + BPoints.back().y) / 2;

		middlePoints.push_back(t);

	}// for i


	vector<CvPoint>::iterator itr;

	itr = APoints.begin();
	while(itr != APoints.end()){
		src->edgeA.push_back(*itr);	
		++itr;
	}

	itr = BPoints.begin();
	while(itr != BPoints.end()){
		src->edgeB.push_back(*itr);
		++itr;
	}

	itr = middlePoints.begin();
	while(itr != middlePoints.end()){
		 src->centLine.push_back(*itr);
		++itr;
	}

	// smooth contours edgeA and edgeB
	smoothContour( src );
	
	src->chordA = chorda(src->edgeA, src->posChordA);
	src->chordB = -chorda(src->edgeB, src->posChordB);

	
	// вывод результата (две грани и центральная линия) на картинку visualImage
		
	// рисуем  левую, правую и среднюю линии

	//printf("S: %d\t", curFrStrip.isStrip() ? 1 : 0);
		if(src->edgeA.size() > 5){
			
			vector<CvPoint>::iterator itr2 = src->edgeA.begin();
			while(itr2 != src->edgeA.end()){
				cvLine( visualImage, cvPoint(itr2->x - myROI.x, itr2->y - myROI.y), cvPoint(itr2->x - myROI.x, itr2->y - myROI.y), CV_RGB(0,0,0));
				++itr2;
			}
			
			vector<CvPoint>::iterator itr3 = src->edgeB.begin();
			while(itr3 != src->edgeB.end()){
				cvLine( visualImage, cvPoint(itr3->x - myROI.x, itr3->y - myROI.y), cvPoint(itr3->x - myROI.x, itr3->y - myROI.y), CV_RGB(0,0,0));
				++itr3;
			}
			
			vector<CvPoint>::iterator itr4 = src->centLine.begin();
			while(itr4 != src->centLine.end()){
				cvLine( visualImage, cvPoint(itr4->x - myROI.x, itr4->y - myROI.y), cvPoint(itr4->x - myROI.x, itr4->y - myROI.y), CV_RGB(0,255,0), 2);
				++itr4;
			}


		}

		FILE* fi;
	#ifdef __UNDIST_PROC__
		if ( src->undistAv == false ) {
	#endif
	#ifdef __DIST_PROC__
		 fi = fopen("chords.txt", "a+");
	#endif
	#ifdef __UNDIST_PROC__
		} else { 
			fi = fopen("undchords.txt", "a+");
		}
	#endif

		CvPoint A1, A2, B1, B2, Ah, Bh; 

		int p1 = (src->edgeA.size()*O_o > H_T_PIX) ? src->edgeA.size()*O_o : H_T_PIX;
		int p2 = (src->edgeA.size()*(1-O_o) < (src->edgeA.size() - H_T_PIX)) ? src->edgeA.size()*(1-O_o) : (src->edgeA.size() - H_T_PIX);

			A1 = cvPoint(src->edgeA[p1].x, src->edgeA[p1].y);
			A2 = cvPoint(src->edgeA[p2].x, src->edgeA[p2].y); 
			B1 = cvPoint(src->edgeB[p1].x, src->edgeB[p1].y);
			B2 = cvPoint(src->edgeB[p2].x, src->edgeB[p2].y);
		
		


		// Рисование хорд

		cvLine(visualImage, cvPoint(A1.x - myROI.x, A1.y - myROI.y) , cvPoint(A2.x - myROI.x, A2.y - myROI.y) , CV_RGB(255,0,0));
			cvLine(visualImage, cvPoint(A1.x - myROI.x, A1.y - myROI.y-3) , cvPoint(A1.x - myROI.x, A1.y - myROI.y+3) , CV_RGB(255,0,0));
			cvLine(visualImage, cvPoint(A2.x - myROI.x, A2.y - myROI.y-3) , cvPoint(A2.x - myROI.x, A2.y - myROI.y+3) , CV_RGB(255,0,0));
		
		cvLine(visualImage, cvPoint(B1.x - myROI.x, B1.y - myROI.y) , cvPoint(B2.x - myROI.x, B2.y - myROI.y) , CV_RGB(255,0,0));
			cvLine(visualImage, cvPoint(B1.x - myROI.x, B1.y - myROI.y-3) , cvPoint(B1.x - myROI.x, B1.y - myROI.y+3) , CV_RGB(255,0,0));
			cvLine(visualImage, cvPoint(B2.x - myROI.x, B2.y - myROI.y-3) , cvPoint(B2.x - myROI.x, B2.y - myROI.y+3) , CV_RGB(255,0,0));
			/*
		cvCircle(visualImage, cvPoint(src->posChordA.x - myROI.x, src->posChordA.y - myROI.y), 2, CV_RGB(255,0,0), 1);
		cvCircle(visualImage, cvPoint(src->posChordB.x - myROI.x, src->posChordB.y - myROI.y), 2, CV_RGB(255,0,0), 1);
		*/
		Ah = heightBase(A1, A2, src->posChordA);
		Bh = heightBase(B1, B2, src->posChordB);
		//cvDrawLine
		cvLine(visualImage, cvPoint(Ah.x - myROI.x, Ah.y - myROI.y), cvPoint(src->posChordA.x - myROI.x, src->posChordA.y - myROI.y), CV_RGB(0,0,0) );
		cvLine(visualImage, cvPoint(Bh.x - myROI.x, Bh.y - myROI.y), cvPoint(src->posChordB.x - myROI.x, src->posChordB.y - myROI.y), CV_RGB(0,0,0) );

		src->head_tail = findHeadTail(src);
		printf( "HT:\t%d\n", src->head_tail );

	//################################# AG code####################
    //chords in mm
		src->chordAmm = chordmm(src->edgeA, src->posChordA, src->cAnch);
		src->chordBmm = -chordmm(src->edgeB, src->posChordB, src->cAnch);
		printf("in mm:\tchords\t%3.2f\t%3.2f\tavg:\t%4.3f\tlen:\t%d\n", src->chordAmm, src->chordBmm, (src->chordAmm + src->chordBmm)/2, /*abs*/(pi2mm(src->edgeA.back(), src->cAnch ).x - pi2mm( src->edgeA.front(), src->cAnch ).x)) ;
		fprintf(fi,"in mm:\tchords\t%3.2f\t%3.2f\tavg:\t%4.3f\tlen:\t%d\tHT:%d\n", src->chordAmm, src->chordBmm, (src->chordAmm + src->chordBmm)/2, abs(pi2mm(src->edgeA.back(), src->cAnch ).x - pi2mm( src->edgeA.front(), src->cAnch ).x), src->head_tail) ;
    //################################# noneAG code####################


	//################################# AG code####################
    //chords in mm
		src->chordAmm = chordmm(src->edgeA, src->posChordA, src->cAnch);
		src->chordBmm = -chordmm(src->edgeB, src->posChordB, src->cAnch);
		printf("in mm:\tchords\t%3.2f\t%3.2f\tavg:\t%4.3f\tlen:\t%d\n", src->chordAmm, src->chordBmm, (src->chordAmm + src->chordBmm)/2, abs(pi2mm(src->edgeA.back(), src->cAnch ).x - pi2mm( src->edgeA.front(), src->cAnch ).x)) ;
       fprintf(fi,"in mm:\tchords\t%3.2f\t%3.2f\tavg:\t%4.3f\tlen:\t%d\n", src->chordAmm, src->chordBmm, (src->chordAmm + src->chordBmm)/2, abs(pi2mm(src->edgeA.back(), src->cAnch ).x - pi2mm( src->edgeA.front(), src->cAnch ).x)) ;
    //################################# noneAG code####################


		//printf("chords %3.2f:%3.2f; avg: %4.3f; len: %d \n", src->chordA, src->chordB, (src->chordA + src->chordB)/2, abs(src->edgeA.back().x - src->edgeA.front().x) );

	#ifdef __DEBUG_CHORDS__
		fprintf(fi,"in pi:\tchords\t%3.2f\t%3.2f\tavg:\t%4.3f\tlen:\t%d\n", src->chordA, src->chordB, (src->chordA + src->chordB)/2, abs(src->edgeA.back().x - src->edgeA.front().x)) ; 
		printf("in pi:\tchords\t%3.2f\t%3.2f\tavg:\t%4.3f\tlen:\t%d\n", src->chordA, src->chordB, (src->chordA + src->chordB)/2, abs(src->edgeA.back().x - src->edgeA.front().x)) ; 
	#endif
		
		fclose(fi);
		//////////////////////////////////////

	#ifdef __UNDIST_PROC__
		if ( src->undistAv == false ) {
	#endif
	#ifdef __DIST_PROC__
			cvShowImage("visual", visualImage);
	//	cvShowImage("visual", auxiliaryImage);
	#endif
	#ifdef __UNDIST_PROC__
		} else { 
			cvShowImage("undVisual", visualImage);
		}
	#endif
			
	// removing binaryImage from memory
	cvReleaseImage(&auxiliaryImage);
	cvReleaseImage(&visualImage);

	return 0;
}