双窗otsu,通两个不同尺寸的窗口实现阈值分割,然后把两个不同窗口的二值图像合并。
第一列为原图,otsu结果。第二列,3.bmp表示以3x3的窗口的内的Otsu自适应阈值分割效果图,其他图片以此类推。
随着窗口越大越接近原图的otsu结果。
不过局部自适应的阈值的缺点是算法时间花费比较大,而通过积分图可以减少阈值化的时间。
自适应阈值分割,主要解决全局阈值不适用光照不均图像的阈值分割,并可以在线性时间完成计算积分图像I(x,y),原图为f(x,y),过程为:
积分图计算完后,只需要要知道一个矩形窗的左上角和右下角的坐标,就可以借用积分图快速实现对矩形窗内的像素的累加,
,完成自适应阈值化:
//积分图像实现自适应阈值分割
void CWK_Image_ProcessingView::On_Integral_Image_Adaptive_Threshold()
{
CDC* pDC = GetDC();
int i, j,t=15;
int x1, x2, y1, y2, s = 31;
double sum = 0, temp1 = 0, temp2 = 0;
vector<vector<int> > integral(intHeight, vector<int>(intWidth, 0));//点的结构图矩阵,积分图
vector<vector<int> > out(intHeight, vector<int>(intWidth, 0));//输出
for (i = 0; i < intHeight; i++)
{
sum = 0;
for (j = 0; j <intWidth; j++)
{
sum += Data[i][j];//Data为原图
if (i == 0)
integral[i][j] = sum;
else
integral[i][j] = integral[i-1][j] + sum;
}
}
for (i = 0; i < intHeight; i++)
{
for (j = 0; j <intWidth; j++)
{
x1 = i - s / 2;
x2 = i + s / 2;
y1 = j - s / 2;
y2 = j + s / 2;
if (x1 < 0) x1 = 0;//边界判断
if (y1 < 0) y1 = 0;//边界判断
if (x2 >= intHeight) x2 = intHeight - 1;//边界判断
if (y2 >= intWidth) y2 = intWidth - 1;//边界判断
int count = (x2 - x1)*(y2-y1);
if (y2 < 1) y2 = 1;//边界判断
if (x1 < 1) x1 = 1;//边界判断
if (y1 < 1) y1 = 1;//边界判断
sum = integral[x2][y2] - integral[x2][y1-1] - integral[x1-1][y2] + integral[x1-1][y1-1];
temp1 = Data[i][j] * count;
temp2 = (sum*(100 - t) / 100);
if (temp1<=temp2)
{
pDC->SetPixel(j + intWidth, i, RGB(0, 0, 0));
out[i][j] = 0;
}
else
{
pDC->SetPixel(j + intWidth, i, RGB(255, 255, 255));
out[i][j] = 255;
}
}
}
ReleaseDC(pDC);
}
Bradley D,Roth G. Adaptive Thresholding using the Integral Image[J]. Journal of Graphics Gpu & Game Tools, 2007, 12(2):13-21.