Ostu阈值分割
算法思想
- 计算直方图,将图像中所有的像素点按照0-255共256个bin,统计落在每个bin的像素点数量;
- 对直方图进行归一化处理,即计算每个灰度级的像素数目占整幅图像的比例
- i表示分类的阈值,也即一个灰度级,从0开始迭代;
- 通过归一化的直方图,统计0~i 灰度级的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例w1,并统计前景像素的平均灰度mu1;统计i~255灰度级的像素(假设像素值在此范围的像素叫做背景像素) 所占整幅图像的比例w2,并统计背景像素的平均灰度mu2;
- 计算前景像素和背景像素的方差 sigma = w1 * w2 * (mu1 - mu2) * (mu1 - mu2)
- i++;转到4,直到i为256时结束迭代;
- 将最大的方差sigma相应的i值作为图像的全局阈值;
- 二值化图像;
程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
namespace segmentation
{
class Program
{
static void Main(string[] args)
{
string savePath = @"E:\Desktop\66ns.jpg";
Bitmap img = new Bitmap(@"E:\Desktop\1n.jpg");
Bitmap a = threshold(img);
a.Save(savePath);
}
public static Bitmap threshold(Bitmap image)
{
Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);
BitmapData bmpData = image.LockBits(rect, ImageLockMode.ReadWrite, image.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = bmpData.Height * bmpData.Stride;
byte[] grayValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
byte T = 0;
byte[] neighb = new byte[bytes];
byte temp = 0;
byte maxGray = 0;
byte minGray = 255;
int[] countPixel = new int[256];
for (int i = 0; i < grayValues.Length; i++)
{
temp = grayValues[i];
countPixel[temp]++;
if (temp > maxGray)
{
maxGray = temp;
}
if (temp < minGray)
{
minGray = temp;
}
}
double mu1, mu2;
int numerator;
double sigma;
double tempMax = 0;
double w1 = 0, w2 = 0;
double sum = 0;
numerator = 0;
for (int i = minGray; i <= maxGray; i++)
{
sum += i * countPixel[i];
}
for (int i = minGray; i < maxGray; i++)
{
w1 += countPixel[i];
numerator += i * countPixel[i];
mu1 = numerator / w1;
w2 = grayValues.Length - w1;
mu2 = (sum - numerator) / w2;
sigma = w1 * w2 * (mu1 - mu2) * (mu1 - mu2);
if (sigma > tempMax)
{
tempMax = sigma;
T = Convert.ToByte(i);
}
}
for (int i = 0; i < bytes; i++)
{
if (grayValues[i] < T)
grayValues[i] = 0;
else
grayValues[i] = 255;
}
System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
image.UnlockBits(bmpData);
return (image);
}
}
}
结果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/97e5559d7bb49a9400dfc94f6e3ba01a.png)