带锁位的边缘检测C# [英] Edge Detection with Lockbits C#

查看:69
本文介绍了带锁位的边缘检测C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了一个实现边缘检测算法的程序,但是要花很长时间.我已经读过关于使用锁位和不安全状态而不是getpixel和setpixel的信息,但是我仍然不知道如何使用它.

I made a program that implements an edge detection algorithm, but it takes a long time to process. I've read about using lockbits, and unsafe state instead of getpixel and setpixel, but I still don't understand how to use it.

这是我的示例代码:

private Bitmap SobelEdgeDetect(Bitmap original)
        {
            Bitmap b = original;
            Bitmap bb = original;
            int width = b.Width;
            int height = b.Height;
            int[,] gx = new int[,] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } };
            int[,] gy = new int[,] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } };

            int[,] allPixR = new int[width, height];
            int[,] allPixG = new int[width, height];
            int[,] allPixB = new int[width, height];

            int limit = 128 * 128;

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    allPixR[i, j] = b.GetPixel(i, j).R;
                    allPixG[i, j] = b.GetPixel(i, j).G;
                    allPixB[i, j] = b.GetPixel(i, j).B;
                }
            }

            int new_rx = 0, new_ry = 0;
            int new_gx = 0, new_gy = 0;
            int new_bx = 0, new_by = 0;
            int rc, gc, bc;
            for (int i = 1; i < b.Width - 1; i++)
            {
                for (int j = 1; j < b.Height - 1; j++)
                {

                    new_rx = 0;
                    new_ry = 0;
                    new_gx = 0;
                    new_gy = 0;
                    new_bx = 0;
                    new_by = 0;
                    rc = 0;
                    gc = 0;
                    bc = 0;

                    for (int wi = -1; wi < 2; wi++)
                    {
                        for (int hw = -1; hw < 2; hw++)
                        {
                            rc = allPixR[i + hw, j + wi];
                            new_rx += gx[wi + 1, hw + 1] * rc;
                            new_ry += gy[wi + 1, hw + 1] * rc;

                            gc = allPixG[i + hw, j + wi];
                            new_gx += gx[wi + 1, hw + 1] * gc;
                            new_gy += gy[wi + 1, hw + 1] * gc;

                            bc = allPixB[i + hw, j + wi];
                            new_bx += gx[wi + 1, hw + 1] * bc;
                            new_by += gy[wi + 1, hw + 1] * bc;
                        }
                    }
                    if (new_rx * new_rx + new_ry * new_ry > limit || new_gx * new_gx + new_gy * new_gy > limit || new_bx * new_bx + new_by * new_by > limit)
                        bb.SetPixel(i, j, Color.Black);


                    else
                        bb.SetPixel(i, j, Color.Transparent);
                }
            }
            return bb;
        }

我正在使用fastbitmap类,该类的实现方式如下:

I am using the fastbitmap class, which I implement like this:

private Bitmap SobelEdgeDetectTwo(Bitmap original)
        {
            int width = original.Width;
            int height = original.Height;
            Bitmap result = new Bitmap(width,height);
            FastBitmap b = new FastBitmap(original);
            FastBitmap bb = new FastBitmap(result);

            b.LockBitmap();
            bb.LockBitmap();

            int[,] gx = new int[,] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } };
            int[,] gy = new int[,] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } };

            int[,] allPixR = new int[width, height];
            int[,] allPixG = new int[width, height];
            int[,] allPixB = new int[width, height];

            int limit = 128 * 128;

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    var pixel = b.GetPixel(i,j);
                    allPixR[i, j] = pixel.Red;
                    allPixG[i, j] = pixel.Green;
                    allPixB[i, j] = pixel.Blue;

                }
            }

            int new_rx = 0, new_ry = 0;
            int new_gx = 0, new_gy = 0;
            int new_bx = 0, new_by = 0;
            int rc, gc, bc;
            for (int i = 1; i < width - 1; i++)
            {
                for (int j = 1; j < height - 1; j++)
                {

                    new_rx = 0;
                    new_ry = 0;
                    new_gx = 0;
                    new_gy = 0;
                    new_bx = 0;
                    new_by = 0;
                    rc = 0;
                    gc = 0;
                    bc = 0;

                    for (int wi = -1; wi < 2; wi++)
                    {
                        for (int hw = -1; hw < 2; hw++)
                        {
                            rc = allPixR[i + hw, j + wi];
                            new_rx += gx[wi + 1, hw + 1] * rc;
                            new_ry += gy[wi + 1, hw + 1] * rc;

                            gc = allPixG[i + hw, j + wi];
                            new_gx += gx[wi + 1, hw + 1] * gc;
                            new_gy += gy[wi + 1, hw + 1] * gc;

                            bc = allPixB[i + hw, j + wi];
                            new_bx += gx[wi + 1, hw + 1] * bc;
                            new_by += gy[wi + 1, hw + 1] * bc;
                        }
                    }

                    if (new_rx * new_rx + new_ry * new_ry > limit || new_gx * new_gx + new_gy * new_gy > limit || new_bx * new_bx + new_by * new_by > limit)
                    {
                        PixelData p = new PixelData(Color.Black);
                        bb.SetPixel(i, j, p);

                    }
                    else
                    {
                        PixelData p = new PixelData(Color.Transparent);
                        bb.SetPixel(i, j, p);

                    }

                }
            }


            b.UnlockBitmap();
            bb.UnlockBitmap();

            return result;
        }

但是,图像完全没有改变.您能给我一些有关我的代码哪一部分错误的建议吗?

However, the image doesn't change at all. Could you give me advice about which part of my code is wrong?

推荐答案

最简单的方法是使用

It's easiest to use a class like FastBitmap. Just add a FastBitmap and use GetPixel() on that class instead of on your Bitmap, the rest can be the same.

类似这样的东西:

Bitmap dstBmp = new Bitmap(width, height, original.PixelFormat);
FastBitmap fastBitmap = new FastBitmap(dstBmp);
fastBitmap.LockBitmap();
//...
var pixel = fastBitmap.GetPixel(x,y);
//...
fastBitmap.UnlockBitmap();

这篇关于带锁位的边缘检测C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆