- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我做了一个实现边缘检测算法的程序,但需要很长时间来处理。我读过有关使用锁位和不安全状态而不是 getpixel 和 setpixel 的信息,但我仍然不明白如何使用它。
这是我的示例代码:
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 类,我是这样实现的:
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;
}
但是,图像根本没有改变。您能否就我的代码的哪一部分错误提出建议?
最佳答案
使用类似 FastBitmap 的类是最简单的.只需添加一个 FastBitmap 并在该类上而不是在您的 Bitmap 上使用 GetPixel(),其余的可以相同。
像这样:
Bitmap dstBmp = new Bitmap(width, height, original.PixelFormat);
FastBitmap fastBitmap = new FastBitmap(dstBmp);
fastBitmap.LockBitmap();
//...
var pixel = fastBitmap.GetPixel(x,y);
//...
fastBitmap.UnlockBitmap();
关于c# - 使用 Lockbits C# 进行边缘检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16747257/
我有一些代码有错误“AccessViolationException 未被用户代码处理:试图读取或写入 protected 内存...” 违规函数的精简版如下: protected override
我有一个方法需要尽可能快,它使用不安全的内存指针,这是我第一次尝试这种类型的编码,所以我知道它可能会更快。 /// /// Copies bitmapdata from one bi
使用 GetPixel 和 SetPixel 很简单,但速度很慢,所以我尝试使用 LockBits。 我很久以前就用过这种方法来比较两张图片: public static Bitmap FastCom
首先,我会指出我将接受 C# 或 VB.NET 解决方案。 我正在尝试重构这段旧代码,以避免使用 GetPixel/SetPixel 方法的坏习惯和性能低下: Public Function Cha
按照 Bob Powell 关于 LockBits 的教程,我将以下代码放入 C# 2010 Visual Studio Express 中: System.Drawing.Imaging.Bitma
我正在尝试使用 Lockbits 写出灰度图像,我当前的代码看起来是 /// /// Save the content of the FrameProc out to a bitmap /// p
我正在使用以下代码来锁定位图的矩形区域 Recangle rect = new rect(X,Y,width,height); BitmapData bitmapData = bitmap.LockB
我在将一些代码从 Bitmap.GetPixel 更改为使用 LockBits 返回的直接像素缓冲区时遇到问题。与 GetPixel 相比,LockBits 返回的数据似乎确实给了我不同的颜色值。 这
我在 Android 上的程序使用的算法使用了很多 setPixel 和 getPixel,因此,它非常慢。在 .NET 上,我可以使用 LockBits 使其更快。 Java 或 Android 上
MSDN 引用:[1] http://msdn.microsoft.com/en-us/library/5ey6h79d.aspx#Y1178 从链接中可以看出,第一个参数将“指定要锁定的位图部分”,
我正在处理由摄像机拍摄的 10 兆像素图像。 目的是在矩阵(二维数组)中注册每个像素的灰度值。 我第一次使用 GetPixel 但花了 25 秒才完成。现在我使用 Lockbits,但仍然需要 10
在部署应用程序之前,我使用 XP 虚拟机和 Vista 虚拟机对应用程序进行冒烟测试。这两个虚拟机都使用 32 位颜色。不确定这是否有什么区别,但我正在使用 VirtualBox。每台机器还分配有 2
我想使用 LockBits 方法更快地比较相似图像,如下所示 using System; using System.Drawing; using System.Drawing.Imaging; usi
我最近经常使用锁定位图,并且不断收到“试图访问无效内存”错误。这主要是因为位图已在内存中移动。有些人使用 GCHandle.Alloc() 在 CLR 中分配内存并固定它。 Bitmap.LockBi
我做了一个实现边缘检测算法的程序,但需要很长时间来处理。我读过有关使用锁位和不安全状态而不是 getpixel 和 setpixel 的信息,但我仍然不明白如何使用它。 这是我的示例代码: priva
使用 MS Visual Studio 2013,具有以下代码: using System; using System.Collections.Generic; using System.Linq;
我正在从一张 1bpp 索引图像剪切并粘贴到一张新图像。 一切正常,直到起始像素是 8 的除数。在下面的代码中,步幅等于相对于矩形宽度的值,直到我达到字节边界。那么步幅等于整个页面的宽度。 var c
我的程序是用 C# 编写的,在低级别上使用位图进行操作。一切正常,但有时(很少见,但稳定)出现“通用 GDI+ 异常”异常,并且很难重现这种情况。 函数 LockBits() 和 UnLockBits
我最近经常使用锁定位图,并且不断收到“试图访问无效内存”错误。这主要是因为位图已在内存中移动。有些人使用 GCHandle.Alloc() 在 CLR 中分配内存并固定它。 Bitmap.LockBi
编辑:非常感谢您的回复。我在这里最需要的是示例代码,用于说明我对嵌套循环中的几行代码所做的工作,因为这在 GetPixel/SetPixel 中是有效的,但也是我无法使用 Lockbits 正确工作的
我是一名优秀的程序员,十分优秀!