OTSU大津法分割

OTSU大津法分割,第1张

不带掩膜 C语言实现:
int otsuThreshold(Mat &frame)
{
    const int GrayScale = 256;
    int width = frame->width;
    int height = frame->height;
    int pixelCount[GrayScale];
    float pixelPro[GrayScale];
    int i, j, pixelSum = width * height, threshold = 0;
    uchar* data = (uchar*)frame->imageData;  //指向像素数据的指针
    for (i = 0; i < GrayScale; i++)
    {
        pixelCount[i] = 0;
        pixelPro[i] = 0;
    }

    //统计灰度级中每个像素在整幅图像中的个数  
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            pixelCount[(int)data[i * width + j]]++;  //将像素值作为计数数组的下标
        }
    }

    //计算每个像素在整幅图像中的比例  
    float maxPro = 0.0;
    int kk = 0;
    for (i = 0; i < GrayScale; i++)
    {
        pixelPro[i] = (float)pixelCount[i] / pixelSum;
        if (pixelPro[i] > maxPro)
        {
            maxPro = pixelPro[i];
            kk = i;
        }
    }

    //遍历灰度级[0,255]  
    float w0, w1, u0tmp, u1tmp, u0, u1, u, deltaTmp, deltaMax = 0;
    for (i = 0; i < GrayScale; i++)     // i作为阈值
    {
        w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0;
        for (j = 0; j < GrayScale; j++)
        {
            if (j <= i)   //背景部分  
            {
                w0 += pixelPro[j];
                u0tmp += j * pixelPro[j];
            }
            else   //前景部分  
            {
                w1 += pixelPro[j];
                u1tmp += j * pixelPro[j];
            }
        }
        u0 = u0tmp / w0;
        u1 = u1tmp / w1;
        u = u0tmp + u1tmp;
        deltaTmp = w0 * pow((u0 - u), 2) + w1 * pow((u1 - u), 2);
        if (deltaTmp > deltaMax)
        {
            deltaMax = deltaTmp;
            threshold = i;
        }
    }

    return threshold;
}
Python实现
def otsu(img,gray_scale):
    pixel_count = np.zeros(gray_scale,dtype=np.int) #灰阶
    pixel_pro = np.zeros(gray_scale,dtype=np.float) #比例
    h,w = img.shape[0:2]
    pixel_sum  = h*w
    maxPro = 0.
    kk = 0
    threshold = 0
    for i in range(gray_scale):
        xpos,ypos = np.where(img==i)
        pixel_count[i] = len(xpos)
        pixel_pro[i] = pixel_count[i]/pixel_sum 
        if pixel_pro[i] > maxPro:
            maxPro = pixel_pro[i]
            kk = i
    deltaMax = 0
    for i in range(gray_scale):
        w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = delta_tmp = 0
        for j in range(gray_scale):
            if j<=i:
                w0 += pixel_pro[j]
                u0tmp += j*pixel_pro[j]
            else:
                w1 += pixel_pro[j]
                u1tmp += j * pixel_pro[j]
        u0 = u0tmp / (w0+1e-10)
        u1 = u1tmp / (w1+1e-10)
        u = u0tmp + u1tmp
        delta_tmp = w0 * pow((u0 - u), 2) + w1 * pow((u1 - u), 2)
        if delta_tmp > deltaMax:
            deltaMax = delta_tmp
            threshold = i
    img[img<=threshold] = 0
    img[img>threshold] = 255
    return threshold,img
带掩膜 python实现
def otsu_withmask(img,mask,gray_scale):
    pixel_count = np.zeros(gray_scale,dtype=np.int) #灰阶
    pixel_pro = np.zeros(gray_scale,dtype=np.float) #比例
    h,w = img.shape[0:2]
    pixel_sum  = h*w
    maxPro = 0.
    kk = 0
    threshold = 0

    for i in range(h):
        for j in range(w):
            if mask[i][j] == 255:
                pixel_count[int(img[i][j])]+=1
            else:
                pass
    for i in range(gray_scale):
        pixel_pro[i] = pixel_count[i]/pixel_sum 
        if pixel_pro[i] > maxPro:
            maxPro = pixel_pro[i]
            kk = i
            

    
    deltaMax = 0
    for i in range(gray_scale):
        w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = delta_tmp = 0
        for j in range(gray_scale):
            if j<=i:# 前景
                w0 += pixel_pro[j]
                u0tmp += j*pixel_pro[j]
            else: # 背景
                w1 += pixel_pro[j]
                u1tmp += j * pixel_pro[j]
        u0 = u0tmp / (w0+1e-10)
        u1 = u1tmp / (w1+1e-10)
        u = u0tmp + u1tmp
        delta_tmp = w0 * pow((u0 - u), 2) + w1 * pow((u1 - u), 2)
        if delta_tmp > deltaMax:
            deltaMax = delta_tmp
            threshold = i

    img[img<=threshold] = 0
    img[img>threshold] = 255
    if 1:#掩膜区域内做二值化:先反色,因为缺陷偏黑,让缺陷高亮,背景是黑色。然后将掩膜区域打黑
        img = 255-img
        img[mask==0] = 0
    return threshold,img

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/788763.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存