cvCanny函数中, 高低阈值自适应计算方法

        OpenCV的Canny算法实现函数的参数中, 需要输入高低阈值, 如果高低阈值输入不对, 通常等不到理想的边缘效果.
网上有人仿Matlab, 实现了自适应高低阈值, 代码如下:

void HYAdaptiveFindThreshold(CvMat *dx, CvMat *dy, double *low, double *high)
{
	CvSize size = cvGetSize(dx);
	IplImage* imge = cvCreateImage(size, IPL_DEPTH_32F, 1);
	
	// 计算边缘的强度, 并存于图像中
	int i, j;
	short* _dx = 0;
	short* _dy = 0;
	float* _image = 0;
	float maxv = 0;
	for(i = 0; i < size.height; ++i)
	{
		_dx = (short*)(dx->data.ptr + dx->step * i);
		_dy = (short*)(dy->data.ptr + dy->step * i);
		_image = (float *)(imge->imageData + imge->widthStep * i);
		for(j = 0; j < size.width; ++j)
		{
			_image[j] = (float)(abs(_dx[j]) + abs(_dy[j]));
			maxv = maxv < _image[j] ? _image[j]: maxv;
		}
	}
	
	int hist_size = 255;
	float range_0[] = {0, 256};
	float* ranges[] = {range_0};

	// 计算直方图
	range_0[1] = maxv;	// 最大值
	hist_size = (int)(hist_size > maxv ? maxv : hist_size);
	
	CvHistogram* hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);	
	cvCalcHist(&imge, hist, 0, 0);
	
	double dPercentOfPixelsNotEdges = 0.97;
	int total = (int)(size.height * size.width * dPercentOfPixelsNotEdges);
	float sum=0;
	int icount = hist->mat.dim[0].size;

	float *h = (float*)cvPtr1D(hist->bins, 0);
	for(i = 0; i < icount; ++i)
	{
		sum += h[i];
		if(sum > total)
			break; 
	}
	// 计算高低门限
	*high = (i + 1) * maxv / hist_size ;
	*low = *high * 0.4 ;
	cvReleaseImage(&imge);
	cvReleaseHist(&hist);
}
    至于为什么这样来求出高低阈值, 自己也不是很理解. 其中CvMat *dx和CvMat *dy分别是用两个Sobel算子计算水平和垂直两个方向的梯度强度得到的.


看看cvCanny函数的代码:
......
	//梯度  
	dx = cvCreateMat( size.height, size.width, CV_16SC1 );  
	dy = cvCreateMat( size.height, size.width, CV_16SC1 );  
	cvSobel( src, dx, 1, 0, aperture_size );  
	cvSobel( src, dy, 0, 1, aperture_size );  

	// 我们可以在这里自适应计算高低阈值
	if(low_thresh == -1 && high_thresh == -1)   
	{   
		HYAdaptiveFindThreshold(dx, dy, &low_thresh, &high_thresh);   
	}
......
      重编一下OpenCV的代码, cvCanny函数的两个高低阈值就可以实现自适应了.
我们也可以自己求出用Sobel算子求出水平和垂直方向的强度, 然后求出高低阈值, 然后再调用cvCanny, 但是这样子就重复了Sobel算子的计算了.


参考:
http://read.pudn.com/downloads171/sourcecode/graph/texture_mapping/791537/StraightLineFinder/StraightLineFinder/StraightLineFinder.cpp__.htm
http://blog.chinaunix.net/uid-14231482-id-2826875.html
http://blog.csdn.net/sunlylorn/article/details/8015825
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值