Example #1
2
void cvCLAdaptEqualize(const CvArr* srcarr, CvArr* dstarr,
                        unsigned int xdivs, unsigned int ydivs, unsigned int bins,
                        float limit, int range)
{
       
        double min_val, max_val;
        unsigned char min, max;
       
        int type;

       IplImage sstub, *src = cvGetImage(srcarr, &sstub);
       IplImage dstub, *dst = cvGetImage(dstarr, &dstub);

        if ((src == NULL) || (dst == NULL))
        CV_ERROR( CV_StsUnsupportedFormat, "NULL value passed as image to function" );
       
        CV_CALL( type = cvGetElemType( src ));
        if( type != CV_8UC1 )
                CV_ERROR( CV_StsUnsupportedFormat, "Only 8uC1 images are supported" );
        CV_CALL( type = cvGetElemType( src ));
        if( type != CV_8UC1 )
                CV_ERROR( CV_StsUnsupportedFormat, "Only 8uC1 images are supported" );
       
        //if( !CV_ARE_SIZES_EQ( src, dst ))     // Modified by Shervin Emami, 17Nov2010.
        if (src->width != dst->width || src->height != dst->height)
                CV_ERROR( CV_StsUnmatchedSizes, "src and dst images must be equal sizes" );
    
        if (((xdivs < 2) || (xdivs > 16)) || ((ydivs < 2) || (ydivs > 16)))
                CV_ERROR( CV_StsBadFlag, "xdivs and ydivs must in range (MIN=2 MAX = 16)" );

        if ((bins < 2) || (bins > 256))
                CV_ERROR( CV_StsBadFlag, "bins must in range (MIN=2 MAX = 256)" );

        // copy src to dst for in-place CLAHE.
     cvCopy(src, dst);
   

        // If the dimensions of the image are not a multiple of the xdivs and ydivs, then enlarge the image to be a correct size and then shrink the image.
        // Also make sure the image is aligned to 8 pixels width, so that OpenCV won't add extra padding to the image.
        // Added by Shervin Emami, 17Nov2010.
        int enlarged = 0;
        int origW = dst->width;
        int origH = dst->height;
        IplImage *tmpDst = 0;
        if ((dst->width & (8-1)) || (dst->height & (8-1)) || (dst->width % xdivs) || (dst->height % ydivs)) {
                int newW = ((dst->width + 8-1) & -8);   // Align to 8 pixels, so that widthStep hopefully equals width.
                newW = ((newW + xdivs-1) & -xdivs);             // Also align for CLAHE.
                int newH = ((dst->height + ydivs-1) & -ydivs);
                //std::cout << "w=" << dst->width << ", h=" << dst->height << ". new w = " << newW << ", h = " << newH << std::endl;
                IplImage *enlargedDst = cvCreateImage(cvSize(newW, newH), dst->depth, dst->nChannels);
                cvResize(dst, enlargedDst, CV_INTER_CUBIC);
                //cvReleaseImage(&dst);
                tmpDst = dst;
                dst = enlargedDst;      // Use the enlarged image instead of the original dst image.
                enlarged = 1;   // signal that we need to shrink later!
        }
        // Check if OpenCV adds padding bytes on each row. Added by Shervin Emami, 17Nov2010.
        if (dst->width != dst->widthStep)
                CV_ERROR( CV_StsBadFlag, "dst->widthStep should be the same as dst->width. The IplImage has padding, so use a larger image." );


        // check number of xdivs and ydivs is a multiple of image dimensions
        if (dst->width % xdivs)
                CV_ERROR( CV_StsBadFlag, "xdiv must be an integer multiple of image width " );
        if (dst->height % ydivs)
                CV_ERROR( CV_StsBadFlag, "ydiv must be an integer multiple of image height " );
               
        // get the min and max values of the image
       
        if (range == CV_CLAHE_RANGE_INPUT) {
                cvMinMaxLoc(dst, &min_val, &max_val);
                min = (unsigned char) min_val;
                max = (unsigned char) max_val;
        } else {
                min = 0;
                max = 255;
        }
        // call CLHAHE for in-place CLAHE
       
        //int rcode =
        CLAHE((kz_pixel_t*) (dst->imageData), (unsigned int) dst->width, (unsigned int)
        dst->height, (kz_pixel_t) min, (kz_pixel_t) max, (unsigned int) xdivs, (unsigned int) ydivs,
              (unsigned int) bins, (float) limit);

        //printf("RCODE %i\n", rcode);  

        // If the dst image was enlarged to fit the alignment, then shrink it back now.
        // Added by Shervin Emami, 17Nov2010.
 
        if (enlarged) {
                //std::cout << "w=" << dst->width << ", h=" << dst->height << ". orig w=" << origW << ", h=" << origH << std::endl;
                cvResize(dst, tmpDst, CV_INTER_CUBIC);  // Shrink the enlarged image back into the original dst image.
                cvReleaseImage(&dst);   // Free the enlarged image.
        }

}
Example #2
0
	TiXmlElement* FileFormatUtils::createXMLMatrix(const char* element_name, const CvMat *matrix) {
		if (!matrix) return NULL;

		TiXmlElement* xml_matrix = new TiXmlElement(element_name);
		int precision;
		if (cvGetElemType(matrix) == CV_32F) {
			xml_matrix->SetAttribute("type", "CV_32F");
			precision = std::numeric_limits<float>::digits10 + 2;
		}
		else if (cvGetElemType(matrix) == CV_64F) {
			xml_matrix->SetAttribute("type", "CV_64F");
			precision = std::numeric_limits<double>::digits10 + 2;
		}
		else {
			delete xml_matrix;
			return NULL;
		}

		xml_matrix->SetAttribute("rows", matrix->rows);
		xml_matrix->SetAttribute("cols", matrix->cols);

		for (int r = 0; r < matrix->rows; ++r) {
			for (int c = 0; c < matrix->cols; ++c) {
				TiXmlElement *xml_data = new TiXmlElement("data");
				xml_matrix->LinkEndChild(xml_data);
				std::stringstream ss;
				ss.precision(precision);
				ss<<cvGetReal2D(matrix, r, c);
				xml_data->LinkEndChild(new TiXmlText(ss.str().c_str()));
			}
		}
		return xml_matrix;
	}
Example #3
0
CVAPI(void) cvShowImageEx(const char * id, const CvArr * arr,
                          const int cm)
{
  CvMat * src, src_stub;
  double minval, maxval, maxdiff; CvPoint minloc, maxloc;
  int type = cvGetElemType(arr);
  CvMat * disp, * src_scaled;
  int i, j;
  
  if (!CV_IS_MAT(arr))
    src = cvGetMat(arr, &src_stub);
  else{
    src = (CvMat*)arr;
  }

  src = cvCloneMat(src);
  if ( (src->rows<60) || (src->rows<60) )
  {
    CvMat * orig = cvCloneMat(src);
    int scale=60./MIN(orig->rows, orig->cols);
    cvReleaseMat(&src);
    src = cvCreateMat(orig->rows*scale, orig->cols*scale,
                      CV_MAT_TYPE(orig->type));
    int m,n;
    if (CV_MAT_TYPE(src->type)==CV_64F){
      for (m=0;m<orig->rows;m++) {
      for (n=0;n<orig->cols;n++) {
      for (i=0;i<scale;i++) {
      for (j=0;j<scale;j++) {
        CV_MAT_ELEM(*src, double, m*scale+i, n*scale+j) = CV_MAT_ELEM(*orig, double, m, n);
      }
      }
      }
      }
    }else if (CV_MAT_TYPE(src->type)==CV_32F){
Example #4
0
/*
 * call-seq:
 *   sub(val[,mask])
 *
 * Return new CvScalar if <i>val</i> is CvScalar or compatible object.
 *   self[I] - val[I]
 * Or return new CvMat if <i>val</i> is CvMat or subclass.
 */
VALUE
rb_sub(int argc, VALUE *argv, VALUE self)
{
  VALUE val, mask;
  rb_scan_args(argc, argv, "11", &val, &mask);
  if (rb_obj_is_kind_of(val, cCvMat::rb_class())) {
    CvArr *val_ptr = CVARR(val);
    VALUE dest = Qnil;
    try {
      dest = cCvMat::new_object(cvGetSize(val_ptr), cvGetElemType(val_ptr));
      cvSubRS(val_ptr, *CVSCALAR(self), CVARR(dest), MASK(mask));
    }
    catch (cv::Exception& e) {
      raise_cverror(e);
    }
    return dest;
  }
  else {
    CvScalar *src = CVSCALAR(self);
    CvScalar scl = VALUE_TO_CVSCALAR(val);
    return new_object(cvScalar(src->val[0] - scl.val[0],
                               src->val[1] - scl.val[1],
                               src->val[2] - scl.val[2],
                               src->val[3] - scl.val[3]));
  }
}
Example #5
0
void  cvPolyLineAA( CvArr* img, CvPoint** pts, int* npts, int contours,
                    int is_closed, double color, int scale )
{
    cvPolyLine( img, pts, npts, contours, is_closed,
                cvColorToScalar(color, cvGetElemType(img)),
                1, CV_AA, scale );
}
Example #6
0
// Rearrange the quadrants of Fourier image so that the origin is at
// the image center
// src & dst arrays of equal size & type
void
cvShiftDFT(CvArr *src_arr, CvArr *dst_arr )
{
  CvMat *tmp = NULL;
  CvMat q1stub, q2stub;
  CvMat q3stub, q4stub;
  CvMat d1stub, d2stub;
  CvMat d3stub, d4stub;
  CvMat *q1, *q2, *q3, *q4;
  CvMat *d1, *d2, *d3, *d4;

  CvSize size = cvGetSize(src_arr);
  CvSize dst_size = cvGetSize(dst_arr);
  int cx, cy;

  if(dst_size.width != size.width ||
     dst_size.height != size.height){
    cvError( CV_StsUnmatchedSizes, "cvShiftDFT", "Source and Destination arrays must have equal sizes", __FILE__, __LINE__ );
  }

  if(src_arr==dst_arr){
    tmp = rb_cvCreateMat(size.height/2, size.width/2, cvGetElemType(src_arr));
  }

  cx = size.width/2;
  cy = size.height/2; // image center

  q1 = cvGetSubRect( src_arr, &q1stub, cvRect(0,0,cx, cy) );
  q2 = cvGetSubRect( src_arr, &q2stub, cvRect(cx,0,cx,cy) );
  q3 = cvGetSubRect( src_arr, &q3stub, cvRect(cx,cy,cx,cy) );
  q4 = cvGetSubRect( src_arr, &q4stub, cvRect(0,cy,cx,cy) );
  d1 = cvGetSubRect( src_arr, &d1stub, cvRect(0,0,cx,cy) );
  d2 = cvGetSubRect( src_arr, &d2stub, cvRect(cx,0,cx,cy) );
  d3 = cvGetSubRect( src_arr, &d3stub, cvRect(cx,cy,cx,cy) );
  d4 = cvGetSubRect( src_arr, &d4stub, cvRect(0,cy,cx,cy) );

  if(src_arr!=dst_arr){
    if( !CV_ARE_TYPES_EQ( q1, d1 )){
      cvError( CV_StsUnmatchedFormats, "cvShiftDFT", "Source and Destination arrays must have the same format", __FILE__, __LINE__ );
    }
    cvCopy(q3, d1, 0);
    cvCopy(q4, d2, 0);
    cvCopy(q1, d3, 0);
    cvCopy(q2, d4, 0);
  }
  else{
    cvCopy(q3, tmp, 0);
    cvCopy(q1, q3, 0);
    cvCopy(tmp, q1, 0);
    cvCopy(q4, tmp, 0);
    cvCopy(q2, q4, 0);
    cvCopy(tmp, q2, 0);
  }

  if (tmp != NULL)
  {
	cvReleaseMat(&tmp);
  }
}
Example #7
0
void  cvEllipseAA( CvArr* img, CvPoint center, CvSize axes,
                   double angle, double start_angle,
                   double end_angle, double color,
                   int scale)
{
    cvEllipse( img, center, axes, angle, start_angle, end_angle,
               cvColorToScalar(color, cvGetElemType(img)), 1, CV_AA, scale );
}
Example #8
0
void test(CvMat* t)
{
	//获取矩阵的数据类型
	int type = cvGetElemType(t);
	CvHistogram
	//获取矩阵的维度信息
	int size[10];
	int dims = cvGetDims(t, size);
	int x = cvGetDimSize(t, 0);
	int y = cvGetDimSize(t, 1);
}
Example #9
0
double CxCore_MulSpectrumsTest::get_success_error_level( int test_case_idx, int i, int j )
{
    CV_UNUSED(test_case_idx);
    CV_Assert(i == OUTPUT);
    CV_Assert(j == 0);
    int elem_depth = CV_MAT_DEPTH(cvGetElemType(test_array[i][j]));
    CV_Assert(elem_depth == CV_32F || elem_depth == CV_64F);

    element_wise_relative_error = false;
    double maxInputValue = 1000; // ArrayTest::get_minmax_bounds
    double err = 8 * maxInputValue;  // result = A*B + C*D
    return (elem_depth == CV_32F ? FLT_EPSILON : DBL_EPSILON) * err;
}
Example #10
0
void CvArrTest::fill_array( int /*test_case_idx*/, int i, int j, CvMat* arr )
{
    if( i == REF_INPUT_OUTPUT )
        cvTsCopy( &test_mat[INPUT_OUTPUT][j], arr, 0 );
    else if( i == INPUT || i == INPUT_OUTPUT || i == MASK )
    {
        int type = cvGetElemType( arr );
        CvScalar low, high;

        get_minmax_bounds( i, j, type, &low, &high );
        cvTsRandUni( ts->get_rng(), arr, low, high );
    }
}
Example #11
0
/*
 * call-seq:
 *   sub(val[,mask])
 *
 * Return new CvScalar if <i>val</i> is CvScalar or compatible object.
 *   self[I] - val[I]
 * Or return new CvMat if <i>val</i> is CvMat or subclass.
 */
VALUE
rb_sub(int argc, VALUE *argv, VALUE self)
{
  VALUE val, mask;
  rb_scan_args(argc, argv, "11", &val, &mask);
  if(rb_obj_is_kind_of(val, cCvMat::rb_class())){
    VALUE dest = cCvMat::new_object(cvGetSize(CVARR(val)), cvGetElemType(CVARR(val)));
    cvSubRS(CVARR(val), *CVSCALAR(self), CVARR(dest), MASK(mask));
    return dest;
  }else{
    CvScalar *src = CVSCALAR(self), scl = VALUE_TO_CVSCALAR(val);
    return new_object(cvScalar(src->val[0] - scl.val[0],
                               src->val[1] - scl.val[1],
                               src->val[2] - scl.val[2],
                               src->val[3] - scl.val[3]));
  }
}
Example #12
0
////////////////////////compute the meshgrid arrays needed for LPF//////////////////////////////////////////////////
// CDM compute meshgrid frequency matrices (ok!)
// see Gonzalez Digital image processing using matlab page93 function dftuv
void CLightSet::CDM(int M,int N,CvMat *mat)
{
	int width = mat->rows;
	int height = mat->cols;

	if (M != width && N != height)
	{
		//cout<<"ERROR! THE SIZE DOES NOT MATCH WITH MAT"<<endl;
		return;
	}

	if (cvGetElemType(mat) < CV_32F)
	{
		//cout<<"ERROR! THE TYPE DOES NOT MATCH WITH MAT"<<endl;
		return;
	}

	CvMat *U,*V;
	U = cvCreateMat(M,N,CV_32FC1);
	V = cvCreateMat(M,N,CV_32FC1);

	for (int u = 0; u < M; ++u)
		for (int v =0 ;v < N; ++v)
		{
			float tm1,tm2;
			tm1 = (float)((u > cvRound(M/2))?u-M:u);
			tm2 = (float)((v > cvRound(N/2))?v-N:v);

			*( (float *)CV_MAT_ELEM_PTR(*U,u,v) ) = tm1;

			*( (float *)CV_MAT_ELEM_PTR(*V,u,v) ) = tm2;
		}

		for ( int u = 0; u < M; ++u)
			for (int v =0 ;v < N; ++v)
			{
				float t1,t2;
				t1 = CV_MAT_ELEM(*U,float,u,v);
				t2 = CV_MAT_ELEM(*V,float,u,v);
				*( (float *)CV_MAT_ELEM_PTR(*mat,u,v) ) = sqrt(t1*t1 + t2*t2);

			}

}
Example #13
0
static bool check_size_type(const CvMat* src, const char* name)
{
    if(src->rows != src->cols)
    {
        fprintf(stderr, "MT_Cholesky Error:  %s must be a square matrix.\n",
                name);
        return false;
    }

    if(cvGetElemType(src) != CV_64FC1)
    {
        fprintf(stderr,
                "MT_Cholesky Error:  %s must be a single-channel "
                "matrix of doubles.\n",
                name);
        return false;
    }

    return true;
}
Example #14
0
void MT_CVQuadraticMul(const CvMat* X,
                       const CvMat* W,
                       CvMat* dst,
                       bool transpose_X,
                       CvMat* tmp_prod)
{
    bool own_prod = (tmp_prod == NULL);

    if(own_prod)
    {
        tmp_prod = cvCreateMat(W->rows, X->cols, cvGetElemType(X));
    }

    cvGEMM(W, X, 1.0, NULL, 1.0, tmp_prod, transpose_X ? CV_GEMM_B_T : 0);
    cvGEMM(X, tmp_prod, 1.0, NULL, 1.0, dst, transpose_X ? 0 : CV_GEMM_A_T);

    if(own_prod)
    {
        cvReleaseMat(&tmp_prod);
    }
}
Example #15
0
	bool FileFormatUtils::parseXMLMatrix(const TiXmlElement *xml_matrix, CvMat *matrix) {
		if (!xml_matrix || !matrix) return false;

		int type, rows, cols;
		if (!decodeXMLMatrix(xml_matrix, type, rows, cols)) return false;

		if (type != cvGetElemType(matrix)) return false;
		if (rows != matrix->rows) return false;
		if (cols != matrix->cols) return false;

		const TiXmlElement *xml_data = xml_matrix->FirstChildElement("data");
		for (int r = 0; r < matrix->rows; ++r) {
			for (int c = 0; c < matrix->cols; ++c) {
				if (!xml_data) return false;
				double value = atof(xml_data->GetText());
				cvSetReal2D(matrix, r, c, value);
				xml_data = (const TiXmlElement *) xml_data->NextSibling("data");
			}
		}

		return true;
	}
Example #16
0
bool CvCalibFilter::FindEtalon( CvMat** mats )
{
    bool result = true;

    if( !mats || etalonPointCount == 0 )
    {
        assert(0);
        result = false;
    }

    if( result )
    {
        int i, tempPointCount0 = etalonPointCount*2;

        for( i = 0; i < cameraCount; i++ )
        {
            if( !latestPoints[i] )
                latestPoints[i] = (CvPoint2D32f*)
                    cvAlloc( tempPointCount0*2*sizeof(latestPoints[0]));
        }

        for( i = 0; i < cameraCount; i++ )
        {
            CvSize size;
            int tempPointCount = tempPointCount0;
            bool found = false;

            if( !CV_IS_MAT(mats[i]) && !CV_IS_IMAGE(mats[i]))
            {
                assert(0);
                break;
            }

            size = cvGetSize(mats[i]);

            if( size.width != imgSize.width || size.height != imgSize.height )
            {
                imgSize = size;
            }

            if( !grayImg || grayImg->width != imgSize.width ||
                grayImg->height != imgSize.height )
            {
                cvReleaseMat( &grayImg );
                cvReleaseMat( &tempImg );
                grayImg = cvCreateMat( imgSize.height, imgSize.width, CV_8UC1 );
                tempImg = cvCreateMat( imgSize.height, imgSize.width, CV_8UC1 );
            }

            if( !storage )
                storage = cvCreateMemStorage();

            switch( etalonType )
            {
            case CV_CALIB_ETALON_CHESSBOARD:
                if( CV_MAT_CN(cvGetElemType(mats[i])) == 1 )
                    cvCopy( mats[i], grayImg );
                else
                    cvCvtColor( mats[i], grayImg, CV_BGR2GRAY );
                found = cvFindChessBoardCornerGuesses( grayImg, tempImg, storage,
                                                       cvSize( cvRound(etalonParams[0]),
                                                       cvRound(etalonParams[1])),
                                                       latestPoints[i], &tempPointCount ) != 0;
                if( found )
                    cvFindCornerSubPix( grayImg, latestPoints[i], tempPointCount,
                                        cvSize(5,5), cvSize(-1,-1),
                                        cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,10,0.1));
                break;
            default:
                assert(0);
                result = false;
                break;
            }

            latestCounts[i] = found ? tempPointCount : -tempPointCount;
            result = result && found;
        }
    }

    if( storage )
        cvClearMemStorage( storage );

    return result;
}
Example #17
0
double ArrayTest::get_success_error_level( int /*test_case_idx*/, int i, int j )
{
    int elem_depth = CV_MAT_DEPTH(cvGetElemType(test_array[i][j]));
    assert( i == OUTPUT || i == INPUT_OUTPUT );
    return elem_depth < CV_32F ? 0 : elem_depth == CV_32F ? FLT_EPSILON*100: DBL_EPSILON*5000;
}
Example #18
0
/* old drawing functions */
void  cvLineAA( CvArr* img, CvPoint pt1, CvPoint pt2, double color, int scale)
{
    cvLine( img, pt1, pt2, cvColorToScalar(color, cvGetElemType(img)), 1, CV_AA, scale );
}
Example #19
0
void  cvCircleAA( CvArr* img, CvPoint center, int radius, double color, int scale)
{
    cvCircle( img, center, radius, cvColorToScalar(color, cvGetElemType(img)), 1, CV_AA, scale );
}
Example #20
0
/** 
 * Euclidean distance transform of a binary image,
 * Computation performed upon 'short' values
 * 
 * @param src       IN: positive pixels are treated as background
 * @param distxArr  OUT: 
 * @param distyArr  OUT: 
 */
void cvCalcEuclideanDistance(
    const CvArr * src,      // positive pixels are treated as background
    CvArr * distxArr, CvArr * distyArr)
{
  CV_FUNCNAME("cvEuclideanDistance");
  
  int x, y, i;
  int offset_u, offset_ur, offset_r, offset_rd,
      offset_d, offset_dl, offset_l, offset_lu;
  double olddist2, newdist2, newdistx, newdisty;
  int changed;

  __BEGIN__;
  // CV_ASSERT(cvGetElemType(src)==CV_16S);
  // CV_ASSERT(cvGetElemType(distxArr)==CV_16S);
  // CV_ASSERT(cvGetElemType(distyArr)==CV_16S);

  CvMat srcHeader, distHeaderX, distHeaderY;
  CvMat * srcImage = cvGetMat(src, &srcHeader);
  CvMat * distImageX = cvGetMat(distxArr, &distHeaderX);
  CvMat * distImageY = cvGetMat(distyArr, &distHeaderY);
  CvMat * srcImage2 =
      cvCreateMat(srcImage->rows, srcImage->cols, CV_16S);
  CvMat * distImageX2 =
      cvCreateMat(srcImage->rows, srcImage->cols, CV_16S);
  CvMat * distImageY2 =
      cvCreateMat(srcImage->rows, srcImage->cols, CV_16S);

  if (cvGetElemType(src)!=CV_16S) cvConvert(srcImage, srcImage2);
  else cvCopy(srcImage, srcImage2);

  CvMat distImageXheader, distImageYheader;
  CvMat * distImageXreshaped =
      cvReshape(distImageX2, &distImageXheader, 0, 1);
  CvMat * distImageYreshaped =
      cvReshape(distImageY2, &distImageYheader, 0, 1);
  
  int w = srcImage->cols;
  int h = srcImage->rows;
  short * distx = (short*)distImageXreshaped->data.ptr;
  short * disty = (short*)distImageYreshaped->data.ptr;

  // Initialize index offsets for the current image width
  offset_u = -w;
  offset_ur = -w+1;
  offset_r = 1;
  offset_rd = w+1;
  offset_d = w;
  offset_dl = w-1;
  offset_l = -1;
  offset_lu = -w-1;

  /* Initialize the distance images to be all large values */
  for(i=0; i<w*h; i++)
    // if(img(i) <= 0.0)
    if(CV_MAT_ELEM(*srcImage2, short, i/w, i%w) <= 0.0)
    {
      distx[i] = 32000; // Large but still representable in a short, and
      disty[i] = 32000; // 32000^2 + 32000^2 does not overflow an int
    }
    else
    {
Example #21
0
void cvFillImage( CvArr* mat, double color )
{
    cvSet( mat, cvColorToScalar(color, cvGetElemType(mat)), 0 );
}
Example #22
0
int CvArrTest::validate_test_results( int test_case_idx )
{
    static const char* arr_names[] = { "input", "input/output", "output",
                                       "ref input/output", "ref output",
                                       "temporary", "mask" };
    int i, j;
    prepare_to_validation( test_case_idx );

    for( i = 0; i < 2; i++ )
    {
        int i0 = i == 0 ? OUTPUT : INPUT_OUTPUT;
        int i1 = i == 0 ? REF_OUTPUT : REF_INPUT_OUTPUT;
        int count = test_array[i0].size();

        assert( count == test_array[i1].size() );
        for( j = 0; j < count; j++ )
        {
            double err_level;
            CvPoint idx = {0,0};
            double max_diff = 0;
            int code;
            char msg[100];

            if( !test_array[i1][j] )
                continue;

            err_level = get_success_error_level( test_case_idx, i0, j );
            code = cvTsCmpEps( &test_mat[i0][j], &test_mat[i1][j], &max_diff, err_level, &idx,
                               element_wise_relative_error );

            switch( code )
            {
            case -1:
                sprintf( msg, "Too big difference (=%g)", max_diff );
                code = CvTS::FAIL_BAD_ACCURACY;
                break;
            case -2:
                strcpy( msg, "Invalid output" );
                code = CvTS::FAIL_INVALID_OUTPUT;
                break;
            case -3:
                strcpy( msg, "Invalid output in the reference array" );
                code = CvTS::FAIL_INVALID_OUTPUT;
                break;
            default:
                continue;
            }
            ts->printf( CvTS::LOG, "%s in %s array %d at (%d,%d)\n", msg,
                        arr_names[i0], j, idx.x, idx.y );
            for( i0 = 0; i0 < max_arr; i0++ )
            {
                int count = test_array[i0].size();
                if( i0 == REF_INPUT_OUTPUT || i0 == OUTPUT || i0 == TEMP )
                    continue;
                for( i1 = 0; i1 < count; i1++ )
                {
                    CvArr* arr = test_array[i0][i1];
                    if( arr )
                    {
                        CvSize size = cvGetSize(arr);
                        int type = cvGetElemType(arr);
                        ts->printf( CvTS::LOG, "%s array %d type=%sC%d, size=(%d,%d)\n",
                                    arr_names[i0], i1, cvTsGetTypeName(type),
                                    CV_MAT_CN(type), size.width, size.height );
                    }
                }
            }
            ts->set_failed_test_info( code );
            return code;
        }
    }

    return 0;
}
/**
 * Transforms points from the ground plane (z=-h) in the world frame
 * into points on the image in image frame (uv-coordinates)
 *
 * \param inPoints 2xN array of input points on the ground in world coordinates
 * \param outPoints 2xN output points in on the image in image coordinates
 * \param cameraInfo the camera parameters
 *
 */
void mcvTransformGround2Image(const CvMat *inPoints,
                              CvMat *outPoints, const CameraInfo *cameraInfo)
{
    //add two rows to the input points
    CvMat *inPoints3 = cvCreateMat(inPoints->rows+1, inPoints->cols,
                                   cvGetElemType(inPoints));
    cvSet(inPoints3, cvScalar(0));

    //copy inPoints to first two rows
    CvMat inPoints2,  inPointsr3;
    cvGetRows(inPoints3, &inPoints2, 0, 2);
    cvGetRow(inPoints3, &inPointsr3, 2);
    cvSet(&inPointsr3, cvRealScalar(-cameraInfo->cameraHeight));
    cvCopy(inPoints, &inPoints2);
    //create the transformation matrix
    float c1 = cos(cameraInfo->pitch);
    float s1 = sin(cameraInfo->pitch);
    float c2 = cos(cameraInfo->yaw);
    float s2 = sin(cameraInfo->yaw);
    float matp[] = {
        cameraInfo->focalLength.x * c2 + c1*s2* cameraInfo->opticalCenter.x,
        -cameraInfo->focalLength.x * s2 + c1*c2* cameraInfo->opticalCenter.x,
        - s1 * cameraInfo->opticalCenter.x,

        s2 * (-cameraInfo->focalLength.y * s1 + c1* cameraInfo->opticalCenter.y),
        c2 * (-cameraInfo->focalLength.y * s1 + c1* cameraInfo->opticalCenter.y),
        -cameraInfo->focalLength.y * c1 - s1* cameraInfo->opticalCenter.y,

        c1*s2,
        c1*c2,
        -s1
    };
    CvMat mat = cvMat(3, 3, FLOAT_MAT_TYPE, matp);
    //multiply
    //std::cout << " inPoints3.rows " << inPoints3->rows << " inPoints3.cols "<< inPoints3->cols << "\n ";

    cvMatMul(&mat, inPoints3, inPoints3);
    //divide by last row of inPoints4
    for (int i=0; i<inPoints->cols; i++)
    {
        float div = CV_MAT_ELEM(inPointsr3, float, 0, i);

        CV_MAT_ELEM(*inPoints3, float, 0, i) =
                CV_MAT_ELEM(*inPoints3, float, 0, i) / div ;
        CV_MAT_ELEM(*inPoints3, float, 1, i) =
                CV_MAT_ELEM(*inPoints3, float, 1, i) / div;
        if(isnan(CV_MAT_ELEM(*inPoints3, float, 0, i) ) || isnan(CV_MAT_ELEM(*inPoints3, float, 1, i) ))
        {
            cout << "cameraInfo->pitch " << cameraInfo->pitch << endl;
            cout << "cameraInfo->yaw " << cameraInfo->yaw << endl;
            cout << "opticalCenter.x " << cameraInfo->opticalCenter.x << endl;
            cout << "opticalCenter.y " << cameraInfo->opticalCenter.y << endl;
            cout << "focalLength.x " << cameraInfo->focalLength.x << endl;
            cout << "focalLength.y " << cameraInfo->focalLength.y << endl;
        }
        //if(isnan(CV_MAT_ELEM(*inPoints3, float, 1, i) )) cout << "JAP!!!2 div " << div <<endl;
    }
    //put back the result into outPoints
    //std::cout << " inPoints2.rows " << inPoints2.rows << " inPoints2.cols "<< inPoints2.cols << "\n ";
    // std::cout << " outPoints.rows " << outPoints->rows << " outPoints.cols "<< outPoints->cols << "\n ";
    cvCopy(&inPoints2, outPoints);
    // std::cout << " outPoints.rows " << outPoints->rows << " outPoints.cols "<< outPoints->cols << "\n ";
    //clear
    cvReleaseMat(&inPoints3);
}
/**
 * Transforms points from the image frame (uv-coordinates)
 * into the real world frame on the ground plane (z=-height)
 *
 * \param inPoints input points in the image frame
 * \param outPoints output points in the world frame on the ground
 *          (z=-height)
 * \param cemaraInfo the input camera parameters
 *
 */
void mcvTransformImage2Ground(const CvMat *inPoints,
                              CvMat *outPoints, const CameraInfo *cameraInfo)
{

    //add two rows to the input points
    CvMat *inPoints4 = cvCreateMat(inPoints->rows+2, inPoints->cols,
                                   cvGetElemType(inPoints));

    //copy inPoints to first two rows
    CvMat inPoints2, inPoints3, inPointsr4, inPointsr3;
    cvGetRows(inPoints4, &inPoints2, 0, 2);
    cvGetRows(inPoints4, &inPoints3, 0, 3);
    cvGetRow(inPoints4, &inPointsr3, 2);
    cvGetRow(inPoints4, &inPointsr4, 3);
    cvSet(&inPointsr3, cvRealScalar(1));
    cvCopy(inPoints, &inPoints2);
    //create the transformation matrix
    float c1 = cos(cameraInfo->pitch);
    float s1 = sin(cameraInfo->pitch);
    float c2 = cos(cameraInfo->yaw);
    float s2 = sin(cameraInfo->yaw);
    float matp[] = {
        -cameraInfo->cameraHeight*c2/cameraInfo->focalLength.x,
        cameraInfo->cameraHeight*s1*s2/cameraInfo->focalLength.y,
        (cameraInfo->cameraHeight*c2*cameraInfo->opticalCenter.x/
        cameraInfo->focalLength.x)-
        (cameraInfo->cameraHeight *s1*s2* cameraInfo->opticalCenter.y/
        cameraInfo->focalLength.y) - cameraInfo->cameraHeight *c1*s2,

        cameraInfo->cameraHeight *s2 /cameraInfo->focalLength.x,
        cameraInfo->cameraHeight *s1*c2 /cameraInfo->focalLength.y,
        (-cameraInfo->cameraHeight *s2* cameraInfo->opticalCenter.x
        /cameraInfo->focalLength.x)-(cameraInfo->cameraHeight *s1*c2*
        cameraInfo->opticalCenter.y /cameraInfo->focalLength.y) -
        cameraInfo->cameraHeight *c1*c2,

        0,
        cameraInfo->cameraHeight *c1 /cameraInfo->focalLength.y,
        (-cameraInfo->cameraHeight *c1* cameraInfo->opticalCenter.y /
        cameraInfo->focalLength.y) + cameraInfo->cameraHeight *s1,

        0,
        -c1 /cameraInfo->focalLength.y,
        (c1* cameraInfo->opticalCenter.y /cameraInfo->focalLength.y) - s1,
    };

    CvMat mat = cvMat(4, 3, CV_32FC1, matp);
    //multiply
    cvMatMul(&mat, &inPoints3, inPoints4);
    //divide by last row of inPoints4
    for (int i=0; i<inPoints->cols; i++)
    {
        float div = CV_MAT_ELEM(inPointsr4, float, 0, i);
        CV_MAT_ELEM(*inPoints4, float, 0, i) =
                CV_MAT_ELEM(*inPoints4, float, 0, i) / div ;
        CV_MAT_ELEM(*inPoints4, float, 1, i) =
                CV_MAT_ELEM(*inPoints4, float, 1, i) / div;
    }
    //put back the result into outPoints
    cout << "cameraInfo->cameraHeight " << cameraInfo->cameraHeight << endl;
    cvCopy(&inPoints2, outPoints);
    //clear
    cvReleaseMat(&inPoints4);
}
/*! \fn FaceDetectorPlugin::checkZone(Zone *zone, const Image *zmImage)
 *  \param zone is a zone where faces will be detected
 *  \param zmImage is an image to perform face detection (in the form of ZM' Image)
 *  \return true if there were objects detected in given image and
 *          false otherwise
 */
bool FaceDetectorPlugin::checkZone(Zone *zone, const Image *zmImage)
{
    //log(LOG_DEBUG, "Entering checkZone.");
    double score;
    Polygon zone_polygon = Polygon(zone->GetPolygon()); // Polygon of interest of the processed zone.
    //char szMessage[50];
    //sprintf(szMessage, "Polygon of the zone has %d vertices.", zone_polygon.getNumCoords());
    //log(LOG_WARNING, szMessage);

	//zone->ResetStats();

    /*
    log(LOG_WARNING, "precheck");
    if ( !zone->CheckOverloadCount() )
    {
        log(LOG_WARNING, "CheckOverloadCount() return false, we'll return false.");
        return(false);
    }
    */
    //zmLoadConfig();
    // An image for highlighting detected objects.                                
    Image *pMaskImage = new Image(zmImage->Width(), zmImage->Height(), ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE );
    pMaskImage->Fill(BLACK);

    //log(LOG_WARNING, "FILLBLACK.");
    // An temporary image in the form of ZM for making from it CvMat.
    // If don't use temp image, after rgb->bgr it will change.
    Image *tempZmImage = new Image(*zmImage);
    CvMat* cvInputImage = NULL;
    CvMat* pScaledImage = NULL;

    bool bDoResizing = (m_fImageScaleFactor != 1.0);    // resize image or not

    if (tempZmImage->Colours() == ZM_COLOUR_GRAY8)
    {
        // if image is not colored, create an one-channel CvMat.
        cvInputImage = cvCreateMat(tempZmImage->Height(), tempZmImage->Width(), CV_8UC1);
        unsigned char *buffer = (unsigned char*)tempZmImage->Buffer();
        cvSetData(cvInputImage, buffer, tempZmImage->Width());
    }
    // NEXTIME XXX TODO: manage also 32 bit images!
    else
    {
        // otherwise create a three-channel CvMat and then convert colors from RGB to BGR.
        cvInputImage = cvCreateMat(tempZmImage->Height(), tempZmImage->Width(), CV_8UC3);
        unsigned char *buffer = (unsigned char*)tempZmImage->Buffer();
        cvSetData(cvInputImage, buffer, tempZmImage->Width() * 3);
        cvCvtColor(cvInputImage, cvInputImage, CV_RGB2BGR);
    }

    if (bDoResizing)
    {
        int nNewWidth = int (m_fImageScaleFactor * zmImage->Width());
        int nNewHeight = int (m_fImageScaleFactor * tempZmImage->Height());
        int nImageElemType = cvGetElemType(cvInputImage);
        pScaledImage = cvCreateMat(nNewHeight, nNewWidth, nImageElemType);
        cvResize(cvInputImage, pScaledImage, CV_INTER_LINEAR);
    }


    //Process image

    vector<CvRect> foundObjects;
    if (bDoResizing)
        foundObjects = _opencvHaarDetect(pScaledImage);
    else
        foundObjects = _opencvHaarDetect(cvInputImage);

    if (foundObjects.size() > 0)
        log(LOG_INFO, "OBJECTS WERE DETECTED");

    score = 0;
    for (vector<CvRect>::iterator it = foundObjects.begin(); it < foundObjects.end(); it++)
    {
        // Process found objects.

        // Scale object's coordinates back if image has been scaled.
        int x1 = int(it->x/m_fImageScaleFactor), x2 = int((it->x + it->width)/m_fImageScaleFactor), y1 = int(it->y/m_fImageScaleFactor), y2 = int((it->y + it->height)/m_fImageScaleFactor);
        
        // Check if object's rectangle is inside zone's polygon of interest.
        Coord rectVertCoords[4] = {Coord(x1, y1), Coord(x1, y2), Coord(x2, y1), Coord(x2, y2)};
        int nNumVertInside = 0;
        for (int i = 0; i < 4; i++)
        {
            nNumVertInside += zone_polygon.isInside(rectVertCoords[i]);
        }
        if (nNumVertInside < 3)
        // if at least three rectangle coordinates are inside polygon, consider rectangle as belonging to the zone
        // otherwise process next object
            continue;

        // Fill a box with object in the mask
        Box *faceBox = new Box(x1, y1, x2, y2);
        pMaskImage->Fill(WHITE, faceBox);
        // Calculate score as portion of object area in the image
        score += (100.0*(it->width)*(it->height)/m_fImageScaleFactor/m_fImageScaleFactor)/zone_polygon.Area();
        delete faceBox;
    }


    if (score == 0)
    {
        //log(LOG_DEBUG, "No objects found. Exit.");
        delete pMaskImage;
        delete tempZmImage;

        if (cvInputImage)
            cvReleaseMat(&cvInputImage);
        if (pScaledImage)
            cvReleaseMat(&pScaledImage);

        return( false );
    }



    if ( m_fMinAlarmScore && ( score < m_fMinAlarmScore) )
    {
        delete pMaskImage;
        delete tempZmImage;

        if (cvInputImage)
            cvReleaseMat(&cvInputImage);
        if (pScaledImage)
            cvReleaseMat(&pScaledImage);

        return( false );
    }
    if ( m_fMaxAlarmScore && (score > m_fMaxAlarmScore) )
    {
        zone->SetOverloadCount(zone->GetOverloadFrames());
        delete pMaskImage;
        delete tempZmImage;

        if (cvInputImage)
            cvReleaseMat(&cvInputImage);
        if (pScaledImage)
            cvReleaseMat(&pScaledImage);

        return( false );
    }


    zone->SetScore(max(1, (int)score));

    //Get mask by highlighting contours of objects and overlaying them with previous contours.
    Rgb alarm_colour = RGB_GREEN;
	Image *hlZmImage = pMaskImage->HighlightEdges(alarm_colour, ZM_COLOUR_RGB24, 
                                                 ZM_SUBPIX_ORDER_RGB, &zone_polygon.Extent());

    if (zone->Alarmed())
    {
        // if there were previous detection and they have already set up alarm image
        // then overlay it with current mask
        Image* pPrevZoneMask = new Image(*(zone->AlarmImage()));
        pPrevZoneMask->Overlay(*hlZmImage);
        zone->SetAlarmImage(pPrevZoneMask);
        delete pPrevZoneMask;
    }
    else
        zone->SetAlarmImage(hlZmImage);

    delete pMaskImage;
    delete hlZmImage;
    delete tempZmImage;

    if (cvInputImage)
        cvReleaseMat(&cvInputImage);
    if (pScaledImage)
        cvReleaseMat(&pScaledImage);

    //log(LOG_DEBUG, "Leaving checkZone.");
    return true;
}
Example #26
0
/* Warps source into destination by a perspective transform */
static void cvWarpPerspective( CvArr* src, CvArr* dst, double quad[4][2] )
{
    CV_FUNCNAME( "cvWarpPerspective" );

    __BEGIN__;

#ifdef __IPL_H__
    IplImage src_stub, dst_stub;
    IplImage* src_img;
    IplImage* dst_img;
    CV_CALL( src_img = cvGetImage( src, &src_stub ) );
    CV_CALL( dst_img = cvGetImage( dst, &dst_stub ) );
    iplWarpPerspectiveQ( src_img, dst_img, quad, IPL_WARP_R_TO_Q,
                         IPL_INTER_CUBIC | IPL_SMOOTH_EDGE );
#else

    int fill_value = 0;

    double c[3][3]; /* transformation coefficients */
    double q[4][2]; /* rearranged quad */

    int left = 0;
    int right = 0;
    int next_right = 0;
    int next_left = 0;
    double y_min = 0;
    double y_max = 0;
    double k_left, b_left, k_right, b_right;

    uchar* src_data;
    int src_step;
    CvSize src_size;

    uchar* dst_data;
    int dst_step;
    CvSize dst_size;

    double d = 0;
    int direction = 0;
    int i;

    if( !src || (!CV_IS_IMAGE( src ) && !CV_IS_MAT( src )) ||
        cvGetElemType( src ) != CV_8UC1 ||
        cvGetDims( src ) != 2 )
    {
        CV_ERROR( CV_StsBadArg,
            "Source must be two-dimensional array of CV_8UC1 type." );
    }
    if( !dst || (!CV_IS_IMAGE( dst ) && !CV_IS_MAT( dst )) ||
        cvGetElemType( dst ) != CV_8UC1 ||
        cvGetDims( dst ) != 2 )
    {
        CV_ERROR( CV_StsBadArg,
            "Destination must be two-dimensional array of CV_8UC1 type." );
    }

    CV_CALL( cvGetRawData( src, &src_data, &src_step, &src_size ) );
    CV_CALL( cvGetRawData( dst, &dst_data, &dst_step, &dst_size ) );

    CV_CALL( cvGetPerspectiveTransform( src_size, quad, c ) );

    /* if direction > 0 then vertices in quad follow in a CW direction,
       otherwise they follow in a CCW direction */
    direction = 0;
    for( i = 0; i < 4; ++i )
    {
        int ni = i + 1; if( ni == 4 ) ni = 0;
        int pi = i - 1; if( pi == -1 ) pi = 3;

        d = (quad[i][0] - quad[pi][0])*(quad[ni][1] - quad[i][1]) -
            (quad[i][1] - quad[pi][1])*(quad[ni][0] - quad[i][0]);
        int cur_direction = CV_SIGN(d);
        if( direction == 0 )
        {
            direction = cur_direction;
        }
        else if( direction * cur_direction < 0 )
        {
            direction = 0;
            break;
        }
    }
    if( direction == 0 )
    {
        CV_ERROR( CV_StsBadArg, "Quadrangle is nonconvex or degenerated." );
    }

    /* <left> is the index of the topmost quad vertice
       if there are two such vertices <left> is the leftmost one */
    left = 0;
    for( i = 1; i < 4; ++i )
    {
        if( (quad[i][1] < quad[left][1]) ||
            ((quad[i][1] == quad[left][1]) && (quad[i][0] < quad[left][0])) )
        {
            left = i;
        }
    }
    /* rearrange <quad> vertices in such way that they follow in a CW
       direction and the first vertice is the topmost one and put them
       into <q> */
    if( direction > 0 )
    {
        for( i = left; i < 4; ++i )
        {
            q[i-left][0] = quad[i][0];
            q[i-left][1] = quad[i][1];
        }
        for( i = 0; i < left; ++i )
        {
            q[4-left+i][0] = quad[i][0];
            q[4-left+i][1] = quad[i][1];
        }
    }
    else
    {
        for( i = left; i >= 0; --i )
        {
            q[left-i][0] = quad[i][0];
            q[left-i][1] = quad[i][1];
        }
        for( i = 3; i > left; --i )
        {
            q[4+left-i][0] = quad[i][0];
            q[4+left-i][1] = quad[i][1];
        }
    }

    left = right = 0;
    /* if there are two topmost points, <right> is the index of the rightmost one
       otherwise <right> */
    if( q[left][1] == q[left+1][1] )
    {
        right = 1;
    }

    /* <next_left> follows <left> in a CCW direction */
    next_left = 3;
    /* <next_right> follows <right> in a CW direction */
    next_right = right + 1;

    /* subtraction of 1 prevents skipping of the first row */
    y_min = q[left][1] - 1;

    /* left edge equation: y = k_left * x + b_left */
    k_left = (q[left][0] - q[next_left][0]) /
               (q[left][1] - q[next_left][1]);
    b_left = (q[left][1] * q[next_left][0] -
               q[left][0] * q[next_left][1]) /
                 (q[left][1] - q[next_left][1]);

    /* right edge equation: y = k_right * x + b_right */
    k_right = (q[right][0] - q[next_right][0]) /
               (q[right][1] - q[next_right][1]);
    b_right = (q[right][1] * q[next_right][0] -
               q[right][0] * q[next_right][1]) /
                 (q[right][1] - q[next_right][1]);

    for(;;)
    {
        int x, y;

        y_max = MIN( q[next_left][1], q[next_right][1] );

        int iy_min = MAX( cvRound(y_min), 0 ) + 1;
        int iy_max = MIN( cvRound(y_max), dst_size.height - 1 );

        double x_min = k_left * iy_min + b_left;
        double x_max = k_right * iy_min + b_right;

        /* walk through the destination quadrangle row by row */
        for( y = iy_min; y <= iy_max; ++y )
        {
            int ix_min = MAX( cvRound( x_min ), 0 );
            int ix_max = MIN( cvRound( x_max ), dst_size.width - 1 );

            for( x = ix_min; x <= ix_max; ++x )
            {
                /* calculate coordinates of the corresponding source array point */
                double div = (c[2][0] * x + c[2][1] * y + c[2][2]);
                double src_x = (c[0][0] * x + c[0][1] * y + c[0][2]) / div;
                double src_y = (c[1][0] * x + c[1][1] * y + c[1][2]) / div;

                int isrc_x = cvFloor( src_x );
                int isrc_y = cvFloor( src_y );
                double delta_x = src_x - isrc_x;
                double delta_y = src_y - isrc_y;

                uchar* s = src_data + isrc_y * src_step + isrc_x;

                int i00, i10, i01, i11;
                i00 = i10 = i01 = i11 = (int) fill_value;

                /* linear interpolation using 2x2 neighborhood */
                if( isrc_x >= 0 && isrc_x <= src_size.width &&
                    isrc_y >= 0 && isrc_y <= src_size.height )
                {
                    i00 = s[0];
                }
                if( isrc_x >= -1 && isrc_x < src_size.width &&
                    isrc_y >= 0 && isrc_y <= src_size.height )
                {
                    i10 = s[1];
                }
                if( isrc_x >= 0 && isrc_x <= src_size.width &&
                    isrc_y >= -1 && isrc_y < src_size.height )
                {
                    i01 = s[src_step];
                }
                if( isrc_x >= -1 && isrc_x < src_size.width &&
                    isrc_y >= -1 && isrc_y < src_size.height )
                {
                    i11 = s[src_step+1];
                }

                double i0 = i00 + (i10 - i00)*delta_x;
                double i1 = i01 + (i11 - i01)*delta_x;

                ((uchar*)(dst_data + y * dst_step))[x] = (uchar) (i0 + (i1 - i0)*delta_y);
            }
            x_min += k_left;
            x_max += k_right;
        }

        if( (next_left == next_right) ||
            (next_left+1 == next_right && q[next_left][1] == q[next_right][1]) )
        {
            break;
        }

        if( y_max == q[next_left][1] )
        {
            left = next_left;
            next_left = left - 1;

            k_left = (q[left][0] - q[next_left][0]) /
                       (q[left][1] - q[next_left][1]);
            b_left = (q[left][1] * q[next_left][0] -
                       q[left][0] * q[next_left][1]) /
                         (q[left][1] - q[next_left][1]);
        }
        if( y_max == q[next_right][1] )
        {
            right = next_right;
            next_right = right + 1;

            k_right = (q[right][0] - q[next_right][0]) /
                       (q[right][1] - q[next_right][1]);
            b_right = (q[right][1] * q[next_right][0] -
                       q[right][0] * q[next_right][1]) /
                         (q[right][1] - q[next_right][1]);
        }
        y_min = y_max;
    }
#endif /* #ifndef __IPL_H__ */

    __END__;
}
Example #27
0
bool MT_Cholesky(const CvMat* src, CvMat* dst, unsigned int orientation)
{

    if(!check_size_type(src, "Input"))
    {
        return false;
    }

    if(!dst)
    {
        fprintf(stderr, "MT_Cholesky Error:  Output is not allocated.\n");
        return false;
    }
    else
    {
        if((dst->rows != src->rows) || (dst->cols != src->cols) ||
           (cvGetElemType(dst) != cvGetElemType(src)))
        {
            fprintf(stderr,
                    "MT_Cholesky Error:  Output matrix must be same size"
                    " and type as input.\n");
            return false;
        }
    }

    if((orientation != MT_CHOLESKY_UPPER_TRIANGULAR) &&
       (orientation != MT_CHOLESKY_LOWER_TRIANGULAR))
    {
        fprintf(stderr,
                "MT_Cholesky Error:  Orientation must be either "
                "MT_CHOLESKY_UPPER_TRIANGULAR (%d) or "
                "MT_CHOLESKY_LOWER_TRIANGULAR (%d).\n",
                MT_CHOLESKY_UPPER_TRIANGULAR,
                MT_CHOLESKY_LOWER_TRIANGULAR);
        return false;
    }

    double p;
    unsigned int R = src->rows;
    cvSet(dst, cvScalar(0));
    double* src_data = src->data.db;
    double* dst_data = dst->data.db;
  
    for(int i = 0; i < R; i++)
    {
        for(int j = 0; j < R; j++)
        {
            if(i < j)
            {
                continue;
            }
      
            p = 0;
      
            if(i==j)
            {
                p = src_data[i*R + i];
                for(int k = 0; k <= j-1; k++)
                {
                    p -= dst_data[i*R+k]*dst_data[i*R+k];
                }
                if( p < 0 ){     // NOTE these may not be numerically correct, but it is a safeguard
                    p = fabs(p);
                }
                if( p == 0 ){
                    p = 1e-6;
                }
                dst_data[i*R+i] = sqrt(p);
            } else {
                p = src_data[i*R+j];
                for(int k = 0; k <= j-1; k++)
                {
                    p -= dst_data[i*R+k]*dst_data[j*R+k];
                }
                dst_data[i*R+j] = p/dst_data[j*R+j];
            }
      
        }
    }

    if(orientation == MT_CHOLESKY_UPPER_TRIANGULAR)
    {
        cvTranspose(dst, dst);
    }
  
    return true;

}