mirror of
https://github.com/opencv/opencv.git
synced 2024-12-04 00:39:11 +08:00
imgproc: approx C-API cleanup
This commit is contained in:
parent
c3fdb9769d
commit
3d88db02d4
@ -1,52 +0,0 @@
|
||||
/*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*/
|
||||
|
||||
#ifndef _CV_GEOM_H_
|
||||
#define _CV_GEOM_H_
|
||||
|
||||
#include "opencv2/core/core_c.h"
|
||||
|
||||
/* curvature: 0 - 1-curvature, 1 - k-cosine curvature. */
|
||||
CvSeq* icvApproximateChainTC89( CvChain* chain, int header_size, CvMemStorage* storage, int method );
|
||||
|
||||
#endif /*_IPCVGEOM_H_*/
|
||||
|
||||
/* End of file. */
|
@ -40,372 +40,6 @@
|
||||
//M*/
|
||||
#include "precomp.hpp"
|
||||
|
||||
/****************************************************************************************\
|
||||
* Chain Approximation *
|
||||
\****************************************************************************************/
|
||||
|
||||
typedef struct _CvPtInfo
|
||||
{
|
||||
CvPoint pt;
|
||||
int k; /* support region */
|
||||
int s; /* curvature value */
|
||||
struct _CvPtInfo *next;
|
||||
}
|
||||
_CvPtInfo;
|
||||
|
||||
static const CvPoint icvCodeDeltas[8] =
|
||||
{ {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1} };
|
||||
|
||||
/** Freeman chain reader state */
|
||||
typedef struct CvChainPtReader
|
||||
{
|
||||
CV_SEQ_READER_FIELDS()
|
||||
char code;
|
||||
CvPoint pt;
|
||||
schar deltas[8][2];
|
||||
}
|
||||
CvChainPtReader;
|
||||
|
||||
static void cvStartReadChainPoints( CvChain * chain, CvChainPtReader * reader )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( !chain || !reader )
|
||||
CV_Error( cv::Error::StsNullPtr, "" );
|
||||
|
||||
if( chain->elem_size != 1 || chain->header_size < (int)sizeof(CvChain))
|
||||
CV_Error( cv::Error::StsBadSize, "" );
|
||||
|
||||
cvStartReadSeq( (CvSeq *) chain, (CvSeqReader *) reader, 0 );
|
||||
|
||||
reader->pt = chain->origin;
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
reader->deltas[i][0] = (schar) icvCodeDeltas[i].x;
|
||||
reader->deltas[i][1] = (schar) icvCodeDeltas[i].y;
|
||||
}
|
||||
}
|
||||
|
||||
/* curvature: 0 - 1-curvature, 1 - k-cosine curvature. */
|
||||
CvSeq* icvApproximateChainTC89( CvChain* chain, int header_size,
|
||||
CvMemStorage* storage, int method )
|
||||
{
|
||||
static const int abs_diff[] = { 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1 };
|
||||
|
||||
cv::AutoBuffer<_CvPtInfo> buf(chain->total + 8);
|
||||
|
||||
_CvPtInfo temp;
|
||||
_CvPtInfo *array = buf.data(), *first = 0, *current = 0, *prev_current = 0;
|
||||
int i, j, i1, i2, s, len;
|
||||
int count = chain->total;
|
||||
|
||||
CvChainPtReader reader;
|
||||
CvSeqWriter writer;
|
||||
CvPoint pt = chain->origin;
|
||||
|
||||
CV_Assert( CV_IS_SEQ_CHAIN_CONTOUR( chain ));
|
||||
CV_Assert( header_size >= (int)sizeof(CvContour) );
|
||||
|
||||
cvStartWriteSeq( (chain->flags & ~CV_SEQ_ELTYPE_MASK) | CV_SEQ_ELTYPE_POINT,
|
||||
header_size, sizeof( CvPoint ), storage, &writer );
|
||||
|
||||
if( chain->total == 0 )
|
||||
{
|
||||
CV_WRITE_SEQ_ELEM( pt, writer );
|
||||
return cvEndWriteSeq( &writer );
|
||||
}
|
||||
|
||||
reader.code = 0;
|
||||
cvStartReadChainPoints( chain, &reader );
|
||||
|
||||
temp.next = 0;
|
||||
current = &temp;
|
||||
|
||||
/* Pass 0.
|
||||
Restores all the digital curve points from the chain code.
|
||||
Removes the points (from the resultant polygon)
|
||||
that have zero 1-curvature */
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
int prev_code = *reader.prev_elem;
|
||||
|
||||
reader.prev_elem = reader.ptr;
|
||||
CV_READ_CHAIN_POINT( pt, reader );
|
||||
|
||||
/* calc 1-curvature */
|
||||
s = abs_diff[reader.code - prev_code + 7];
|
||||
|
||||
if( method <= cv::CHAIN_APPROX_SIMPLE )
|
||||
{
|
||||
if( method == cv::CHAIN_APPROX_NONE || s != 0 )
|
||||
{
|
||||
CV_WRITE_SEQ_ELEM( pt, writer );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( s != 0 )
|
||||
current = current->next = array + i;
|
||||
array[i].s = s;
|
||||
array[i].pt = pt;
|
||||
}
|
||||
}
|
||||
|
||||
//CV_Assert( pt.x == chain->origin.x && pt.y == chain->origin.y );
|
||||
|
||||
if( method <= cv::CHAIN_APPROX_SIMPLE )
|
||||
return cvEndWriteSeq( &writer );
|
||||
|
||||
current->next = 0;
|
||||
|
||||
len = i;
|
||||
current = temp.next;
|
||||
|
||||
CV_Assert( current );
|
||||
|
||||
/* Pass 1.
|
||||
Determines support region for all the remained points */
|
||||
do
|
||||
{
|
||||
cv::Point2i pt0;
|
||||
int k, l = 0, d_num = 0;
|
||||
|
||||
i = (int)(current - array);
|
||||
pt0 = array[i].pt;
|
||||
|
||||
/* determine support region */
|
||||
for( k = 1;; k++ )
|
||||
{
|
||||
int lk, dk_num;
|
||||
int dx, dy;
|
||||
Cv32suf d;
|
||||
|
||||
CV_Assert( k <= len );
|
||||
|
||||
/* calc indices */
|
||||
i1 = i - k;
|
||||
i1 += i1 < 0 ? len : 0;
|
||||
i2 = i + k;
|
||||
i2 -= i2 >= len ? len : 0;
|
||||
|
||||
dx = array[i2].pt.x - array[i1].pt.x;
|
||||
dy = array[i2].pt.y - array[i1].pt.y;
|
||||
|
||||
/* distance between p_(i - k) and p_(i + k) */
|
||||
lk = dx * dx + dy * dy;
|
||||
|
||||
/* distance between p_i and the line (p_(i-k), p_(i+k)) */
|
||||
dk_num = (pt0.x - array[i1].pt.x) * dy - (pt0.y - array[i1].pt.y) * dx;
|
||||
d.f = (float) (((double) d_num) * lk - ((double) dk_num) * l);
|
||||
|
||||
if( k > 1 && (l >= lk || ((d_num > 0 && d.i <= 0) || (d_num < 0 && d.i >= 0))))
|
||||
break;
|
||||
|
||||
d_num = dk_num;
|
||||
l = lk;
|
||||
}
|
||||
|
||||
current->k = --k;
|
||||
|
||||
/* determine cosine curvature if it should be used */
|
||||
if( method == cv::CHAIN_APPROX_TC89_KCOS )
|
||||
{
|
||||
/* calc k-cosine curvature */
|
||||
for( j = k, s = 0; j > 0; j-- )
|
||||
{
|
||||
double temp_num;
|
||||
int dx1, dy1, dx2, dy2;
|
||||
Cv32suf sk;
|
||||
|
||||
i1 = i - j;
|
||||
i1 += i1 < 0 ? len : 0;
|
||||
i2 = i + j;
|
||||
i2 -= i2 >= len ? len : 0;
|
||||
|
||||
dx1 = array[i1].pt.x - pt0.x;
|
||||
dy1 = array[i1].pt.y - pt0.y;
|
||||
dx2 = array[i2].pt.x - pt0.x;
|
||||
dy2 = array[i2].pt.y - pt0.y;
|
||||
|
||||
if( (dx1 | dy1) == 0 || (dx2 | dy2) == 0 )
|
||||
break;
|
||||
|
||||
temp_num = dx1 * dx2 + dy1 * dy2;
|
||||
temp_num =
|
||||
(float) (temp_num /
|
||||
sqrt( ((double)dx1 * dx1 + (double)dy1 * dy1) *
|
||||
((double)dx2 * dx2 + (double)dy2 * dy2) ));
|
||||
sk.f = (float) (temp_num + 1.1);
|
||||
|
||||
CV_Assert( 0 <= sk.f && sk.f <= 2.2 );
|
||||
if( j < k && sk.i <= s )
|
||||
break;
|
||||
|
||||
s = sk.i;
|
||||
}
|
||||
current->s = s;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
while( current != 0 );
|
||||
|
||||
prev_current = &temp;
|
||||
current = temp.next;
|
||||
|
||||
/* Pass 2.
|
||||
Performs non-maxima suppression */
|
||||
do
|
||||
{
|
||||
int k2 = current->k >> 1;
|
||||
|
||||
s = current->s;
|
||||
i = (int)(current - array);
|
||||
|
||||
for( j = 1; j <= k2; j++ )
|
||||
{
|
||||
i2 = i - j;
|
||||
i2 += i2 < 0 ? len : 0;
|
||||
|
||||
if( array[i2].s > s )
|
||||
break;
|
||||
|
||||
i2 = i + j;
|
||||
i2 -= i2 >= len ? len : 0;
|
||||
|
||||
if( array[i2].s > s )
|
||||
break;
|
||||
}
|
||||
|
||||
if( j <= k2 ) /* exclude point */
|
||||
{
|
||||
prev_current->next = current->next;
|
||||
current->s = 0; /* "clear" point */
|
||||
}
|
||||
else
|
||||
prev_current = current;
|
||||
current = current->next;
|
||||
}
|
||||
while( current != 0 );
|
||||
|
||||
/* Pass 3.
|
||||
Removes non-dominant points with 1-length support region */
|
||||
current = temp.next;
|
||||
CV_Assert( current );
|
||||
prev_current = &temp;
|
||||
|
||||
do
|
||||
{
|
||||
if( current->k == 1 )
|
||||
{
|
||||
s = current->s;
|
||||
i = (int)(current - array);
|
||||
|
||||
i1 = i - 1;
|
||||
i1 += i1 < 0 ? len : 0;
|
||||
|
||||
i2 = i + 1;
|
||||
i2 -= i2 >= len ? len : 0;
|
||||
|
||||
if( s <= array[i1].s || s <= array[i2].s )
|
||||
{
|
||||
prev_current->next = current->next;
|
||||
current->s = 0;
|
||||
}
|
||||
else
|
||||
prev_current = current;
|
||||
}
|
||||
else
|
||||
prev_current = current;
|
||||
current = current->next;
|
||||
}
|
||||
while( current != 0 );
|
||||
|
||||
if( method == cv::CHAIN_APPROX_TC89_KCOS )
|
||||
goto copy_vect;
|
||||
|
||||
/* Pass 4.
|
||||
Cleans remained couples of points */
|
||||
CV_Assert( temp.next );
|
||||
|
||||
if( array[0].s != 0 && array[len - 1].s != 0 ) /* specific case */
|
||||
{
|
||||
for( i1 = 1; i1 < len && array[i1].s != 0; i1++ )
|
||||
{
|
||||
array[i1 - 1].s = 0;
|
||||
}
|
||||
if( i1 == len )
|
||||
goto copy_vect; /* all points survived */
|
||||
i1--;
|
||||
|
||||
for( i2 = len - 2; i2 > 0 && array[i2].s != 0; i2-- )
|
||||
{
|
||||
array[i2].next = 0;
|
||||
array[i2 + 1].s = 0;
|
||||
}
|
||||
i2++;
|
||||
|
||||
if( i1 == 0 && i2 == len - 1 ) /* only two points */
|
||||
{
|
||||
i1 = (int)(array[0].next - array);
|
||||
array[len] = array[0]; /* move to the end */
|
||||
array[len].next = 0;
|
||||
array[len - 1].next = array + len;
|
||||
}
|
||||
temp.next = array + i1;
|
||||
}
|
||||
|
||||
current = temp.next;
|
||||
first = prev_current = &temp;
|
||||
count = 1;
|
||||
|
||||
/* do last pass */
|
||||
do
|
||||
{
|
||||
if( current->next == 0 || current->next - current != 1 )
|
||||
{
|
||||
if( count >= 2 )
|
||||
{
|
||||
if( count == 2 )
|
||||
{
|
||||
int s1 = prev_current->s;
|
||||
int s2 = current->s;
|
||||
|
||||
if( s1 > s2 || (s1 == s2 && prev_current->k <= current->k) )
|
||||
/* remove second */
|
||||
prev_current->next = current->next;
|
||||
else
|
||||
/* remove first */
|
||||
first->next = current;
|
||||
}
|
||||
else
|
||||
first->next->next = current;
|
||||
}
|
||||
first = current;
|
||||
count = 1;
|
||||
}
|
||||
else
|
||||
count++;
|
||||
prev_current = current;
|
||||
current = current->next;
|
||||
}
|
||||
while( current != 0 );
|
||||
|
||||
copy_vect:
|
||||
|
||||
// gather points
|
||||
current = temp.next;
|
||||
CV_Assert( current );
|
||||
|
||||
do
|
||||
{
|
||||
CV_WRITE_SEQ_ELEM( current->pt, writer );
|
||||
current = current->next;
|
||||
}
|
||||
while( current != 0 );
|
||||
|
||||
return cvEndWriteSeq( &writer );
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
* Polygonal Approximation *
|
||||
\****************************************************************************************/
|
||||
|
@ -100,21 +100,12 @@ static inline IppiInterpolationType ippiGetInterpolation(int inter)
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "_geom.h"
|
||||
#include "opencv2/core/types_c.h"
|
||||
#include "opencv2/core/core_c.h"
|
||||
#include "filterengine.hpp"
|
||||
|
||||
#include "opencv2/core/sse_utils.hpp"
|
||||
|
||||
inline bool isStorageOrMat(void * arr)
|
||||
{
|
||||
if (CV_IS_STORAGE( arr ))
|
||||
return true;
|
||||
else if (CV_IS_MAT( arr ))
|
||||
return false;
|
||||
CV_Error( cv::Error::StsBadArg, "Destination is not CvMemStorage* nor CvMat*" );
|
||||
}
|
||||
|
||||
|
||||
namespace cv {
|
||||
|
||||
CV_EXPORTS
|
||||
|
Loading…
Reference in New Issue
Block a user