cvcalibinit.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 613 行 · 第 1/2 页
SVN-BASE
613 行
/*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 "_cv.h"
#include "_cvgeom.h"
#include "string.h"
#include <limits.h>
typedef struct CvContourEx
{
CV_CONTOUR_FIELDS()
int counter;
}
CvContourEx;
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: cvFindChessBoardCornerGuesses8uC1R
// Purpose:
// Function finds first approximation of internal corners on the chess board.
// Context:
// Parameters:
// img - source haltone image
// step - its full width in bytes
// thresh - temporary image where will the thresholded source image be stored.
// th_step - full width of temporary image row in bytes
// size - width and height of the images in pixels
// etalon_size - number of corners in checkerboard per row and per column.
// corners - pointer to array, containing found points
// corner_count - number of corners found
// Returns:
// Notes:
//F*/
CV_IMPL int
cvFindChessBoardCornerGuesses( const void* arr, void* thresharr,
CvMemStorage * storage,
CvSize etalon_size, CvPoint2D32f * corners,
int *corner_count )
{
#define BUFFER_SIZE 8192
const int min_approx_level = 2;
const int max_approx_level = 4;
int min_size;
CvContourScanner scanner;
CvStatus result = CV_NO_ERR;
double mean;
int thresh_level;
int temp_count = 0, found = 0;
CvPoint pt_buffer[BUFFER_SIZE];
CvSeqReader reader;
CvSeq *src_contour = 0;
CvMemStorage *storage1 = 0;
CvSeq *root;
CvContourEx* board = 0;
int max_count = 0;
CvPoint *iPoints = 0;
CvPoint *ordered = 0;
CvPoint *hullpoints = 0;
int *indices = 0;
int idx;
int quandrangles = 0;
CV_FUNCNAME( "cvFindChessBoardCornerGuesses" );
__BEGIN__;
CvMat stub, *img = (CvMat*)arr;
CvMat thstub, *thresh = (CvMat*)thresharr;
CvSize size;
if( corner_count )
{
max_count = *corner_count;
*corner_count = 0;
}
CV_CALL( img = cvGetMat( img, &stub ));
CV_CALL( thresh = cvGetMat( thresh, &thstub ));
if( CV_MAT_TYPE( img->type ) != CV_8UC1 ||
CV_MAT_TYPE( thresh->type ) != CV_8UC1 )
CV_ERROR( CV_BadDepth, icvUnsupportedFormat );
if( !CV_ARE_SIZES_EQ( img, thresh ))
CV_ERROR( CV_StsUnmatchedSizes, "" );
size = icvGetMatSize( img );
//
// Create temporary storages.
// First one will store retrived contours and the
// second one - approximated contours.
storage1 = storage ? cvCreateChildMemStorage( storage ) : cvCreateMemStorage(0);
root = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvSeq*), storage1 );
// empiric bound for minimal allowed perimeter for squares
min_size = cvRound( size.width*size.height * .03 * 0.03 );
// empiric threshold level
mean = cvMean( img );
thresh_level = cvRound( mean - 10 );
thresh_level = MAX( thresh_level, 10 );
// Make dilation before the thresholding.
// It splits chessboard corners
cvDilate( img, thresh, 0, 1 );
// convert to binary
cvThreshold( thresh, thresh, thresh_level, 255, CV_THRESH_BINARY );
// initialize contour retrieving routine
scanner = cvStartFindContours( thresh, storage1, sizeof( CvContourEx ),
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
// get all the contours one by one
while( (src_contour = cvFindNextContour( scanner )) != 0 )
{
CvSeq *dst_contour = 0;
CvRect rect = ((CvContour*)src_contour)->rect;
// reject contours with too small perimeter
if( CV_IS_SEQ_HOLE( src_contour ) &&
rect.width*rect.height >= min_size )
{
int approx_level;
for( approx_level = min_approx_level;
approx_level <= max_approx_level;
approx_level++ )
{
dst_contour = cvApproxPoly( src_contour, sizeof( CvContour ),
storage1, CV_POLY_APPROX_DP,
(float)approx_level );
if( dst_contour->total == 4 )
break;
}
quandrangles += dst_contour->total == 4;
// reject non-quadrangles
if( dst_contour->total == 4 && cvCheckContourConvexity( dst_contour ))
{
CvPoint pt[4];
int i;
double d1, d2, p = cvContourPerimeter(dst_contour);
double dx, dy;
for( i = 0; i < 4; i++ )
pt[i] = *(CvPoint*)cvGetSeqElem( dst_contour, i );
dx = pt[0].x - pt[2].x;
dy = pt[0].y - pt[2].y;
d1 = sqrt( dx*dx + dy*dy );
dx = pt[1].x - pt[3].x;
dy = pt[1].y - pt[3].y;
d2 = sqrt( dx*dx + dy*dy );
if( d1 >= 0.25*p && d2 >= 0.25*p )
{
CvContourEx* parent = (CvContourEx*)(src_contour->v_prev);
parent->counter++;
if( !board || board->counter < parent->counter )
board = parent;
dst_contour->v_prev = (CvSeq*)parent;
cvSeqPush( root, &dst_contour );
}
}
}
}
// finish contour retrieving
cvEndFindContours( &scanner );
// iterate through all the "good" contours and store the corners.
//for( src_contour = root; src_contour != 0; src_contour = src_contour->h_next )
for( idx = 0; idx < root->total; idx++ )
{
src_contour = *(CvSeq**)cvGetSeqElem( root, idx );
int i, j, total = src_contour->total;
int keep_temp_count = temp_count;
if( src_contour->v_prev != (CvSeq*)board )
continue;
cvStartReadSeq( src_contour, &reader, 0 );
assert( total == 4 );
// choose the points of the current quadrangle that are close to
// some points of the other quadrangles
// (it can happen for splitted corners (due to dilation) of the
// checker board). Search only in other quadrangles! That's why
// keep_temp_count is used instead of temp_count
for( i = 0; i < total; i++ )
{
CvPoint pt;
CV_READ_SEQ_ELEM( pt, reader );
for( j = 0; j < keep_temp_count; j++ )
{
int dx = pt.x - pt_buffer[j].x;
int dy = pt.y - pt_buffer[j].y;
dx = abs( dx );
dy = abs( dy );
if( MAX( dx, dy ) < 8 )
break;
}
// if the close point has been found, store the middle point
// to the destination buffer
if( j < keep_temp_count )
{
if( found >= max_count )
{
result = CV_OUTOFMEM_ERR;
EXIT;
}
corners[found].x = (pt.x + pt_buffer[j].x) * 0.5f;
corners[found].y = (pt.y + pt_buffer[j].y) * 0.5f;
found++;
// remove found point from the temporary buffer
memmove( pt_buffer + j, pt_buffer + j + 1,
(temp_count - j - 1) * sizeof( CvPoint ));
temp_count--;
keep_temp_count--;
}
else
{
// else store point in the buffer
if( temp_count >= BUFFER_SIZE )
{
result = CV_OUTOFMEM_ERR;
EXIT;
}
pt_buffer[temp_count++] = pt;
}
}
}
result = CV_NOTDEFINED_ERR;
/*************** reorder found corners in the right order **************/
// ------ New processing of points --------
if( found == etalon_size.width * etalon_size.height )
{
// Copy all points to iPoints array for inner computation
// This is a prepare part. It calls ones
int etalon_points = found;
CvPoint cornerPoints[4];
CvPoint firstPoint = { 0, 0 };
CvContour hullcontour;
CvSeqBlock hullcontour_blk;
CvSeq *hullcontour2 = 0;
CvPoint start_pt;
CvPoint end_pt;
CvPoint botStart_pt = { 0, 0 };
CvPoint botEnd_pt = { 0, 0 };
int min_dist;
int test_dist;
int numRestPoints = etalon_points;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?