Example #1
0
    /// <summary>
    /// 图片灰度化和二值化
    /// </summary>
    private void ImageGray()
    {
        Dictionary <float, int> pixelCounts = new Dictionary <float, int>();

        Texture2D tt          = TextureTool.TextureToTexture2D(img.texture);
        Texture2D grayTexture = new Texture2D(tt.width, tt.height);

        for (int y = 0; y < tt.height; ++y)
        {
            for (int x = 0; x < tt.width; ++x)
            {
                Color curColor = tt.GetPixel(x, y);
                float g        = curColor.r * 0.299f + curColor.g * 0.587f + curColor.b * 0.114f;

                //grayTexture.SetPixel(x, y, new Color(g, g, g, 1f));

                // 记录相同灰度亮度值的像素有多少个
                int lumina = (int)(g * 256);
                if (pixelCounts.ContainsKey(lumina))
                {
                    pixelCounts[lumina] = pixelCounts[lumina] + 1;
                }
                else
                {
                    pixelCounts[lumina] = 1;
                }
            }
        }


        //grayTexture.Apply();
        //img2.texture = grayTexture;

        // 图像二值化与otsu算法,获取平均阈值
        float[] s_max = new float[2] {
            0, -10
        };
        for (int i = 0; i < 256; ++i)
        {
            int w_0 = 0, w_1 = 0, u_0 = 0, u_1 = 0, u = 0, g = 0;
            foreach (KeyValuePair <float, int> val in pixelCounts)
            {
                if (val.Key < i)
                {
                    w_0 += val.Value;    // 得到阈值以下像素个数的和
                }
                else
                {
                    w_1 += val.Value;    // 得到阈值以上像素个数的和
                }
            }

            // 得到阈值下所有像素的平均灰度
            for (int b = 0; b < i; b++)
            {
                if (pixelCounts.ContainsKey(b))
                {
                    u_0 += w_0 > 0 ? (b * pixelCounts[b]) / w_0 : 0;
                }
            }
            for (int c = 200; c < 256; c++)
            {
                if (pixelCounts.ContainsKey(c))
                {
                    u_1 += w_1 > 0 ? (c * pixelCounts[c]) / w_1 : 0;
                }
            }


            // 总平均灰度
            u = w_0 * u_0 + w_1 * u_1;

            // 类间方差
            g = w_0 * (u_0 - u) * (u_0 - u) + w_1 * (u_1 - u) * (u_1 - u);

            // 类间方差等价公式
            //g = w_0 * w_1 * (u_0 * u_1) * (u_0 * u_1);

            // 取最大的
            if (g > s_max[1])
            {
                s_max = new float[2] {
                    i, g
                }
            }
            ;
        }

        Debug.Log(s_max[0]);
        // 二值化
        for (int y = 0; y < tt.height; ++y)
        {
            for (int x = 0; x < tt.width; ++x)
            {
                Color curColor = tt.GetPixel(x, y);
                float g        = curColor.r * 0.299f + curColor.g * 0.587f + curColor.b * 0.114f;

                Color newColor = curColor;
                int   lumina   = (int)(g * 256);
                if (lumina > s_max[0])
                {
                    newColor = new Color(1, 1, 1, 0);
                }
                else
                {
                    newColor = new Color(0, 0, 0, curColor.a);
                }

                grayTexture.SetPixel(x, y, newColor);
            }
        }
        grayTexture.Apply();
        img2.texture = grayTexture;

        OnCreateMesh_4(grayTexture.width, grayTexture.height, grayTexture.GetPixels());
        //OnCreateMesh_3(grayTexture);
    }