matlab中的imadjust函数的第一种调用方式为:imadjust(I), I为待处理图像,在参数封装时调用了stretchlim函数。但opencv中没有相应的实现,故参照matlab的源代码实现了stretchlim函数。该函数用了上一篇文章中实现的hist函数,
void stretchlim(const IplImage* img, vector<double> tol, vector<double>& low_high)
{
//接受参数
double tol_low , tol_high;
switch(tol.size())
{
case 0: //默认值为 0.01, 0.99
tol_low = 0.01;
tol_high = 0.99;
break;
case 1:
tol_low = tol[0];
tol_high = 1-tol[0];
break;
case 2:
tol_low = tol[0];
tol_high = tol[1];
break;
}
int nbins = 255;
if(img->depth == IPL_DEPTH_16U)
nbins = 65535;
//若容忍度低值小于高值则观察直方图获取灰度范围
if(tol_low<tol_high)
{
//计算直方图
vector<long> N = hist(img);
//计算累积分布向量
vector<double> cdp = cumsumativeDistribution(N);
//查找tol_low,tol_high边界灰度值
int ilow = lower_bound(cdp.begin(), cdp.end(), tol_low)-cdp.begin();
int ihigh = upper_bound(cdp.begin(), cdp.end(), tol_high)-cdp.begin();
cout<<tol_low<<endl;
cout<<tol_high<<endl;
cout<<ilow<<endl;
cout<<ihigh<<endl;
if(ilow == ihigh)//若边界灰度值相等则设为默认值(当图像为一个平面时)
{
low_high.push_back(0);
low_high.push_back(1);
}
else //否则设为边界灰度归一化值
{
low_high.push_back(ilow*1.0/nbins);
low_high.push_back(ihigh*1.0/nbins);
}
}
//否则设为默认值0,1
else
{
low_high.push_back(0);
low_high.push_back(1);
}
}
vector<double> cumsumativeDistribution(vector<long> vec)
{
vector<double> distr;
vector<long> cum;
long sum = 0;
//计算累积向量和总和
for(vector<long>::iterator it = vec.begin(); it != vec.end(); it++)
{
sum += *it;
cum.push_back(sum);
}
//计算累积分布率向量
for(vector<long>::iterator it = cum.begin(); it != cum.end(); it++)
{
distr.push_back(*it*1.0/sum);
}
return distr;
}

本文介绍如何在OpenCV中参照Matlab的源代码实现stretchlim函数,以达到与Matlab中的imadjust函数类似的效果。文章讨论了如何利用之前实现的hist函数来完成这一目标。

3469

被折叠的 条评论
为什么被折叠?



