Exemple #1
0
        // Выделение связных областей рекурсивным алгоритмом
        unsafe private void AllocationOfConnectedDomains_recursively()
        {
            int maxStackSize = 100000000;
            Bitmap tmp = bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), bitmap.PixelFormat);

            Thread t = new Thread(() =>
            {              
                UnsafeBitmap src = new UnsafeBitmap(tmp);
                Byte* pBaseSrc = src.LockBitmap();
                int L = 1;
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        FillLabels(pBaseSrc, x, y, L++);
                    }
                }
                src.UnlockBitmap();
            }, maxStackSize);

            t.Start();
            t.Join();

            objectsCount = RenumberDomains();            
        }
Exemple #2
0
        // Выделение связных областей рекурсивным алгоритмом
        unsafe private void AllocationOfConnectedDomains_recursively()
        {
            int    maxStackSize = 100000000;
            Bitmap tmp          = bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), bitmap.PixelFormat);

            Thread t = new Thread(() =>
            {
                UnsafeBitmap src = new UnsafeBitmap(tmp);
                Byte *pBaseSrc   = src.LockBitmap();
                int L            = 1;
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        FillLabels(pBaseSrc, x, y, L++);
                    }
                }
                src.UnlockBitmap();
            }, maxStackSize);

            t.Start();
            t.Join();

            objectsCount = RenumberDomains();
        }
Exemple #3
0
        unsafe public Bitmap GetClusteredBitmap()
        {
            AllocationOfConnectedDomains_recursively();
            CalculateParameters();

            Bitmap bitmapRes = new Bitmap(bitmap.Width, bitmap.Height, bitmap.PixelFormat);

            if (GetGoodObjectsCount() == 0)
            {
                return(bitmapRes);
            }

            Hashtable table = k_means();

            Random random = new Random();

            Color[] colors = new Color[table.Count];
            for (int i = 0; i < table.Count; i++)
            {
                colors[i] = Color.FromArgb(random.Next(50, 255), random.Next(50, 255),
                                           random.Next(50, 255));
            }

            UnsafeBitmap src      = new UnsafeBitmap(bitmap);
            UnsafeBitmap res      = new UnsafeBitmap(bitmapRes);
            Byte *       pBaseRes = res.LockBitmap();
            Byte *       pBaseSrc = src.LockBitmap();

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    int labelIndex = GetLabelIndex(x, y);
                    if (labels[labelIndex] != 0)
                    {
                        for (int i = 0; i < table.Count; i++)
                        {
                            if (((List <int>)table[i]).Contains(labels[labelIndex]))
                            {
                                int imageIndex = (y * byteWidth) + x * byteDepth;
                                pBaseRes[imageIndex]     = colors[i].R;
                                pBaseRes[imageIndex + 1] = colors[i].G;
                                pBaseRes[imageIndex + 2] = colors[i].B;

                                if (byteDepth == 4)
                                {
                                    pBaseRes[imageIndex + 3] = pBaseSrc[imageIndex + 3];
                                }

                                break;
                            }
                        }
                    }
                }
            }

            res.UnlockBitmap();
            src.UnlockBitmap();
            return(bitmapRes);
        }
Exemple #4
0
        unsafe public Bitmap GetClusteredBitmap()
        {
            AllocationOfConnectedDomains_recursively();
            CalculateParameters();

            Bitmap bitmapRes = new Bitmap(bitmap.Width, bitmap.Height, bitmap.PixelFormat);
            if (GetGoodObjectsCount() == 0)
                return bitmapRes;

            Hashtable table = k_means();

            Random random = new Random();
            Color[] colors = new Color[table.Count];
            for (int i = 0; i < table.Count; i++)
            {
                colors[i] = Color.FromArgb(random.Next(50, 255), random.Next(50, 255), 
                                                                    random.Next(50, 255));
            }           

            UnsafeBitmap src = new UnsafeBitmap(bitmap);
            UnsafeBitmap res = new UnsafeBitmap(bitmapRes);
            Byte* pBaseRes = res.LockBitmap();
            Byte* pBaseSrc = src.LockBitmap();

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    int labelIndex = GetLabelIndex(x, y);
                    if (labels[labelIndex] != 0)
                    {
                        for (int i = 0; i < table.Count; i++)
                        {
                            if (((List<int>)table[i]).Contains(labels[labelIndex]))
                            {
                                int imageIndex = (y * byteWidth) + x * byteDepth;
                                pBaseRes[imageIndex] = colors[i].R;
                                pBaseRes[imageIndex + 1] = colors[i].G;
                                pBaseRes[imageIndex + 2] = colors[i].B;

                                if(byteDepth == 4)
                                    pBaseRes[imageIndex + 3] = pBaseSrc[imageIndex + 3];

                                break;
                            }
                        }
                    }
                }
            }

            res.UnlockBitmap();
            src.UnlockBitmap();
            return bitmapRes;
        }
Exemple #5
0
        // Пропорциональная маска без перекрытия - бинарное изображение одинаково во всех каналах
        unsafe public static Bitmap ApplyMask_grayscale(Bitmap bitmapSrc, double[,] mask)
        {
            Bitmap bitmapRes = new Bitmap(bitmapSrc.Width, bitmapSrc.Height, bitmapSrc.PixelFormat);

            int depth = Bitmap.GetPixelFormatSize(bitmapSrc.PixelFormat);
            Byte* pBaseSrc, pBaseRes;

            UnsafeBitmap src_wrap = new UnsafeBitmap(bitmapSrc);
            UnsafeBitmap res_wrap = new UnsafeBitmap(bitmapRes);

            pBaseSrc = src_wrap.LockBitmap();
            pBaseRes = res_wrap.LockBitmap();

            int width = bitmapSrc.Width;
            int height = bitmapSrc.Height;

            int maskWidth = mask.GetLength(0);
            int maskHeight = mask.GetLength(1);

            double maxValue = mask.Cast<double>().Max();

            int pos;

            if (depth == 24)
            {
                for (int x = 0; x < width; x += maskWidth)
                {
                    for (int y = 0; y < height; y += maskHeight)
                    {

                        double mul = 255 / maxValue;

                        for (int i = 0; i < maskWidth; i++)
                        {
                            for (int j = 0; j < maskHeight; j++)
                            {
                                int pixelPosX = x + i;
                                int pixelPosY = y + j;

                                if (pixelPosX >= width) pixelPosX -= width;
                                if (pixelPosY >= height) pixelPosY -= height;

                                pos = 3 * (width * pixelPosY + pixelPosX);

                                double value = 0.3 * pBaseSrc[pos + 0] + 0.59 * pBaseSrc[pos + 1] + 0.11 * pBaseSrc[pos + 2];

                                if (value < mul * mask[j, i])
                                {
                                    pBaseRes[pos + 0] = 0;
                                    pBaseRes[pos + 1] = 0;
                                    pBaseRes[pos + 2] = 0;
                                }
                                else
                                {
                                    pBaseRes[pos + 0] = 255;
                                    pBaseRes[pos + 1] = 255;
                                    pBaseRes[pos + 2] = 255;
                                }
                            }
                        }
                    }
                }

            }
            else if (depth == 32)
            {
                for (int x = 0; x < width; x += maskWidth)
                {
                    for (int y = 0; y < height; y += maskHeight)
                    {
                        double mul = 255 / maxValue;

                        for (int i = 0; i < maskWidth; i++)
                        {
                            for (int j = 0; j < maskHeight; j++)
                            {
                                int pixelPosX = x + i;
                                int pixelPosY = y + j;

                                if (pixelPosX >= width) pixelPosX -= width;
                                if (pixelPosY >= height) pixelPosY -= height;

                                pos = 4 * (width * pixelPosY + pixelPosX);

                                double value = 0.3 * pBaseSrc[pos + 0] + 0.59 * pBaseSrc[pos + 1] + 0.11 * pBaseSrc[pos + 2];

                                if (value < mul * mask[j, i])
                                {
                                    pBaseRes[pos + 0] = 0;
                                    pBaseRes[pos + 1] = 0;
                                    pBaseRes[pos + 2] = 0;
                                }
                                else
                                {
                                    pBaseRes[pos + 0] = 255;
                                    pBaseRes[pos + 1] = 255;
                                    pBaseRes[pos + 2] = 255;
                                }
                                pBaseRes[pos + 3] = pBaseSrc[pos + 3];
                            }
                        }
                    }
                }
            }

            res_wrap.UnlockBitmap();
            src_wrap.UnlockBitmap();

            return bitmapRes;
        }
Exemple #6
0
        // Свёртка с ядром без масштабирования (<0 = 0, >255 = 255)
        unsafe public static Bitmap ApplyKernel(Bitmap bitmapSrc, double[,] kernel)
        {
            Bitmap bitmapRes = new Bitmap(bitmapSrc.Width, bitmapSrc.Height, bitmapSrc.PixelFormat);

            int depth = Bitmap.GetPixelFormatSize(bitmapSrc.PixelFormat);
            Byte* pBaseSrc, pBaseRes;

            UnsafeBitmap src_wrap = new UnsafeBitmap(bitmapSrc);
            UnsafeBitmap res_wrap = new UnsafeBitmap(bitmapRes);

            pBaseSrc = src_wrap.LockBitmap();
            pBaseRes = res_wrap.LockBitmap();

            int width = bitmapSrc.Width;
            int height = bitmapSrc.Height;

            int kernelWidth = kernel.GetLength(0);
            int kernelHeight = kernel.GetLength(1);

            int pos;

            //Производим вычисления
            if (depth == 24)
            {
                for (int x = 0; x < width; x++)
                {
                    for (int y = 0; y < height; y++)
                    {
                        double rSum = 0, gSum = 0, bSum = 0;

                        for (int i = 0; i < kernelWidth; i++)
                        {
                            for (int j = 0; j < kernelHeight; j++)
                            {
                                int pixelPosX = x + (i - (kernelWidth / 2));
                                int pixelPosY = y + (j - (kernelHeight / 2));

                                if (pixelPosX == width) pixelPosX = 0;
                                if (pixelPosX == -1) pixelPosX = width - 1;
                                if (pixelPosY == height) pixelPosY = 0;
                                if (pixelPosY == -1) pixelPosY = height - 1;

                                pos = 3 * (width * pixelPosY + pixelPosX);
                                byte r = pBaseSrc[pos + 0];
                                byte g = pBaseSrc[pos + 1];
                                byte b = pBaseSrc[pos + 2];

                                double kernelVal = kernel[i, j];

                                rSum += r * kernelVal;
                                gSum += g * kernelVal;
                                bSum += b * kernelVal;
                            }
                        }

                        if (rSum < 0) rSum = 0;
                        if (rSum > 255) rSum = 255;

                        if (gSum < 0) gSum = 0;
                        if (gSum > 255) gSum = 255;

                        if (bSum < 0) bSum = 0;
                        if (bSum > 255) bSum = 255;

                        //Записываем значения в результирующее изображение
                        pos = 3 * (width * y + x);
                        pBaseRes[pos + 0] = (byte)rSum;
                        pBaseRes[pos + 1] = (byte)gSum;
                        pBaseRes[pos + 2] = (byte)bSum;
                    }
                }

            }
            else if (depth == 32)
            {
                for (int x = 0; x < width; x++)
                {
                    for (int y = 0; y < height; y++)
                    {
                        double rSum = 0, gSum = 0, bSum = 0;

                        for (int i = 0; i < kernelWidth; i++)
                        {
                            for (int j = 0; j < kernelHeight; j++)
                            {
                                int pixelPosX = x + (i - (kernelWidth / 2));
                                int pixelPosY = y + (j - (kernelHeight / 2));

                                if (pixelPosX == width) pixelPosX = 0;
                                if (pixelPosX == -1) pixelPosX = width - 1;
                                if (pixelPosY == height) pixelPosY = 0;
                                if (pixelPosY == -1) pixelPosY = height - 1;

                                pos = 4 * (width * pixelPosY + pixelPosX);
                                byte r = pBaseSrc[pos + 0];
                                byte g = pBaseSrc[pos + 1];
                                byte b = pBaseSrc[pos + 2];

                                double kernelVal = kernel[i, j];

                                rSum += r * kernelVal;
                                gSum += g * kernelVal;
                                bSum += b * kernelVal;
                            }
                        }

                        if (rSum < 0) rSum = 0;
                        if (rSum > 255) rSum = 255;

                        if (gSum < 0) gSum = 0;
                        if (gSum > 255) gSum = 255;

                        if (bSum < 0) bSum = 0;
                        if (bSum > 255) bSum = 255;

                        //Записываем значения в результирующее изображение
                        pos = 4 * (width * y + x);
                        pBaseRes[pos + 0] = (byte)rSum;
                        pBaseRes[pos + 1] = (byte)gSum;
                        pBaseRes[pos + 2] = (byte)bSum;
                        pBaseRes[pos + 3] = pBaseSrc[pos + 3];
                    }
                }
            }

            res_wrap.UnlockBitmap();
            src_wrap.UnlockBitmap();

            //Возвращаем отфильтрованное изображение
            return bitmapRes;
        }
Exemple #7
0
        // Свёртка с ядром с независимым масштабированием каналов R, G, B
        unsafe static public Bitmap ApplyKernelWithIndependentScaling(Bitmap bitmapSrc, double[,] kernel)
        {
            Bitmap bitmapRes = new Bitmap(bitmapSrc.Width, bitmapSrc.Height, bitmapSrc.PixelFormat);

            int depth = Bitmap.GetPixelFormatSize(bitmapSrc.PixelFormat);
            Byte* pBaseSrc, pBaseRes;

            UnsafeBitmap src_wrap = new UnsafeBitmap(bitmapSrc);
            UnsafeBitmap res_wrap = new UnsafeBitmap(bitmapRes);

            pBaseSrc = src_wrap.LockBitmap();
            pBaseRes = res_wrap.LockBitmap();

            int width = bitmapSrc.Width;
            int height = bitmapSrc.Height;

            Int16[] array = new Int16[width * height * depth / 3];

            int strNum = kernel.GetLength(0);
            int colNum = kernel.GetLength(1);

            int pos, pixelPosX, pixelPosY;
            Int16 maxR = (Int16)pBaseSrc[0], maxG = (Int16)pBaseSrc[1], maxB = (Int16)pBaseSrc[2];
            Int16 minR = (Int16)pBaseSrc[0], minG = (Int16)pBaseSrc[1], minB = (Int16)pBaseSrc[2];

            if (depth == 32)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        double rSum = 0, gSum = 0, bSum = 0;
                        for (int i = 0; i < strNum; i++)
                        {
                            for (int j = 0; j < colNum; j++)
                            {
                                pixelPosX = x + (i - (strNum / 2));
                                pixelPosY = y + (j - (colNum / 2));

                                if (pixelPosX == width) pixelPosX = 0;
                                if (pixelPosX == -1) pixelPosX = width - 1;
                                if (pixelPosY == height) pixelPosY = 0;
                                if (pixelPosY == -1) pixelPosY = height - 1;

                                pos = ((pixelPosY * width) + pixelPosX) * 4;

                                rSum += pBaseSrc[pos] * kernel[i, j];
                                gSum += pBaseSrc[pos + 1] * kernel[i, j];
                                bSum += pBaseSrc[pos + 2] * kernel[i, j];
                            }
                        }

                        pos = ((y * width) + x) * 4;

                        array[pos] = (Int16)rSum;
                        array[pos + 1] = (Int16)gSum;
                        array[pos + 2] = (Int16)bSum;

                        if (array[pos] > maxR) maxR = array[pos];
                        if (array[pos + 1] > maxG) maxG = array[pos + 1];
                        if (array[pos + 2] > maxB) maxB = array[pos + 2];
                        if (array[pos] < minR) minR = array[pos];
                        if (array[pos + 1] < minG) minG = array[pos + 1];
                        if (array[pos + 2] < minB) minB = array[pos + 2];
                    }
                }

                Int16 deltaR = (Int16)(maxR - minR), deltaG = (Int16)(maxG - minG), deltaB = (Int16)(maxB - minB);
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        pos = ((y * width) + x) * 4;

                        Int16 r = array[pos];
                        Int16 g = array[pos + 1];
                        Int16 b = array[pos + 2];

                        pBaseRes[pos] = (byte)((r - minR) * 255 / deltaR);
                        pBaseRes[pos + 1] = (byte)((g - minG) * 255 / deltaG);
                        pBaseRes[pos + 2] = (byte)((b - minB) * 255 / deltaB);
                        pBaseRes[pos + 3] = pBaseSrc[pos + 3];
                    }
                }
            }
            else if (depth == 24)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        double rSum = 0, gSum = 0, bSum = 0;
                        for (int i = 0; i < strNum; i++)
                        {
                            for (int j = 0; j < colNum; j++)
                            {
                                pixelPosX = x + (i - (strNum / 2));
                                pixelPosY = y + (j - (colNum / 2));

                                if (pixelPosX == width) pixelPosX = 0;
                                if (pixelPosX == -1) pixelPosX = width - 1;
                                if (pixelPosY == height) pixelPosY = 0;
                                if (pixelPosY == -1) pixelPosY = height - 1;

                                pos = ((pixelPosY * width) + pixelPosX) * 3;

                                rSum += pBaseSrc[pos] * kernel[i, j];
                                gSum += pBaseSrc[pos + 1] * kernel[i, j];
                                bSum += pBaseSrc[pos + 2] * kernel[i, j];
                            }
                        }

                        pos = ((y * width) + x) * 3;


                        array[pos] = (Int16)rSum;
                        array[pos + 1] = (Int16)gSum;
                        array[pos + 2] = (Int16)bSum;

                        if (array[pos] > maxR)
                            maxR = array[pos];
                        if (array[pos + 1] > maxG) maxG = array[pos + 1];
                        if (array[pos + 2] > maxB) maxB = array[pos + 2];
                        if (array[pos] < minR) minR = array[pos];
                        if (array[pos + 1] < minG) minG = array[pos + 1];
                        if (array[pos + 2] < minB) minB = array[pos + 2];
                    }
                }

                Int16 deltaR = (Int16)(maxR - minR), deltaG = (Int16)(maxG - minG), deltaB = (Int16)(maxB - minB);
                if (deltaR == 0) deltaR = 1;
                if (deltaG == 0) deltaG = 1;
                if (deltaB == 0) deltaB = 1;

                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        pos = ((y * width) + x) * 3;

                        Int16 r = array[pos];
                        Int16 g = array[pos + 1];
                        Int16 b = array[pos + 2];

                        pBaseRes[pos] = (byte)((r - minR) * 255 / deltaR);
                        pBaseRes[pos + 1] = (byte)((g - minG) * 255 / deltaG);
                        pBaseRes[pos + 2] = (byte)((b - minB) * 255 / deltaB);
                    }
                }

            }


            src_wrap.UnlockBitmap();
            res_wrap.UnlockBitmap();
            return bitmapRes;
        }
Exemple #8
0
        // Соляризация
        unsafe static public Bitmap Solarisation(Bitmap BitmapSrc, bool dynamicMatch, double k)
        {
            Bitmap BitmapRes = new Bitmap(BitmapSrc.Width, BitmapSrc.Height, BitmapSrc.PixelFormat);

            int depth = Bitmap.GetPixelFormatSize(BitmapSrc.PixelFormat);
            Byte* pBaseSrc, pBaseRes;

            UnsafeBitmap src = new UnsafeBitmap(BitmapSrc);
            UnsafeBitmap res = new UnsafeBitmap(BitmapRes);

            pBaseSrc = src.LockBitmap();
            pBaseRes = res.LockBitmap();

            int width = BitmapSrc.Width;
            int height = BitmapSrc.Height;

            byte R_max = 0, G_max = 0, B_max = 0;
            byte r, g, b, a;
            double R_k, G_k, B_k;
            int i;

            if (depth == 32)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        i = ((y * width) + x) * 4;
                        r = pBaseSrc[i];
                        g = pBaseSrc[i + 1];
                        b = pBaseSrc[i + 2];

                        if (R_max < r) R_max = r;
                        if (G_max < r) G_max = g;
                        if (B_max < r) B_max = b;

                        if (R_max == 255 && G_max == 255 && B_max == 255)
                            goto loop_End;
                    }
                }
            loop_End:

                if (dynamicMatch == true)
                {
                    R_k = 4.0 / R_max;
                    G_k = 4.0 / G_max;
                    B_k = 4.0 / B_max;
                }
                else
                {
                    R_k = k;
                    G_k = k;
                    B_k = k;
                }

                double R, G, B;
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        i = ((y * width) + x) * 4;
                        r = pBaseSrc[i];
                        g = pBaseSrc[i + 1];
                        b = pBaseSrc[i + 2];
                        a = pBaseSrc[i + 3];

                        R = R_k * r * (R_max - r);
                        G = G_k * g * (G_max - g);
                        B = B_k * b * (B_max - b);


                        if (R < 0) R = 0;
                        else if (R > 255) R = 255;

                        if (G < 0) G = 0;
                        else if (G > 255) G = 255;

                        if (B < 0) B = 0;
                        else if (B > 255) B = 255;

                        pBaseRes[i] = (byte)R;
                        pBaseRes[i + 1] = (byte)G;
                        pBaseRes[i + 2] = (byte)B;
                        pBaseRes[i + 3] = a;
                    }
                }

            }
            else if (depth == 24)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        i = ((y * width) + x) * 3;
                        r = pBaseSrc[i];
                        g = pBaseSrc[i + 1];
                        b = pBaseSrc[i + 2];

                        if (R_max < r) R_max = r;
                        if (G_max < r) G_max = g;
                        if (B_max < r) B_max = b;

                        if (R_max == 255 && G_max == 255 && B_max == 255)
                            goto loop_End;
                    }
                }
            loop_End:

                if (dynamicMatch == true)
                {
                    R_k = 4.0 / R_max;
                    G_k = 4.0 / G_max;
                    B_k = 4.0 / B_max;
                }
                else
                {
                    R_k = k;
                    G_k = k;
                    B_k = k;
                }

                double R, G, B;
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        i = ((y * width) + x) * 3;
                        r = pBaseSrc[i];
                        g = pBaseSrc[i + 1];
                        b = pBaseSrc[i + 2];

                        R = R_k * r * (R_max - r);
                        G = G_k * g * (G_max - g);
                        B = B_k * b * (B_max - b);


                        if (R < 0) R = 0;
                        else if (R > 255) R = 255;

                        if (G < 0) G = 0;
                        else if (G > 255) G = 255;

                        if (B < 0) B = 0;
                        else if (B > 255) B = 255;

                        pBaseRes[i] = (byte)R;
                        pBaseRes[i + 1] = (byte)G;
                        pBaseRes[i + 2] = (byte)B;
                    }
                }
            }

            src.UnlockBitmap();
            res.UnlockBitmap();

            return BitmapRes;
        }
Exemple #9
0
        //----------------------------------------------------------------------------------------------

        // Медианный фильтр
        unsafe public static Bitmap MedianFilter_unsafe(Bitmap bitmapSrc, int kernelSize)
        {
            if (bitmapSrc.PixelFormat != PixelFormat.Format24bppRgb && bitmapSrc.PixelFormat != PixelFormat.Format32bppArgb
                && bitmapSrc.PixelFormat != PixelFormat.Format32bppRgb && bitmapSrc.PixelFormat != PixelFormat.Canonical)
                throw new Exception("Unsupported color depth. Support only 24bppRgb, 32bppArgb and 32bppRgb");

            if(kernelSize < 3 || kernelSize % 2 == 0)
                throw new Exception("Size of kernel of Median filter should be greater than or equal to 3 and odd.");

            Bitmap bitmapRes = new Bitmap(bitmapSrc.Width, bitmapSrc.Height, bitmapSrc.PixelFormat);
            int depth = Bitmap.GetPixelFormatSize(bitmapSrc.PixelFormat);
            int byteDepth = depth / 8;

            Byte* pBaseSrc, pBaseRes;

            UnsafeBitmap src = new UnsafeBitmap(bitmapSrc);
            UnsafeBitmap res = new UnsafeBitmap(bitmapRes);

            pBaseSrc = src.LockBitmap();
            pBaseRes = res.LockBitmap();

            int width = bitmapSrc.Width;

            int byteWidth = bitmapSrc.Width * byteDepth;
            if (byteWidth % 4 != 0)
                byteWidth = 4 * (byteWidth / 4 + 1);

            int height = bitmapSrc.Height;

            int strNum = kernelSize;
            int colNum = kernelSize;

            int pixelPosX, pixelPosY, pos;

            int indent = kernelSize / 2;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    if (y >= indent && y < height - indent && x >= indent && x < width - indent)
                    {
                        byte[] arrayR = new byte[colNum * strNum];
                        byte[] arrayG = new byte[colNum * strNum];
                        byte[] arrayB = new byte[colNum * strNum];
                        int arrIndex = 0;

                        for (int i = 0; i < strNum; i++)
                        {
                            for (int j = 0; j < colNum; j++)
                            {
                                pixelPosX = x + (i - (strNum / 2));
                                pixelPosY = y + (j - (colNum / 2));

                                pos = (pixelPosY * byteWidth) + pixelPosX * byteDepth;

                                arrayR[arrIndex] = pBaseSrc[pos];
                                arrayG[arrIndex] = pBaseSrc[pos + 1];
                                arrayB[arrIndex] = pBaseSrc[pos + 2];
                                arrIndex++;
                            }
                        }

                        Array.Sort(arrayR);
                        Array.Sort(arrayG);
                        Array.Sort(arrayB);

                        pos = (y * byteWidth) + x * byteDepth;

                        pBaseRes[pos] = arrayR[arrayR.Length / 2];
                        pBaseRes[pos + 1] = arrayG[arrayG.Length / 2];
                        pBaseRes[pos + 2] = arrayB[arrayB.Length / 2];
                    }
                    else
                    {
                        pos = (y * byteWidth) + x * byteDepth;

                        pBaseRes[pos] = pBaseSrc[pos];
                        pBaseRes[pos + 1] = pBaseSrc[pos + 1];
                        pBaseRes[pos + 2] = pBaseSrc[pos + 2];
                    }

                    if (byteDepth == 4)
                        pBaseRes[pos + 3] = pBaseSrc[pos + 3];
                }
            }

            src.UnlockBitmap();
            res.UnlockBitmap();

            return bitmapRes;
        }
Exemple #10
0
        //----------------------------------------------------------------------------------------------

        // Перевод в оттенки серого и пороговая бинаризация
        unsafe public static Bitmap GrayscaleAndBinarization_unsafe(Bitmap bitmapSrc, byte threshold)
        {
            if (bitmapSrc.PixelFormat != PixelFormat.Format24bppRgb && bitmapSrc.PixelFormat != PixelFormat.Format32bppArgb
                && bitmapSrc.PixelFormat != PixelFormat.Format32bppRgb && bitmapSrc.PixelFormat != PixelFormat.Canonical)
                throw new Exception("Unsupported color depth. Support only 24bppRgb, 32bppArgb and 32bppRgb");

            Bitmap bitmapRes = new Bitmap(bitmapSrc.Width, bitmapSrc.Height, bitmapSrc.PixelFormat);
            int depth = Bitmap.GetPixelFormatSize(bitmapSrc.PixelFormat);
            int byteDepth = depth / 8;

            Byte* pBaseSrc, pBaseRes;

            UnsafeBitmap src = new UnsafeBitmap(bitmapSrc);
            UnsafeBitmap res = new UnsafeBitmap(bitmapRes);

            pBaseSrc = src.LockBitmap();
            pBaseRes = res.LockBitmap();

            int width = bitmapSrc.Width;

            int byteWidth = bitmapSrc.Width * byteDepth;
            if (byteWidth % 4 != 0)
                byteWidth = 4 * (byteWidth / 4 + 1);

            int height = bitmapSrc.Height;

            int i;
            double value;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    i = (y * byteWidth) + x * byteDepth;
                    value = 0.3 * pBaseSrc[i + 0] + 0.59 * pBaseSrc[i + 1] + 0.11 * pBaseSrc[i + 2];

                    if (value >= (double)threshold)
                    {
                        pBaseRes[i] = 255;
                        pBaseRes[i + 1] = 255;
                        pBaseRes[i + 2] = 255;
                    }
                    else
                    {
                        pBaseRes[i] = 0;
                        pBaseRes[i + 1] = 0;
                        pBaseRes[i + 2] = 0;
                    }

                    if (byteDepth == 4)
                        pBaseRes[i + 3] = pBaseSrc[i + 3];
                }
            }

            src.UnlockBitmap();
            res.UnlockBitmap();

            return bitmapRes;
        }