16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M/////////////////////////////////////////////////////////////////////////////////////// 26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// By downloading, copying, installing or using the software you agree to this license. 66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// If you do not agree to this license, do not download, install, 76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// copy or use the software. 86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Intel License Agreement 116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// For Open Source Computer Vision Library 126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved. 146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners. 156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification, 176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met: 186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * Redistribution's of source code must retain the above copyright notice, 206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// this list of conditions and the following disclaimer. 216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * Redistribution's in binary form must reproduce the above copyright notice, 236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// this list of conditions and the following disclaimer in the documentation 246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and/or other materials provided with the distribution. 256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * The name of Intel Corporation may not be used to endorse or promote products 276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// derived from this software without specific prior written permission. 286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and 306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied 316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed. 326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct, 336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages 346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services; 356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused 366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability, 376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of 386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage. 396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/ 416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cv.h" 426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_DIST_SHIFT 16 446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_INIT_DIST0 (INT_MAX >> 2) 456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus 476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvInitTopBottom( int* temp, int tempstep, CvSize size, int border ) 486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j; 506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < border; i++ ) 516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* ttop = (int*)(temp + i*tempstep); 536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* tbottom = (int*)(temp + (size.height + border*2 - i - 1)*tempstep); 546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < size.width + border*2; j++ ) 566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ttop[j] = ICV_INIT_DIST0; 586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tbottom[j] = ICV_INIT_DIST0; 596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_OK; 636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL 676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDistanceTransform_3x3_C1R( const uchar* src, int srcstep, int* temp, 686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int step, float* dist, int dststep, CvSize size, const float* metrics ) 696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int BORDER = 1; 716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j; 726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int HV_DIST = CV_FLT_TO_FIX( metrics[0], ICV_DIST_SHIFT ); 736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int DIAG_DIST = CV_FLT_TO_FIX( metrics[1], ICV_DIST_SHIFT ); 746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float scale = 1.f/(1 << ICV_DIST_SHIFT); 756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn srcstep /= sizeof(src[0]); 776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn step /= sizeof(temp[0]); 786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dststep /= sizeof(dist[0]); 796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvInitTopBottom( temp, step, size, BORDER ); 816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // forward pass 836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < size.height; i++ ) 846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const uchar* s = src + i*srcstep; 866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER; 876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < BORDER; j++ ) 896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp[-j-1] = tmp[size.width + j] = ICV_INIT_DIST0; 906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < size.width; j++ ) 926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !s[j] ) 946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp[j] = 0; 956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t0 = tmp[j-step-1] + DIAG_DIST; 986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t = tmp[j-step] + HV_DIST; 996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step+1] + DIAG_DIST; 1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-1] + HV_DIST; 1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp[j] = t0; 1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // backward pass 1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = size.height - 1; i >= 0; i-- ) 1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* d = (float*)(dist + i*dststep); 1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER; 1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = size.width - 1; j >= 0; j-- ) 1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t0 = tmp[j]; 1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > HV_DIST ) 1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t = tmp[j+step+1] + DIAG_DIST; 1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step] + HV_DIST; 1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step-1] + DIAG_DIST; 1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+1] + HV_DIST; 1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp[j] = t0; 1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn d[j] = (float)(t0 * scale); 1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_OK; 1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL 1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDistanceTransform_5x5_C1R( const uchar* src, int srcstep, int* temp, 1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int step, float* dist, int dststep, CvSize size, const float* metrics ) 1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int BORDER = 2; 1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j; 1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int HV_DIST = CV_FLT_TO_FIX( metrics[0], ICV_DIST_SHIFT ); 1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int DIAG_DIST = CV_FLT_TO_FIX( metrics[1], ICV_DIST_SHIFT ); 1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int LONG_DIST = CV_FLT_TO_FIX( metrics[2], ICV_DIST_SHIFT ); 1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float scale = 1.f/(1 << ICV_DIST_SHIFT); 1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn srcstep /= sizeof(src[0]); 1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn step /= sizeof(temp[0]); 1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dststep /= sizeof(dist[0]); 1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvInitTopBottom( temp, step, size, BORDER ); 1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // forward pass 1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < size.height; i++ ) 1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const uchar* s = src + i*srcstep; 1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER; 1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < BORDER; j++ ) 1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp[-j-1] = tmp[size.width + j] = ICV_INIT_DIST0; 1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < size.width; j++ ) 1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !s[j] ) 1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp[j] = 0; 1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t0 = tmp[j-step*2-1] + LONG_DIST; 1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t = tmp[j-step*2+1] + LONG_DIST; 1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step-2] + LONG_DIST; 1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step-1] + DIAG_DIST; 1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step] + HV_DIST; 1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step+1] + DIAG_DIST; 1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step+2] + LONG_DIST; 1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-1] + HV_DIST; 1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp[j] = t0; 1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // backward pass 1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = size.height - 1; i >= 0; i-- ) 1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* d = (float*)(dist + i*dststep); 1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER; 1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = size.width - 1; j >= 0; j-- ) 1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t0 = tmp[j]; 1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > HV_DIST ) 2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t = tmp[j+step*2+1] + LONG_DIST; 2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step*2-1] + LONG_DIST; 2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step+2] + LONG_DIST; 2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step+1] + DIAG_DIST; 2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step] + HV_DIST; 2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step-1] + DIAG_DIST; 2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step-2] + LONG_DIST; 2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+1] + HV_DIST; 2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) t0 = t; 2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp[j] = t0; 2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn d[j] = (float)(t0 * scale); 2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_OK; 2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL 2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDistanceTransformEx_5x5_C1R( const uchar* src, int srcstep, int* temp, 2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int step, float* dist, int dststep, int* labels, int lstep, 2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize size, const float* metrics ) 2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int BORDER = 2; 2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j; 2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int HV_DIST = CV_FLT_TO_FIX( metrics[0], ICV_DIST_SHIFT ); 2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int DIAG_DIST = CV_FLT_TO_FIX( metrics[1], ICV_DIST_SHIFT ); 2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int LONG_DIST = CV_FLT_TO_FIX( metrics[2], ICV_DIST_SHIFT ); 2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float scale = 1.f/(1 << ICV_DIST_SHIFT); 2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn srcstep /= sizeof(src[0]); 2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn step /= sizeof(temp[0]); 2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dststep /= sizeof(dist[0]); 2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn lstep /= sizeof(labels[0]); 2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvInitTopBottom( temp, step, size, BORDER ); 2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // forward pass 2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < size.height; i++ ) 2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const uchar* s = src + i*srcstep; 2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER; 2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* lls = (int*)(labels + i*lstep); 2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < BORDER; j++ ) 2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp[-j-1] = tmp[size.width + j] = ICV_INIT_DIST0; 2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < size.width; j++ ) 2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !s[j] ) 2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp[j] = 0; 2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //assert( lls[j] != 0 ); 2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t0 = ICV_INIT_DIST0, t; 2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int l0 = 0; 2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step*2-1] + LONG_DIST; 2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j-lstep*2-1]; 2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step*2+1] + LONG_DIST; 2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j-lstep*2+1]; 2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step-2] + LONG_DIST; 2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j-lstep-2]; 2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step-1] + DIAG_DIST; 2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j-lstep-1]; 2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step] + HV_DIST; 2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j-lstep]; 2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step+1] + DIAG_DIST; 3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j-lstep+1]; 3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-step+2] + LONG_DIST; 3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j-lstep+2]; 3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j-1] + HV_DIST; 3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j-1]; 3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp[j] = t0; 3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn lls[j] = l0; 3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // backward pass 3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = size.height - 1; i >= 0; i-- ) 3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* d = (float*)(dist + i*dststep); 3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* tmp = (int*)(temp + (i+BORDER)*step) + BORDER; 3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* lls = (int*)(labels + i*lstep); 3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = size.width - 1; j >= 0; j-- ) 3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t0 = tmp[j]; 3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int l0 = lls[j]; 3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > HV_DIST ) 3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t = tmp[j+step*2+1] + LONG_DIST; 3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j+lstep*2+1]; 3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step*2-1] + LONG_DIST; 3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j+lstep*2-1]; 3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step+2] + LONG_DIST; 3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j+lstep+2]; 3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step+1] + DIAG_DIST; 3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j+lstep+1]; 3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step] + HV_DIST; 3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j+lstep]; 3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step-1] + DIAG_DIST; 3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j+lstep-1]; 3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+step-2] + LONG_DIST; 3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j+lstep-2]; 3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t = tmp[j+1] + HV_DIST; 3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( t0 > t ) 3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = t; 3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l0 = lls[j+1]; 3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp[j] = t0; 3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn lls[j] = l0; 3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn d[j] = (float)(t0 * scale); 3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_OK; 3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus 3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvGetDistanceTransformMask( int maskType, float *metrics ) 3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !metrics ) 4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NULLPTR_ERR; 4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn switch (maskType) 4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 30: 4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[0] = 1.0f; 4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[1] = 1.0f; 4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 31: 4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[0] = 1.0f; 4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[1] = 2.0f; 4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 32: 4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[0] = 0.955f; 4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[1] = 1.3693f; 4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 50: 4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[0] = 1.0f; 4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[1] = 1.0f; 4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[2] = 2.0f; 4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 51: 4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[0] = 1.0f; 4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[1] = 2.0f; 4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[2] = 3.0f; 4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn case 52: 4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[0] = 1.0f; 4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[1] = 1.4f; 4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn metrics[2] = 2.1969f; 4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn default: 4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_BADRANGE_ERR; 4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_OK; 4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void 4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvTrueDistTrans( const CvMat* src, CvMat* dst ) 4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat* buffer = 0; 4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvDistTransform2" ); 4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, m, n; 4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int sstep, dstep; 4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float inf = 1e6f; 4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int thread_count = cvGetNumThreads(); 4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int pass1_sz, pass2_sz; 4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_ARE_SIZES_EQ( src, dst )) 4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnmatchedSizes, "" ); 4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_MAT_TYPE(src->type) != CV_8UC1 || 4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MAT_TYPE(dst->type) != CV_32FC1 ) 4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnsupportedFormat, 4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "The input image must have 8uC1 type and the output one must have 32fC1 type" ); 4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m = src->rows; 4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn n = src->cols; 4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // (see stage 1 below): 4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // sqr_tab: 2*m, sat_tab: 3*m + 1, d: m*thread_count, 4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pass1_sz = src->rows*(5 + thread_count) + 1; 4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // (see stage 2): 4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // sqr_tab & inv_tab: n each; f & v: n*thread_count each; z: (n+1)*thread_count 4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pass2_sz = src->cols*(2 + thread_count*3) + thread_count; 4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( buffer = cvCreateMat( 1, MAX(pass1_sz, pass2_sz), CV_32FC1 )); 4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sstep = src->step; 4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dstep = dst->step / sizeof(float); 4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // stage 1: compute 1d distance transform of each column 4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* sqr_tab = buffer->data.fl; 4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* sat_tab = (int*)(sqr_tab + m*2); 4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const int shift = m*2; 4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < m; i++ ) 4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sqr_tab[i] = (float)(i*i); 4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = m; i < m*2; i++ ) 4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sqr_tab[i] = inf; 4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < shift; i++ ) 4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sat_tab[i] = 0; 4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ; i <= m*3; i++ ) 4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sat_tab[i] = i - shift; 4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef _OPENMP 4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn #pragma omp parallel for num_threads(thread_count) 4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif 4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < n; i++ ) 5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const uchar* sptr = src->data.ptr + i + (m-1)*sstep; 5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* dptr = dst->data.fl + i; 5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* d = (int*)(sat_tab + m*3+1+m*cvGetThreadNum()); 5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int j, dist = m-1; 5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = m-1; j >= 0; j--, sptr -= sstep ) 5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dist = (dist + 1) & (sptr[0] == 0 ? 0 : -1); 5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn d[j] = dist; 5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dist = m-1; 5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < m; j++, dptr += dstep ) 5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dist = dist + 1 - sat_tab[dist + 1 - d[j] + shift]; 5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn d[j] = dist; 5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dptr[0] = sqr_tab[dist]; 5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // stage 2: compute modified distance transform for each row 5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* inv_tab = buffer->data.fl; 5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* sqr_tab = inv_tab + n; 5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn inv_tab[0] = sqr_tab[0] = 0.f; 5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 1; i < n; i++ ) 5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn inv_tab[i] = (float)(0.5/i); 5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sqr_tab[i] = (float)(i*i); 5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef _OPENMP 5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn #pragma omp parallel for num_threads(thread_count) schedule(dynamic) 5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif 5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < m; i++ ) 5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* d = (float*)(dst->data.ptr + i*dst->step); 5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* f = sqr_tab + n + (n*3+1)*cvGetThreadNum(); 5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* z = f + n; 5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* v = (int*)(z + n + 1); 5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int p, q, k; 5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn v[0] = 0; 5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn z[0] = -inf; 5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn z[1] = inf; 5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn f[0] = d[0]; 5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( q = 1, k = 0; q < n; q++ ) 5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float fq = d[q]; 5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn f[q] = fq; 5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for(;;k--) 5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p = v[k]; 5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float s = (fq + sqr_tab[q] - d[p] - sqr_tab[p])*inv_tab[q - p]; 5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( s > z[k] ) 5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn k++; 5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn v[k] = q; 5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn z[k] = s; 5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn z[k+1] = inf; 5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn break; 5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( q = 0, k = 0; q < n; q++ ) 5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn while( z[k+1] < q ) 5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn k++; 5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p = v[k]; 5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn d[q] = sqr_tab[abs(q - p)] + f[p]; 5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvPow( dst, dst, 0.5 ); 5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &buffer ); 5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*********************************** IPP functions *********************************/ 5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDistanceTransform_3x3_8u32f_C1R_t icvDistanceTransform_3x3_8u32f_C1R_p = 0; 5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDistanceTransform_5x5_8u32f_C1R_t icvDistanceTransform_5x5_8u32f_C1R_p = 0; 5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDistanceTransform_3x3_8u_C1IR_t icvDistanceTransform_3x3_8u_C1IR_p = 0; 5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDistanceTransform_3x3_8u_C1R_t icvDistanceTransform_3x3_8u_C1R_p = 0; 5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvIPPDistTransFunc)( const uchar* src, int srcstep, 5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn void* dst, int dststep, 5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize size, const void* metrics ); 5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvIPPDistTransFunc2)( uchar* src, int srcstep, 6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize size, const int* metrics ); 6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/***********************************************************************************/ 6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvDistTransFunc)( const uchar* src, int srcstep, 6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* temp, int tempstep, 6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* dst, int dststep, 6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize size, const float* metrics ); 6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\ 6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn User-contributed code: 6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn Non-inplace and Inplace 8u->8u Distance Transform for CityBlock (a.k.a. L1) metric 6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (C) 2006 by Jay Stavinzky. 6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/ 6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//BEGIN ATS ADDITION 6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 8-bit grayscale distance transform function */ 6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void 6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDistanceATS_L1_8u( const CvMat* src, CvMat* dst ) 6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvDistanceATS" ); 6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int width = src->cols, height = src->rows; 6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int a; 6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar lut[256]; 6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int x, y; 6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const uchar *sbase = src->data.ptr; 6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn uchar *dbase = dst->data.ptr; 6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int srcstep = src->step; 6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int dststep = dst->step; 6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ASSERT( CV_IS_MASK_ARR( src ) && CV_MAT_TYPE( dst->type ) == CV_8UC1 ); 6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ASSERT( CV_ARE_SIZES_EQ( src, dst )); 6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ////////////////////// forward scan //////////////////////// 6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = 0; x < 256; x++ ) 6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn lut[x] = CV_CAST_8U(x+1); 6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //init first pixel to max (we're going to be skipping it) 6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dbase[0] = (uchar)(sbase[0] == 0 ? 0 : 255); 6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //first row (scan west only, skip first pixel) 6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = 1; x < width; x++ ) 6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dbase[x] = (uchar)(sbase[x] == 0 ? 0 : lut[dbase[x-1]]); 6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( y = 1; y < height; y++ ) 6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sbase += srcstep; 6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dbase += dststep; 6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //for left edge, scan north only 6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a = sbase[0] == 0 ? 0 : lut[dbase[-dststep]]; 6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dbase[0] = (uchar)a; 6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = 1; x < width; x++ ) 6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a = sbase[x] == 0 ? 0 : lut[MIN(a, dbase[x - dststep])]; 6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dbase[x] = (uchar)a; 6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ////////////////////// backward scan /////////////////////// 6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a = dbase[width-1]; 6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // do last row east pixel scan here (skip bottom right pixel) 6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = width - 2; x >= 0; x-- ) 6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a = lut[a]; 6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dbase[x] = (uchar)(CV_CALC_MIN_8U(a, dbase[x])); 6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // right edge is the only error case 6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( y = height - 2; y >= 0; y-- ) 6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dbase -= dststep; 6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // do right edge 6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a = lut[dbase[width-1+dststep]]; 6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dbase[width-1] = (uchar)(MIN(a, dbase[width-1])); 6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( x = width - 2; x >= 0; x-- ) 6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int b = dbase[x+dststep]; 6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a = lut[MIN(a, b)]; 6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dbase[x] = (uchar)(MIN(a, dbase[x])); 6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//END ATS ADDITION 6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Wrapper function for distance transform group */ 7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvDistTransform( const void* srcarr, void* dstarr, 7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int distType, int maskSize, 7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn const float *mask, 7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn void* labelsarr ) 7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat* temp = 0; 7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat* src_copy = 0; 7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMemStorage* st = 0; 7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvDistTransform" ); 7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float _mask[5] = {0}; 7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int _imask[3]; 7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat srcstub, *src = (CvMat*)srcarr; 7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat dststub, *dst = (CvMat*)dstarr; 7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMat lstub, *labels = (CvMat*)labelsarr; 7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize size; 7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvIPPDistTransFunc ipp_func = 0; 7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvIPPDistTransFunc2 ipp_inp_func = 0; 7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( src = cvGetMat( src, &srcstub )); 7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( dst = cvGetMat( dst, &dststub )); 7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_IS_MASK_ARR( src ) || (CV_MAT_TYPE( dst->type ) != CV_32FC1 && 7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (CV_MAT_TYPE(dst->type) != CV_8UC1 || distType != CV_DIST_L1 || labels)) ) 7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnsupportedFormat, 7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "source image must be 8uC1 and the distance map must be 32fC1 " 7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "(or 8uC1 in case of simple L1 distance transform)" ); 7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_ARE_SIZES_EQ( src, dst )) 7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnmatchedSizes, "the source and the destination images must be of the same size" ); 7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( maskSize != CV_DIST_MASK_3 && maskSize != CV_DIST_MASK_5 && maskSize != CV_DIST_MASK_PRECISE ) 7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsBadSize, "Mask size should be 3 or 5 or 0 (presize)" ); 7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( distType == CV_DIST_C || distType == CV_DIST_L1 ) 7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn maskSize = !labels ? CV_DIST_MASK_3 : CV_DIST_MASK_5; 7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( distType == CV_DIST_L2 && labels ) 7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn maskSize = CV_DIST_MASK_5; 7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( maskSize == CV_DIST_MASK_PRECISE ) 7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvTrueDistTrans( src, dst )); 7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn EXIT; 7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( labels ) 7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( labels = cvGetMat( labels, &lstub )); 7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_MAT_TYPE( labels->type ) != CV_32SC1 ) 7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnsupportedFormat, "the output array of labels must be 32sC1" ); 7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !CV_ARE_SIZES_EQ( labels, dst )) 7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsUnmatchedSizes, "the array of labels has a different size" ); 7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( maskSize == CV_DIST_MASK_3 ) 7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNotImplemented, 7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn "3x3 mask can not be used for \"labeled\" distance transform. Use 5x5 mask" ); 7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( distType == CV_DIST_C || distType == CV_DIST_L1 || distType == CV_DIST_L2 ) 7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvGetDistanceTransformMask( (distType == CV_DIST_C ? 0 : 7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn distType == CV_DIST_L1 ? 1 : 2) + maskSize*10, _mask ); 7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( distType == CV_DIST_USER ) 7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !mask ) 7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_StsNullPtr, "" ); 7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( _mask, mask, (maskSize/2 + 1)*sizeof(float)); 7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !labels ) 7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( CV_MAT_TYPE(dst->type) == CV_32FC1 ) 7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ipp_func = (CvIPPDistTransFunc)(maskSize == CV_DIST_MASK_3 ? 7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvDistanceTransform_3x3_8u32f_C1R_p : icvDistanceTransform_5x5_8u32f_C1R_p); 7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( src->data.ptr != dst->data.ptr ) 7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ipp_func = (CvIPPDistTransFunc)icvDistanceTransform_3x3_8u_C1R_p; 7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ipp_inp_func = icvDistanceTransform_3x3_8u_C1IR_p; 7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn size = cvGetMatSize(src); 7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (ipp_func || ipp_inp_func) && src->cols >= 4 && src->rows >= 2 ) 7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _imask[0] = cvRound(_mask[0]); 7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _imask[1] = cvRound(_mask[1]); 7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _imask[2] = cvRound(_mask[2]); 7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( ipp_func ) 7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( ipp_func( src->data.ptr, src->step, 7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst->data.fl, dst->step, size, 8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_MAT_TYPE(dst->type) == CV_8UC1 ? 8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (void*)_imask : (void*)_mask )); 8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( ipp_inp_func( src->data.ptr, src->step, size, _imask )); 8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( CV_MAT_TYPE(dst->type) == CV_8UC1 ) 8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( icvDistanceATS_L1_8u( src, dst )); 8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int border = maskSize == CV_DIST_MASK_3 ? 1 : 2; 8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( temp = cvCreateMat( size.height + border*2, size.width + border*2, CV_32SC1 )); 8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !labels ) 8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvDistTransFunc func = maskSize == CV_DIST_MASK_3 ? 8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvDistanceTransform_3x3_C1R : 8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvDistanceTransform_5x5_C1R; 8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn func( src->data.ptr, src->step, temp->data.i, temp->step, 8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst->data.fl, dst->step, size, _mask ); 8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSeq *contours = 0; 8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvPoint top_left = {0,0}, bottom_right = {size.width-1,size.height-1}; 8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int label; 8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( st = cvCreateMemStorage() ); 8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_CALL( src_copy = cvCreateMat( size.height, size.width, src->type )); 8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvCmpS( src, 0, src_copy, CV_CMP_EQ ); 8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFindContours( src_copy, st, &contours, sizeof(CvContour), 8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); 8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvZero( labels ); 8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( label = 1; contours != 0; contours = contours->h_next, label++ ) 8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvScalar area_color = cvScalarAll(label); 8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvDrawContours( labels, contours, area_color, area_color, -255, -1, 8 ); 8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvCopy( src, src_copy ); 8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvRectangle( src_copy, top_left, bottom_right, cvScalarAll(255), 1, 8 ); 8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvDistanceTransformEx_5x5_C1R( src_copy->data.ptr, src_copy->step, temp->data.i, temp->step, 8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dst->data.fl, dst->step, labels->data.i, labels->step, size, _mask ); 8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &temp ); 8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMat( &src_copy ); 8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvReleaseMemStorage( &st ); 8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */ 860