关于二值化函数cvAdaptiveThreshold和cvThreshold以及OSTU

(1)函数cvAdaptiveThreshold的确可以将灰度图像二值化,但它的主要功能应该是边缘提取,并且参数param1主要是用来控制边缘的类型和粗细的,这些在软件自带的参考手册中均未提及。虽然手册里的阈值计算和判断方法与代码是一致的,但其函数功能说明却给人一种通常意义上的“图像二值化”的印象。

(2)有趣的是,我也留意了一下资料介绍的固定阈值化函数cvThreshold,其实它也有一种自适应阈值方法,那就是OSTU(大津法)!!只需要设定参数thresh_type的值为CV_THRESH_OTSU即可。

(3)前面分析得没问题,自适应二值化就是这样的。这是一种高效实现。自适应二值化计算像素的邻域的平均灰度,来决定二值化的值。如果整个区域几乎是一样灰度的,则无法给出合适的结果了。之所以看起来像边缘检测,是因为窗尺寸设置的小,可以改大一点试一试。
cvAdaptiveThreshold( src, dst, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 21); //窗设置为21
没有万能的二值化方法,具体问题具体分析,自适应二值化对于光照不均的文字,条码等,效果很好。窗口大小选择,考虑被检测物体尺寸。

(4)附:

/*======================================================================*/
/* OTSU global thresholding routine */
/*======================================================================*/

void otsu (IplImage *image)
{
int w = image->width;
int h = image->height;

unsigned char *np; // 图像指针
unsigned char pixel;
int thresholdValue=1; // 阈值
int ihist[256]; // 图像直方图,256个点

int i, j, k; // various counters
int n, n1, n2, gmin, gmax;
double m1, m2, sum, csum, fmax, sb;

// 对直方图置零...
memset(ihist, 0, sizeof(ihist));

gmin=255; gmax=0;
// 生成直方图
for (i = 0; i < h; i++) 
{
np = (unsigned char*)(image->imageData + image->widthStep*i);
for (j = 0; j < w; j++) 
{
pixel = np[j];
ihist[ pixel]++;
if(pixel > gmax) gmax= pixel;
if(pixel < gmin) gmin= pixel;
}
}

// set up everything
sum = csum = 0.0;
n = 0;

for (k = 0; k <= 255; k++) 
{
sum += k * ihist[k]; /* x*f(x) 质量矩*/
n += ihist[k]; /* f(x) 质量 */
}

if (!n) 
{
// if n has no value, there is problems...
//fprintf (stderr, "NOT NORMAL thresholdValue = 160\n");
thresholdValue = 160;
goto L;
}

// do the otsu global thresholding method
fmax = -1.0;
n1 = 0;
for (k = 0; k < 255; k++) 
{
n1 += ihist[k];
if (!n1) { continue; }
n2 = n - n1;
if (n2 == 0) { break; }
csum += k *ihist[k];
m1 = csum / n1;
m2 = (sum - csum) / n2;
sb = n1 * n2 *(m1 - m2) * (m1 - m2);
/* bbg: note: can be optimized. */
if (sb > fmax)
{
fmax = sb;
thresholdValue = k;
}
}

L:
for (i = 0; i < h; i++) 
{
np = (unsigned char*)(image->imageData + image->widthStep*i);
for (j = 0; j < w; j++) 
{
if(np[j] >= thresholdValue)
np[j] = 255;
else np[j] = 0;
}
}
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值