📄 acontours.cpp
字号:
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "CvTest.h"
#include <limits.h>
#include <float.h>
#define DRAW_CONTOURS 0
#if DRAW_CONTOURS
extern "C" void WINAPI Sleep(unsigned long);
#endif
static char* funcName[] =
{
"cvStartFindContours, cvFindNextContour, cvEndFindContours, cvDrawContours, cvApproxChains, "
"cvStartReadChainPoints, cvReadChainPoint",
"cvCopySeqToArray, cvContourPerimeter"
};
static char* testName[] =
{
"Retrieving contours",
"Comparing perimeter calculation with etalon algorithm"
};
static int img_size;
static int min_blob_size, max_blob_size;
static int max_contour_size;
static int base_iters;
static int blob_count;
static int init_contour_params = 0;
static const int max_storage_size = 100000;
void read_contour_params( void )
{
if( !init_contour_params )
{
trsiRead( &img_size, "307", "linear image size" );
trsiRead( &min_blob_size, "1", "Minimal size of blob" );
trsiRead( &max_blob_size, "50", "Maximal size of blob" );
trsiRead( &max_contour_size, "10000", "Maximal contour size" );
trsiRead( &blob_count, "100", "Number of blobs" );
trsiRead( &base_iters, "300", "Number of iterations" );
init_contour_params = 1;
}
}
static void mark_contours_etalon( IplImage* img, int val )
{
uchar* data = 0;
int i, step = 0;
CvSize size;
assert( img->depth == IPL_DEPTH_8U && img->nChannels == 1 && (val&1) != 0);
atsGetImageInfo( img, (void**)&data, &step, &size, 0, 0, 0 );
data += step;
for( i = 1; i < size.height - 1; i++, data += step )
{
int j;
for( j = 1; j < size.width - 1; j++ )
{
uchar* t = data + j;
if( *t == 1 && (t[-step] == 0 || t[-1] == 0 || t[1] == 0 || t[step] == 0))
*t = (uchar)val;
}
}
cvThreshold( img, img, val - 2, val, CV_THRESH_BINARY );
}
static int contour_retrieving_test( void )
{
const double success_error_level = 0;
const int depth = IPL_DEPTH_8U;
const int min_brightness = 0, max_brightness = 2;
const int mark_val = 255, mark_val2 = mark_val >> DRAW_CONTOURS;
int seed = atsGetSeed();
/* position where the maximum error occured */
int merr_iter = 0;
/* test parameters */
int i = 0;
double max_err = 0.;
int code = TRS_OK;
IplImage *src_img, *dst1_img, *dst2_img, *dst3_img;
/*IplImage *srcfl_img;*/
AtsRandState rng_state;
CvMemStorage* storage;
CvSize size;
atsRandInit( &rng_state, 0, 1, seed );
read_contour_params();
size = cvSize( img_size, img_size*3/4 );
src_img = cvCreateImage( size, depth, 1 );
dst1_img = cvCreateImage( size, depth, 1 );
dst2_img = cvCreateImage( size, depth, 1 );
dst3_img = cvCreateImage( size, depth, 1 );
storage = cvCreateMemStorage(atsRandPlain32s(&rng_state) % max_storage_size );
for( i = 0; i < base_iters; i++ )
{
double err = 0, err1 = 0;
int count = 0, count2 = 0, count3 = 0;
CvChainApproxMethod approxMethod;
CvContourRetrievalMode retrMode;
(int&)approxMethod = atsRandPlain32s( &rng_state ) % 4 + 1;
(int&)retrMode = atsRandPlain32s( &rng_state ) % 4;
CvSeq* contours = 0;
CvSeq* contours2 = 0;
CvSeq* contours3 = 0;
atsGenerateBlobImage( src_img, min_blob_size, max_blob_size, blob_count,
min_brightness, max_brightness, &rng_state );
iplCopy( src_img, dst2_img );
iplCopy( src_img, dst3_img );
atsClearBorder( src_img );
iplCopy( src_img, dst1_img );
mark_contours_etalon( dst1_img, mark_val );
count = cvFindContours( dst2_img, storage, &contours, sizeof(CvContour),
retrMode, approxMethod );
iplSet( dst2_img, 0 );
if( contours )
{
cvDrawContours( dst2_img, contours, mark_val2, mark_val2, INT_MAX );
}
#if DRAW_CONTOURS
{
CvSize winSize = cvSize(960,960);
int win = atsCreateWindow( "", cvPoint(10,10), winSize);
iplMultiplyS( src_img, src_img, 64 );
atsDisplayImage( src_img, win, cvPoint(0,0), winSize);
Sleep( 3000 );
iplXor( src_img, dst1_img, dst1_img );
atsDisplayImage( dst1_img, win, cvPoint(0,0), winSize);
Sleep( 10000 );
atsDestroyWindow( win );
}
#endif
if( retrMode != CV_RETR_EXTERNAL && approxMethod < CV_CHAIN_APPROX_TC89_L1 )
err = iplNorm( dst1_img, dst2_img, IPL_L1 );
count2 = cvFindContours( dst3_img, storage, &contours2, sizeof(CvChain),
retrMode, CV_CHAIN_CODE );
if( count2 != count )
{
code = TRS_FAIL;
goto test_exit;
}
if( approxMethod < CV_CHAIN_APPROX_TC89_L1 )
{
iplSet( dst3_img, 0 );
if( contours2 )
{
cvDrawContours( dst3_img, contours2, mark_val2, mark_val2, INT_MAX );
}
err1 = iplNorm( dst2_img, dst3_img, IPL_L1 );
err = MAX( err, err1 );
if( approxMethod == CV_CHAIN_APPROX_NONE )
{
CvSeqTreeIterator iterator1;
CvSeqTreeIterator iterator2;
icvInitSeqTreeIterator( &iterator1, contours, INT_MAX );
icvInitSeqTreeIterator( &iterator2, contours2, INT_MAX );
for(;;)
{
CvSeq* seq1 = icvNextSeq( &iterator1 );
CvChain* seq2 = (CvChain*)icvNextSeq( &iterator2 );
CvSeqReader reader;
CvChainPtReader reader2;
CvChainPtReader reader3;
if( !seq1 )
break;
assert( seq2 );
cvStartReadSeq( seq1, &reader );
cvStartReadChainPoints( seq2, &reader2 );
cvStartReadChainPoints( seq2, &reader3 );
for( int j = 0; j < seq1->total; j++ )
{
CvPoint pt;
CvPoint pt2;
CvPoint pt3;
CV_READ_SEQ_ELEM( pt, reader );
CV_READ_CHAIN_POINT( pt2, reader2 );
pt3 = cvReadChainPoint( &reader3 );
if( pt.x != pt2.x || pt.x != pt3.x ||
pt.y != pt2.y || pt.y != pt3.y )
{
code = TRS_FAIL;
goto test_exit;
}
}
}
}
}
contours3 = cvApproxChains( contours2, storage, approxMethod, 0, 0, 1 );
{
CvSeqTreeIterator iterator1;
CvSeqTreeIterator iterator2;
icvInitSeqTreeIterator( &iterator1, contours, INT_MAX );
icvInitSeqTreeIterator( &iterator2, contours3, INT_MAX );
for( ;; count3++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -