📄 canny.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"
int follow(int i, int j, float low, CvSize roi, uchar* dst, int dstStep, float* mag)
{
int pixel_counter = 1;
int k,l; /* counters */
int i_plus_1,i_minus_1,j_plus_1,j_minus_1;
long index,kindex;
char break_flag;
i_plus_1= i + 1;
i_minus_1= i - 1;
j_plus_1=j+1;
j_minus_1=j-1;
index = i * dstStep + j;
if (j_plus_1>=roi.width) j_plus_1=roi.width-1;
if (j_minus_1<0) j_minus_1=0;
if (i_plus_1>=roi.height) i_plus_1=roi.height-1;
if (i_minus_1<0) i_minus_1=0;
if (!dst[index])
{
/* current point must be added to the list of tracked points */
dst[index]=255;
/* now we can check immediately adjacent points to see if
they too could be added to the track */
break_flag=0;
for (k=i_minus_1;k<=i_plus_1;k++)
{
for(l=j_minus_1;l<=j_plus_1;l++)
{
kindex = k * roi.width + l;
if (!(l==j && k==i) && (mag[kindex]>low ))
{
pixel_counter+=follow(k,l,low, roi, dst, dstStep, mag);
}
}
}
return(pixel_counter);
}
else return(0);
}
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: atsCannyStatistics
// Purpose:
// perform canny edge detection with statistic
// Context:
// Parameters:
// zero_mag - number of elements with zero magnitude
// under_low - number of elements under low threshold
// above_high - number of elements above high threshold
// edges_in_nms - above low threshold and has local maxima
// in_edges - in detected edges
// components - number of 8-connected components on edge image
// Returns:
// Number of nonequal elements
// Notes:
//F*/
int atsCannyStatistics(uchar* src,
CvSize roi,
int srcStep,
uchar* dst,
int dstStep,
int Sobord,
float lowThreshold,
float highThreshold,
int* zero_mag,
int* under_low,
int* above_high,
int* edges_in_nms,
int* components,
int* in_edges)
{
float pi = 3.1415926535f;
int i,j;
IplImage* _dX = cvCreateImage( roi, IPL_DEPTH_16S, 1 );
IplImage* _dY = cvCreateImage( roi, IPL_DEPTH_16S, 1 );
short* dX = (short*)(_dX->imageData);
short* dY = (short*)(_dY->imageData);
int stepx = _dX->widthStep/2;
int stepy = _dY->widthStep/2;
IplImage* img = cvCreateImageHeader( roi, IPL_DEPTH_8U, 1 );
float* mag = (float*)icvAlloc(roi.width * roi.height * 4);
float* nms = (float*)icvAlloc(roi.width * roi.height * 4);
memset(dst, 0, roi.height*dstStep);
if(zero_mag) (*zero_mag)=0;
if(under_low) (*under_low)=0;
if(above_high) (*above_high)=0;
if(edges_in_nms) (*edges_in_nms)=0;
if(components) (*components)=0;
if(in_edges) (*in_edges)=0;
cvSetImageData( img, src, srcStep );
/* smooth and difference */
cvSobel( img, _dX, 1, 0, Sobord );
cvSobel( img, _dY, 0, 1, Sobord );
/* estimate magnitude and angle */
for ( i = 0; i < roi.height; i++ )
{
for ( j = 0; j < roi.width; j++ )
{
mag[i*roi.width+j] = (float)(abs(dX[i*stepx+j])+abs(dY[i*stepy+j]));
if ( (!mag[i*roi.width+j]) && zero_mag)
(*zero_mag)++;
if ( (mag[i*roi.width+j] <= lowThreshold) && under_low)
(*under_low)++;
if ( mag[i*roi.width+j] > highThreshold && above_high) (*above_high)++;
}
}
/* nonmaxima suppression */
for ( i = 0; i < roi.height; i++ )
{
for ( j = 0; j < roi.width; j++ )
{
int i1=0,i2=0,j1=0,j2=0;
float tg = (float)dY[i*roi.width+j]/(float)dX[i*roi.width+j];
float max = 0;
if ( (tg < tan( pi/8 )) && (tg > tan( -pi/8 ) ))
{
i1 = i2 = i; j1 = j + 1; j2 = j - 1;
}
if ( (tg <= tan( pi/4+pi/8 )) && (tg >= tan( pi/8 )))
{
i1 = i + 1; i2 = i - 1; j1 = j + 1; j2 = j - 1;
}
if ((tg <= tan( -pi/8 )) && (tg >= tan( -pi/4-pi/8 )))
{
i1 = i - 1; i2 = i + 1; j1 = j + 1; j2 = j - 1;
}
if ((tg > tan( pi/2 - pi/8 )) || (tg < tan( -pi/4-pi/8 ))
|| (dX[i*roi.width+j]==0) )
{
j1 = j2 = j; i1 = i + 1; i2 = i - 1;
}
if ( i1>=0 && i1 < roi.height && j1>=0 && j1 < roi.width )
{
max = MAX( mag[i*roi.width+j], mag[i1*roi.width+j1] );
}
if ( i2>=0 && i2 < roi.height && j2>=0 && j2 < roi.width )
{
max = MAX( max, mag[i2*roi.width+j2] );
}
if ( mag[i * roi.width + j] >= max )
{
nms[i * roi.width + j] = mag[i * roi.width + j];
if (nms[i * roi.width + j]>lowThreshold && edges_in_nms)
{
(*edges_in_nms)++;
}
}
else
nms[i * roi.width + j] = 0;
}
}
/* hysteresis threshold */
for ( i = 0; i < roi.height; i++ )
{
for ( j = 0; j < roi.width; j++ )
{
if ((nms[i*roi.width+j] > highThreshold) && ( !dst[i*dstStep+j] ))
{
int a = follow( i,j, lowThreshold, roi, dst, dstStep, nms);
if (components) (*components)++;
if (in_edges) (*in_edges)+=a;
}
}
}
cvReleaseImage(&_dX);
cvReleaseImage(&_dY);
cvReleaseImageHeader(&img);
icvFree(&nms);
icvFree(&mag);
return (int)CV_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -