最近的一个月一直在根据项目的具体问题来学习一些新的算法,但是在写最大类间方差的时候由于调用了很多的mat类逻辑运算和求和运算来求最大方差,导致程序的运行时间直接跑到了4秒开外,所以最近准备学习我一开始就回避的向量方法。
借用同学的一句话:没有用到指针和内存分配,学C++干嘛?
先上一个简单的向量遍历的方法(灰度图像),并累计每个像素值的个数:
有点类似与calcHist()函数
bool fiter(Mat src)
{
int gray;//灰度值
int histogram[256]={0};
for(int i=0;i<src.rows;i++)
{
uchar* p=src.ptr<uchar>(i);//给p指向行的首地址
//printf("A[%d][j]=%d\n",i,(*p));
for(int j=0;j<src.cols;j++)
{
gray=*(p+j);
histogram[gray]++;
}
}
for(int k=0;k<256;k++)
printf("histogram[%d]= %d\n",k,histogram[k]);
return 1;
}
最大类间方差
//这段代码耗时太长,不建议采纳
//for(int T=0;T<256;T++)
//{
// U=(g_filter<T)/255;
// //cout<<sum(U)[0]/N<<endl;
// w0=sum(U)[0];//背景的个数
// w1=N-w0;//N为像素总个数
// u0=sum(g_filter.mul(U))[0]/w0;
// u1=sum(((U==0)/255).mul(g_filter))[0]/w1;
// w0=w0/N;
// w1=1-w0;
// S=w1*w0*(u0-u1)*(u0-u1);
// if(S>Smax)
// Smax=S;
//}
下面用指针的方法可大大节约程序运行时间
int histogram[256]={0};
//int gray;
double S,Smax=0;
int t_OTSU;
for (int i=0;i<g_filter.rows;i++)
{
uchar* p=g_filter.ptr<uchar>(i);
//uchar* p=src.ptr<uchar>(i);
for(int j=0;j<g_filter.cols;j++)
//gray=*(p+j);
histogram[*(p+j)]++;
}
float w0=0,w1=0,u0=0,u1=0;//背景和前景的比例及灰度均值
int N=g_filter.rows*g_filter.cols;
for(int T=50;T<150;T++)//遍历阈值
{
for(int k=0;k<256;k++)
{
//printf("histogram[%d]= %d\n",k,histogram[k]);
if(k<T)
{
w0+=histogram[k];//背景的个数
u0+=histogram[k]*k;
}
else
{
w1+=histogram[k];
u1+=histogram[k]*k;
}
}
u0=u0/w0;//灰度均值
w0=w0/N;//比例
u1=u1/w1;
w1=w1/N;
// double S,Smax=0;
S=w1*w0*(u0-u1)*(u0-u1);
if(S>Smax)
{Smax=S;t_OTSU=T;}
}
cout<<"最大类间方差阈值为 "<<t_OTSU<<endl;
cout<<"最大类间方差为 "<<Smax<<endl;