static int aMatchContourTrees(void)
{
    CvSeqBlock contour_blk1, contour_blk2;
    CvContour contour_h1, contour_h2;
    CvContourTree *tree1, *tree2;
    CvMemStorage *storage;   /*   storage for contour and tree writing */
    int block_size = 10000;

    CvRandState state;
    double lower, upper;
    int seed;
    float fr;
    int type_seq;
    int method;
    int nPoints1 = 12, nPoints2 = 12;
    int xc,yc,a1 = 10, b1 = 20, a2 = 10, b2 =20, fi = 0;
    int xmin,ymin,xmax,ymax;
    double error_test,rezult, eps_rez = 0.8;
    double pi = 3.1415926;
    double threshold = 1.e-7;
    double threshold2 = 5.;
    int i;
    int code = TRS_OK;

    int width=256,height=256;
    CvPoint *cp1,*cp2;

    /* read tests params */

    if (!trsiRead(&nPoints1,"20","Number of points first contour"))
        return TRS_UNDEF;
    if (!trsiRead(&nPoints2,"20","Number of points second contour"))
        return TRS_UNDEF;

    if(nPoints1>0&&nPoints2>0)
    {
        if (!trsiRead(&a1,"10","first radius of the first elipse"))
            return TRS_UNDEF;
        if (!trsiRead(&b1,"20","second radius of the first elipse"))
            return TRS_UNDEF;
        if (!trsiRead(&a2,"15","first radius of the second elipse"))
            return TRS_UNDEF;
        if (!trsiRead(&b2,"30","second radius of the second elipse"))
            return TRS_UNDEF;
        if (!trsiRead(&fi,"0","second radius of the second elipse"))
            return TRS_UNDEF;

        if (!trsdRead(&upper,"3","noise amplidude"))
            return TRS_UNDEF;

        xc = (int)(width/2.);
        yc = (int)(height/2.);
        xmin = width;
        ymin = height;
        xmax = 0;
        ymax = 0;

        cp1 = (CvPoint*) trsmAlloc(nPoints1*sizeof(CvPoint));
        cp2 = (CvPoint*) trsmAlloc(nPoints2*sizeof(CvPoint));

        for(i=0; i<nPoints1; i++)
        {
            cp1[i].x = (int)(a1*cos(2*pi*i/nPoints1))+xc;
            cp1[i].y = (int)(b1*sin(2*pi*i/nPoints1))+yc;
            if(xmin> cp1[i].x) xmin = cp1[i].x;
            if(xmax< cp1[i].x) xmax = cp1[i].x;
            if(ymin> cp1[i].y) ymin = cp1[i].y;
            if(ymax< cp1[i].y) ymax = cp1[i].y;
        }

        if(xmax>width||xmin<0||ymax>height||ymin<0) return TRS_FAIL;

        lower = -upper;
        /*     upper = 3;*/
        seed = 345753;
        cvRandInit(&state, (float)lower,(float)upper, seed );
        for(i=0; i<nPoints2; i++)
        {
            cvbRand( &state, &fr, 1 );
            cp2[i].x =(int)fr+(int)(a2*cos(2*pi*i/nPoints2)*cos(2*pi*fi/360.))-
                      (int)(b2*sin(2*pi*i/nPoints2)*sin(2*pi*fi/360.))+xc;
            cvbRand( &state, &fr, 1 );
            cp2[i].y =(int)fr+(int)(a2*cos(2*pi*i/nPoints2)*sin(2*pi*fi/360.))+
                      (int)(b2*sin(2*pi*i/nPoints2)*cos(2*pi*fi/360.))+yc;

            if(xmin> cp2[i].x) xmin = cp2[i].x;
            if(xmax< cp2[i].x) xmax = cp2[i].x;
            if(ymin> cp2[i].y) ymin = cp2[i].y;
            if(ymax< cp2[i].y) ymax = cp2[i].y;
        }
        if(xmax>width||xmin<0||ymax>height||ymin<0) return TRS_FAIL;

        /*   contours initialazing */
        type_seq = CV_SEQ_POLYGON;
        cvMakeSeqHeaderForArray( type_seq, sizeof(CvContour), sizeof(CvPoint),
                                 (char*)cp1, nPoints1, (CvSeq*)&contour_h1, &contour_blk1);

        cvMakeSeqHeaderForArray( type_seq, sizeof(CvContour), sizeof(CvPoint),
                                 (char*)cp2, nPoints2, (CvSeq*)&contour_h2, &contour_blk2);

        /*  contour trees created*/
        storage = cvCreateMemStorage( block_size );

        tree1 = cvCreateContourTree ((CvSeq*)&contour_h1, storage, threshold);
        tree2 = cvCreateContourTree ((CvSeq*)&contour_h2, storage, threshold);


        /*  countours matchig */
        error_test = 0.;
        method = 1;

        rezult = cvMatchContourTrees (tree1, tree2, (CvContourTreesMatchMethod)method,threshold2);
        error_test+=rezult;

        if(error_test > eps_rez ) code = TRS_FAIL;
        else code = TRS_OK;

        trsWrite( ATS_CON | ATS_LST | ATS_SUM, "contours matching error_test =%f \n",
                  error_test);

        cvReleaseMemStorage ( &storage );

        trsFree (cp2);
        trsFree (cp1);

    }


    /*    _getch();     */
    return code;
}
int testShrinkObservedNodes()
{
    int i/*,j*/;
    int ret = TRS_OK;
    /*prepare to read the values from console*/
    EDistributionType dt;
    int disType = -1;
    EFactorType pt;
    int paramType = -1;
    /*read int disType corresponding DistributionType*/
    while((disType<0)||(disType>0))/*now we have only Tabulars&Gaussian*/
    {
	trsiRead( &disType, "0", "DistributionType");
    }
    /*read int paramType corresponding FactorType*/
    while((paramType<0)||(paramType>2))
    {
	trsiRead( &paramType, "0", "FactorType");
    }
    dt = EDistributionType(disType);
    pt = EFactorType(paramType);
    int numberOfNodes = 0;
    /*read number of nodes in Factor domain*/
    while(numberOfNodes<=0)
    {
	trsiRead( &numberOfNodes, "1", "Number of Nodes in domain");
    }
    int numNodeTypes = 0;
    /*read number of node types in model*/
    while(numNodeTypes<=0)
    {
	trsiRead( &numNodeTypes, "1", "Number of node types in Domain");
    }
    //int seed1 = pnlTestRandSeed()/*%100000*/;
    /*create string to display the value*/
    /*	char *value = new char[20];
    value = _itoa(seed1, value, 10);
    trsiRead(&seed1, value, "Seed for srand to define NodeTypes etc.");
    delete []value;
    trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "seed for rand = %d\n", seed1);
    int *domain = (int *)trsGuardcAlloc(numberOfNodes, sizeof(int));
    CNodeType * allNodeTypes = (CNodeType*)trsGuardcAlloc(numNodeTypes,
    sizeof(CNodeType));
    //To generate the NodeTypes we use rand()% and creates only Tabular now
    for(i=0; i<numNodeTypes; i++)
    {
    allNodeTypes[i] = CNodeType(1, 1+rand()%(numNodeTypes+3));
    }
    */	
    
    /*load data for parameter::ShrinkObservedNodes from console*/
    intVector domain;
    domain.assign( numberOfNodes, 0 );
    nodeTypeVector allNodeTypes;
    allNodeTypes.assign( numNodeTypes, CNodeType() );
    /*read node types*/
    for(i=0; i < numNodeTypes; i++)
    {
	int IsDiscrete = -1;
	int NodeSize = -1;
	while((IsDiscrete<0)||(IsDiscrete>1))
	    /*now we have tabular & Gaussian nodes!! */
	    trsiRead(&IsDiscrete, "1", "Is the node discrete?");
	while(NodeSize<0)
	    trsiRead(&NodeSize, "2", "NodeSize of node");
	allNodeTypes[i] = CNodeType( IsDiscrete != 0, NodeSize );
    }
    const CNodeType **nodeTypesOfDomain = (const CNodeType**)
	trsGuardcAlloc(numberOfNodes, sizeof(CNodeType*));
    int numData = 1;
    int *Ranges = (int*)trsGuardcAlloc(numberOfNodes, sizeof(int));
    /*associate nodes to node types*/
    for(i=0; i<numberOfNodes; i++)
    {
	domain[i] = i;
	int nodeAssociationToNodeType = -1;
	while((nodeAssociationToNodeType<0)||(nodeAssociationToNodeType>=
	    numNodeTypes))
	    trsiRead(&nodeAssociationToNodeType, "0", 
	    "node i has type nodeAssociationToNodeType");
	nodeTypesOfDomain[i] = &allNodeTypes[nodeAssociationToNodeType];
	//	nodeTypesOfDomain[i] = &allNodeTypes[rand()%numNodeTypes];
	Ranges[i] = nodeTypesOfDomain[i]->GetNodeSize();
	numData=numData*Ranges[i];
    }
    
    CModelDomain* pMD = CModelDomain::Create( allNodeTypes, domain );
    
    /*create factor according all information*/
    CFactor *pMyParam = NULL;
    float *data = (float *)trsGuardcAlloc(numData, sizeof(float));
    char *stringVal;/* = (char*)trsGuardcAlloc(50, sizeof(char));*/
    double val=0;
    /*read the values from console*/
    if(pt == ftPotential)
    {
	pMyParam = CTabularPotential::Create( &domain.front(), numberOfNodes, pMD );
	/*here we can create data by multiply on 0.1 - numbers are nonnormalized*/
	for(i=0; i<numData; i++)
	{
	    val = 0.1*i;
	    stringVal = trsDouble(val);
	    trsdRead(&val, stringVal, "value of i's data position");
	    data[i] = (float)val;
	    //data[i] = (float)rand()/1000;
	}
    }
    else
    {
    /*we can only read data from console - it must be normalized!!
	(according their dimensions) - or we can normalize it by function!*/
	if(pt == ftCPD)
	    pMyParam = CTabularCPD::Create( &domain.front(), numberOfNodes, pMD );
	for(i=0; i<numData; i++)
	{
	    val = -1;
	    while((val<0)||(val>1))
	    {
		trsdRead(&val, "-1", "value of (2*i)'s data position");
	    }
	    data[i] = (float)val;
	}
    }
    //trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "data for Factor = %d\n", data[i]);
    pMyParam->AllocMatrix(data,matTable);
    int nObsNodes = 0;	/*rand()%numberOfNodes;*/
    while((nObsNodes<=0)||(nObsNodes>numberOfNodes))
    {
	trsiRead(&nObsNodes, "1", "Number of Observed Nodes");
    }
    intVector myHelpForEvidence = intVector(domain.begin(), domain.end() );
    int *ObsNodes = (int *)trsGuardcAlloc(nObsNodes, sizeof(int));
    valueVector TabularValues;
    TabularValues.assign( nObsNodes, (Value)0 );
    char *strVal;
    for(i=0; i<nObsNodes; i++)
    {
	//fixme - we need to have noncopy only different ObsNodes
	/*		j = rand()%(numberOfNodes-i);*/
	int numberOfObsNode = -1;
	strVal = trsInt(i);
        intVector::iterator j = std::find( myHelpForEvidence.begin(), myHelpForEvidence.end(), numberOfObsNode );
	while((numberOfObsNode<0)||(numberOfObsNode>numberOfNodes)||
	    (j==myHelpForEvidence.end()))
	{
	    trsiRead(&numberOfObsNode, strVal,"Number of i's observed node");
	    j = std::find(myHelpForEvidence.begin(), myHelpForEvidence.end(),
		numberOfObsNode);
	}
	//ObsNodes[i] = myHelpForEvidence[j];
	myHelpForEvidence.erase( j );
	ObsNodes[i] = numberOfObsNode;
	int valueOfNode = -1;
	int maxValue = (*nodeTypesOfDomain[ObsNodes[i]]).GetNodeSize();
	while((valueOfNode<0)||(valueOfNode>=maxValue))
	{
	    trsiRead(&valueOfNode,"0","this is i's observed node value");
	}
	TabularValues[i].SetInt(valueOfNode);
	/*rand()%((*nodeTypesOfDomain[ObsNodes[i]]).pgmGetNodeSize());*/
    }
    CEvidence* pEvidence = CEvidence::Create( pMD, nObsNodes, ObsNodes, TabularValues );
    myHelpForEvidence.clear();
    CNodeType *ObservedNodeType = (CNodeType*)trsGuardcAlloc(1, 
	sizeof(CNodeType));
    *ObservedNodeType = CNodeType(1,1);
    CPotential *myTakedInFactor = static_cast<CPotential*>(pMyParam)->ShrinkObservedNodes(pEvidence);
    const int *myfactorDomain;
    int factorDomSize ;
    myTakedInFactor->GetDomain(&factorDomSize, &myfactorDomain);
#if 0
    CNumericDenseMatrix<float> *mySmallMatrix = static_cast<
        CNumericDenseMatrix<float>*>(myTakedInFactor->GetMatrix(matTable));
    int n;
    const float* mySmallData;
    mySmallMatrix->GetRawData(&n, &mySmallData);
    int nDims; // = mySmallMatrix->GetNumberDims();
    const int * mySmallRanges;
    mySmallMatrix->GetRanges(&nDims, &mySmallRanges);
    
    if(nDims!=numberOfNodes)
    {
	ret = TRS_FAIL;
	trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "nDims = %d\n", nDims);
    }
    else
    {
	int numSmallData = 1;
	for(i=0; i<nDims; i++)
	{
	    numSmallData = numSmallData*mySmallRanges[i];
	    trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "Range[%d] = %d\n", i, 
		mySmallRanges[i]);
	}
	for(i=0; i<numSmallData; i++)
	{	
	    trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "mySmallData[%d] = %f ",
		i, mySmallData[i]);
	}
    }
#endif
    //getchar();
    delete(myTakedInFactor);
    delete (pMyParam);
    delete pMD;
    //test gaussian parameter
    nodeTypeVector nTypes;
    nTypes.assign( 2, CNodeType() );
    nTypes[0] = CNodeType( 0, 2 );
    nTypes[1] = CNodeType( 0,1 );
    intVector domn = intVector(3,0);
    domn[1] = 1;
    domn[2] = 1;
    
    CModelDomain* pMD1 = CModelDomain::Create( nTypes, domn );
    
    domn[2] = 2;
    
    CPotential *BigFactor = CGaussianPotential::CreateUnitFunctionDistribution( 
	&domn.front(), domn.size(), pMD1,0 );
    float mean[] = { 1.0f, 3.2f};
    CPotential *SmallDelta = CGaussianPotential::CreateDeltaFunction( &domn.front(), 1, pMD1, mean, 1 );
    domn.resize( 2 );
    domn[0] = 1;
    domn[1] = 2;
    CPotential *SmallFunct = CGaussianPotential::Create( &domn.front(),
	domn.size(),  pMD1);
    float datH[] = { 1.1f, 2.2f, 3.3f };
    float datK[] = { 1.2f, 2.3f, 2.3f, 3.4f, 5.6f, 6.7f, 3.4f, 6.7f, 9.0f };
    SmallFunct->AllocMatrix( datH, matH );
    SmallFunct->AllocMatrix( datK, matK );
    static_cast<CGaussianPotential*>(SmallFunct)->SetCoefficient( 0.2f, 1 );
    CPotential* multFact = BigFactor->Multiply( SmallDelta );
    CPotential* nextMultFact = multFact->Multiply( SmallFunct );
    domn[0] = 0;
    domn[1] = 1;
    CPotential *marginalized = static_cast<CPotential*>(nextMultFact->Marginalize( &domn.front(), domn.size() ));
    int isSpecific = marginalized->IsDistributionSpecific();
    if( isSpecific )
    {
	trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "\nGaussian Distribution is specific");
    }
    delete BigFactor;
    delete SmallFunct;
    delete SmallDelta;
    delete pMD1;
    
    int ranges_memory_flag = trsGuardCheck(Ranges);
    int data_memory_flag = trsGuardCheck(data);
    int nodeTypesOfDomain_mem_b = trsGuardCheck(nodeTypesOfDomain);
    int ObsNodes_mem_b = trsGuardCheck(ObsNodes);
    int ObsNodeType_mem_b = trsGuardCheck(ObservedNodeType);
    if(((ranges_memory_flag)||(data_memory_flag)||
	(nodeTypesOfDomain_mem_b)||
	(ObsNodes_mem_b)||(ObsNodeType_mem_b)))
    {
	ret = TRS_FAIL;
	return trsResult( ret, ret == TRS_OK ? "No errors" : 
	"Bad test on ShrinkObservedNodes Method - memory");
    }
    else
    {
	trsGuardFree(ObservedNodeType);
	trsGuardFree(ObsNodes);
	trsGuardFree(nodeTypesOfDomain);
	trsGuardFree(data);
	trsGuardFree(Ranges);
    }			
    return trsResult( ret, ret == TRS_OK ? "No errors" : 
    "Bad test on ShrinkObservedNodes Method");
}
Exemple #3
0
/*=================================================== Test body ========================== */
static int fmaNormMask(void)
{
    /* Some Variables */
    int nx, ny, n, n4, it, ir, nr, nerr=0, coi, step, step4;
    int xoff, yoff, roiw, roih, nerrt[9];
    CvSize size;
    AtsRandState state1, state2, state3, state4;
    IplImage *A_8uC1, *A_8sC1, *A_32fC1, *B_8uC1, *B_8sC1, *B_32fC1;
    IplImage *A_8uC3, *A_8sC3, *A_32fC3, *B_8uC3, *B_8sC3, *B_32fC3;
    IplImage *mask;
    IplROI   r, rm;
    double norm, testnorm, err;
    double Mask_density, d1, d2;

    trsiRead( &Min_Image_Width,  "1", "Minimal image width" );
    trsiRead( &Max_Image_Width, "32", "Maximal image width" );
    trsiRead( &Max_ROI_Offset,   "8", "Maximal ROI offset" );
    trsdRead( &Mask_density,   "0.5", "Mask density (0 - 1)" );

    if( Min_Image_Width < 1 )               Min_Image_Width = 1;
    if( Max_Image_Width < Min_Image_Width ) Max_Image_Width = Min_Image_Width;
    if( Max_ROI_Offset  < 0 )               Max_ROI_Offset  = 0;
    if( Mask_density    < 0.0 )             Mask_density    = 0.0;

    if( Mask_density >= 1.0 ) { d1 = 2.0; d2 = 4.0; }
    else                      { d1 = 0.0; d2 = 1.0/(1.0-Mask_density); }
    if(d2>256.0) d2=256.0;

    atsRandInit( &state1, MIN_VAL(IPL_DEPTH_8U),  MAX_VAL(IPL_DEPTH_8U),  13 );
    atsRandInit( &state2, MIN_VAL(IPL_DEPTH_8S),  MAX_VAL(IPL_DEPTH_8S),  14 );
    atsRandInit( &state3, MIN_VAL(IPL_DEPTH_32F), MAX_VAL(IPL_DEPTH_32F), 15 );
    atsRandInit( &state4, d1, d2, 16 );

    for( it=0; it<9; it++ ) nerrt[it] = 0;

/*  Image size cycle starts ________________________ */
    for( nx = Min_Image_Width; nx<=Max_Image_Width; nx++ )
    {
        ny = nx;
        /*if(nx>1)ny=(int)(0.7*nx);           // Non-square images test */
        size.width  = nx;  size.height = ny;

        /* Initial images allocating & random filling */
        A_8uC1  = cvCreateImage( size, IPL_DEPTH_8U,  1 );
        A_8sC1  = cvCreateImage( size, IPL_DEPTH_8S,  1 );
        A_32fC1 = cvCreateImage( size, IPL_DEPTH_32F, 1 );

        B_8uC1  = cvCreateImage( size, IPL_DEPTH_8U,  1 );
        B_8sC1  = cvCreateImage( size, IPL_DEPTH_8S,  1 );
        B_32fC1 = cvCreateImage( size, IPL_DEPTH_32F, 1 );

        A_8uC3  = cvCreateImage( size, IPL_DEPTH_8U,  3 );
        A_8sC3  = cvCreateImage( size, IPL_DEPTH_8S,  3 );
        A_32fC3 = cvCreateImage( size, IPL_DEPTH_32F, 3 );

        B_8uC3  = cvCreateImage( size, IPL_DEPTH_8U,  3 );
        B_8sC3  = cvCreateImage( size, IPL_DEPTH_8S,  3 );
        B_32fC3 = cvCreateImage( size, IPL_DEPTH_32F, 3 );

        mask  = cvCreateImage( size, IPL_DEPTH_8U,  1 );

        step = A_8uC1->widthStep;  step4 = (A_32fC1->widthStep)/4;
        n = ny*step;  n4 = ny*step4;

        atsbRand8u ( &state1, (uchar*)A_8uC1->imageData,  n );
        atsbRand8s ( &state2, A_8sC1->imageData,  n );
        atsbRand32f( &state3, (float*)A_32fC1->imageData, n4);

        atsbRand8u ( &state1, (uchar*)B_8uC1->imageData,  n );
        atsbRand8s ( &state2, B_8sC1->imageData,  n );
        atsbRand32f( &state3, (float*)B_32fC1->imageData, n4);

        atsbRand8u ( &state4, (uchar*)mask->imageData,  n );
        for(ir=0; ir<n; ir++) if((mask->imageData)[ir]>1) (mask->imageData)[ir]=1;
        (mask->imageData)[0] = 1;

        step = A_8uC3->widthStep;  step4 = (A_32fC3->widthStep)/4;
        n = ny*step;  n4 = ny*step4;

        atsbRand8u ( &state1, (uchar*)A_8uC3->imageData,  n );
        atsbRand8s ( &state2, A_8sC3->imageData,  n );
        atsbRand32f( &state3, (float*)A_32fC3->imageData, n4);

        atsbRand8u ( &state1, (uchar*)B_8uC3->imageData,  n );
        atsbRand8s ( &state2, B_8sC3->imageData,  n );
        atsbRand32f( &state3, (float*)B_32fC3->imageData, n4);

        nr = (ny-1)/2>Max_ROI_Offset ? Max_ROI_Offset : (ny-1)/2;

        A_8uC1->roi = A_8sC1->roi = A_32fC1->roi = 
        A_8uC3->roi = A_8sC3->roi = A_32fC3->roi = 
        B_8uC1->roi = B_8sC1->roi = B_32fC1->roi = 
        B_8uC3->roi = B_8sC3->roi = B_32fC3->roi = &r;

        for( ir = 0; ir<=nr; ir++) /* ROI size cycle starts ----------------- */
        {
            /* IPL ROI structures filling */
            xoff = ir/11;
            yoff = ir;
            roiw = nx - (int)(1.2*xoff);
            roih = ny - (int)(1.5*yoff);
            r.xOffset = xoff;
            r.yOffset = yoff;
            r.width   = roiw;
            r.height  = roih;

            rm = r;
            rm.coi = 0;
            mask->roi = &rm;

/*  T E S T I N G  */
            for(it = 0; it<9; it++)
            {
                IplImage* B;

                r.coi = 0;

                //if( it >= 3 )
                //    continue;

                B = it<3 ? NULL : B_8uC1;
                A_8uC1->maskROI = B_8uC1->maskROI = NULL;
                norm     =   cvNormMask( A_8uC1, B, mask, cvlType[it] );
                testnorm = TestNormMask( A_8uC1, B, mask, cvlType[it] );
                err = fabs((norm-testnorm)/testnorm);
                if( err > EPS )
                {
                    nerrt[it]++;
                    printf(" 8uC1  %d norm fail:  %f  %f\n", it+1, norm, testnorm);
                }

                B = it<3 ? NULL : B_8sC1;
                A_8sC1->maskROI = B_8sC1->maskROI = NULL;
                norm     =   cvNormMask( A_8sC1, B, mask, cvlType[it] );
                testnorm = TestNormMask( A_8sC1, B, mask, cvlType[it] );
                err = fabs((norm-testnorm)/testnorm);
                if( err > EPS )
                {
                    nerrt[it]++;
                    printf(" 8sC1  %d norm fail:  %f  %f\n", it+1, norm, testnorm);
                }

                B = it<3 ? NULL : B_32fC1;
                A_32fC1->maskROI = B_32fC1->maskROI = NULL;
                norm     =   cvNormMask( A_32fC1, B, mask, cvlType[it] );
                testnorm = TestNormMask( A_32fC1, B, mask, cvlType[it] );
                err = fabs((norm-testnorm)/testnorm);
                if( err > FEPS )
                {
                    nerrt[it]++;
                    printf(" 32fC1 %d norm fail:  %f  %f\n", it+1, norm, testnorm);
                }

                    B = it<3 ? NULL : B_8uC3;
                    for( coi=1; coi<4; coi++ )
                    {
                        r.coi   = coi;
                        A_8uC3->maskROI = B_8uC3->maskROI = NULL;
                        norm     =   cvNormMask( A_8uC3, B, mask, cvlType[it] );
                        testnorm = TestNormMask( A_8uC3, B, mask, cvlType[it] );
                        err     = fabs((norm-testnorm)/testnorm);
                        if( err > EPS )
                        {
                            nerrt[it]++;
                            printf(" 8uC3  %d norm fail:  %f  %f,  coi = %d\n", it+1, norm, testnorm, coi);
                        }
                    }

                    B = it<3 ? NULL : B_8sC3;
                    for( coi=1; coi<4; coi++ )
                    {
                        r.coi = coi;
                        A_8sC3->maskROI = B_8sC3->maskROI = NULL;
                        norm     =   cvNormMask( A_8sC3, B, mask, cvlType[it] );
                        testnorm = TestNormMask( A_8sC3, B, mask, cvlType[it] );
                        err = fabs((norm-testnorm)/testnorm);
                        if( err > EPS )
                        {
                            nerrt[it]++;
                            printf(" 8sC3  %d norm fail:  %f  %f,  coi = %d\n", it+1, norm, testnorm, coi);
                        }
                    }

                    B = it<3 ? NULL : B_32fC3;
                    for( coi=1; coi<4; coi++ )
                    {
                        r.coi = coi;
                        A_32fC3->maskROI = B_32fC3->maskROI = NULL;
                        norm     =   cvNormMask( A_32fC3, B, mask, cvlType[it] );
                        testnorm = TestNormMask( A_32fC3, B, mask, cvlType[it] );
                        err = fabs((norm-testnorm)/testnorm);
                        if( err > FEPS )
                        {
                            nerrt[it]++;
                            printf(" 32fC3 %d norm fail:  %f  %f,  coi = %d\n", it+1, norm, testnorm, coi);
                        }
                    }
            } /* norm type */

            for( it=0; it<9; it++ ) nerr += nerrt[it];
        } /* ROI */

        A_8uC1->roi = A_8sC1->roi = A_32fC1->roi = 
        A_8uC3->roi = A_8sC3->roi = A_32fC3->roi = 
        B_8uC1->roi = B_8sC1->roi = B_32fC1->roi = 
        B_8uC3->roi = B_8sC3->roi = B_32fC3->roi = 0;

        mask->roi = 0;

        A_8uC1->maskROI = A_8sC1->maskROI = A_32fC1->maskROI = 
        A_8uC3->maskROI = A_8sC3->maskROI = A_32fC3->maskROI = 
        B_8uC1->maskROI = B_8sC1->maskROI = B_32fC1->maskROI = 
        B_8uC3->maskROI = B_8sC3->maskROI = B_32fC3->maskROI = 0;

        mask->maskROI = 0;

        cvReleaseImage( &A_8uC1  );
        cvReleaseImage( &A_8sC1  );
        cvReleaseImage( &A_32fC1 );
        cvReleaseImage( &B_8uC1  );
        cvReleaseImage( &B_8sC1  );
        cvReleaseImage( &B_32fC1 );
        cvReleaseImage( &A_8uC3  );
        cvReleaseImage( &A_8sC3  );
        cvReleaseImage( &A_32fC3 );
        cvReleaseImage( &B_8uC3  );
        cvReleaseImage( &B_8sC3  );
        cvReleaseImage( &B_32fC3 );
        cvReleaseImage( &mask    );
    } /* Nx */

/*trsWrite (TW_RUN|TW_CON|TW_SUM," %d norm  %s%s flavor  fail:  %g %g\n",
          it+1, f1, f2, norm, testnorm);*/

    if(nerr) return trsResult( TRS_FAIL, "Algorithm test has passed. %d errors.", nerr );
    else    return trsResult( TRS_OK, "Algorithm test has passed successfully" );

} /* fmaNorm */