Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 索贝尔公司;具有可写性Bitmapex的卷积_C#_Edge Detection_Writeablebitmap_Writeablebitmapex - Fatal编程技术网

C# 索贝尔公司;具有可写性Bitmapex的卷积

C# 索贝尔公司;具有可写性Bitmapex的卷积,c#,edge-detection,writeablebitmap,writeablebitmapex,C#,Edge Detection,Writeablebitmap,Writeablebitmapex,因此,我在Windows RT上使用WriteableBitmapEx应用程序。我试图使用sobel操作符对图像执行边缘检测。我已经使用.curvole()成功地将x和y检测的两个内核应用到图像上,但现在我无法将两个图像都添加到一个。 问题是,两幅图像的所有像素的透明度值似乎都为0(因此ARGB中的A)。我可以自己显示两个图像,没有问题,但添加它们只会给我一张黑色的图片。 因此,我的问题是: 为什么卷积后每个像素的透明度都设置为0 为什么我仍然可以显示图像而不显示全部黑色 为什么我添加两个图像

因此,我在Windows RT上使用WriteableBitmapEx应用程序。我试图使用sobel操作符对图像执行边缘检测。我已经使用.curvole()成功地将x和y检测的两个内核应用到图像上,但现在我无法将两个图像都添加到一个。 问题是,两幅图像的所有像素的透明度值似乎都为0(因此ARGB中的A)。我可以自己显示两个图像,没有问题,但添加它们只会给我一张黑色的图片。 因此,我的问题是:

  • 为什么卷积后每个像素的透明度都设置为0
  • 为什么我仍然可以显示图像而不显示全部黑色
  • 为什么我添加两个图像时它是黑色的
  • 有没有更好的方法组合两个图像?不幸的是,Blit似乎不支持这种像素添加。但是ForEach真的很慢
对于calrification,这是我到目前为止的代码。我可以显示wbmpY和wbmpX,但finalbmp是完全黑色的

    public int[,] sobelY = new int[3, 3] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } };
    public int[,] sobelX = new int[3, 3] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } };

    public void trim(WriteableBitmap wbmp)
    {
        var graybmp = wbmp.Clone();
        graybmp.ForEach(toGrayscale);

        var wbmpY = graybmp.Clone();
        var wbmpX = graybmp.Clone();

        wbmpY = wbmpY.Convolute(sobelY, 1, 0);
        wbmpX = wbmpX.Convolute(sobelX, 1, 0);

        var finalbmp = combineSobel(wbmpX, wbmpY);           
     }

    public WriteableBitmap combineSobel(WriteableBitmap img, WriteableBitmap img2)
    {
        int height = img.PixelHeight;
        int width = img.PixelWidth;
        WriteableBitmap result = img.Clone();
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                Color imgColor = img.GetPixel(x, y);
                Color img2Color = img2.GetPixel(x, y);
                Color newColor = Color.FromArgb(
                    Math.Min((byte)Math.Sqrt(Math.Pow(imgColor.A, 2) + Math.Pow(img2Color.A, 2)), (byte)255),
                    Math.Min((byte)Math.Sqrt(Math.Pow(imgColor.R, 2) + Math.Pow(img2Color.R, 2)), (byte)255),
                    Math.Min((byte)Math.Sqrt(Math.Pow(imgColor.G, 2) + Math.Pow(img2Color.G, 2)), (byte)255),
                    Math.Min((byte)Math.Sqrt(Math.Pow(imgColor.B, 2) + Math.Pow(img2Color.B, 2)), (byte)255)
                );

                result.SetPixel(x, y, newColor);
            }
        }
        return result;
    }
public int[,]sobelY=new int[3,3]{{1,2,1},{0,0,0},{-1,-2,-1};
公共int[,]sobelX=新int[3,3]{-1,0,1},{-2,0,2},{-1,0,1};
公共空间修剪(可写位图wbmp)
{
var graybmp=wbmp.Clone();
灰度bmp.ForEach(toGrayscale);
var wbmpY=graybmp.Clone();
var wbmpX=graybmp.Clone();
wbmpY=wbmpY.卷积(sobelY,1,0);
wbmpX=wbmpX.卷积(sobelX,1,0);
var finalbmp=组合表(wbmpX,wbmpY);
}
公共WriteableBitmap组合标签(WriteableBitmap img、WriteableBitmap img2)
{
int height=img.PixelHeight;
int width=img.PixelWidth;
WriteableBitmap结果=img.Clone();
对于(int x=0;x
卷积应用于所有可用通道。不仅会处理红色、绿色和蓝色(在本例中这是您想要的),还会处理alpha通道。这将导致alpha值为零(100%透明)。考虑下面的例子:

1 0 -1 255 255 255 2 0 -2 over 255 255 255 1 0 -1 255 255 255 1 0 -1 255 255 255 2 0-2超过255 1 0 -1 255 255 255 1*255 0*255 -1*255 255 0 -255 2*255 0*255 -2*255 = 510 0 -510 1*255 0*255 -1*255 255 0 -255 对于所有像素,2*255+510+3*0-2*255-510=0 从技术上讲,这一切都很好,它没有检测到alpha通道上的任何边缘。然而,在这种情况下,这在功能上并不是您想要的。如果不需要此行为,则可以跳过处理alpha通道(如果源允许),或在之后将alpha重置为255

我想推测一下屏幕上会显示的黑色图像,因为我没有使用过这种技术的经验。许多框架首先将图像重置为纯色(假设在本例中为黑色)。这是必需的,以便在处理透明图像(或部分图像)时,前一个图像不会溢出。将卷积(透明)图像添加到此纯色,将产生相同的纯色。因此,图像将显示为全黑色


注意:combineSobel使用所有通道,但由于之前已将其转换为灰度,您可能需要优化颜色的创建。

代码中有两个问题:

1) 我试过了,卷积的方法对我不起作用——它只是创建了一个空图像。我想这不是你的错。当您组合两个空图像时,将得到一个空图像

2) 您的联合收割机实现存在一个小问题。您可以像在r、g、b上一样,在不使用sqrt calc的情况下将透明度设置为255

希望这有帮助

有没有更好的方法组合两个图像?不幸的是,Blit似乎不支持这种>像素添加。但是ForEach真的很慢

因此,您应该使用不安全代码,请检查以下内容:

就速度而言,假设您为每个像素调用16个函数(4xMath.Min、4xMath.Pow、4xMath.Sqrt)。这是一个巨大的开销

像素值在[0255]范围内 Math.Pow([0255],2)+Mat.Pow([0255],2)结果的范围为[0,2*Math.Pow(255,2)]=>[0130 050] 我会像这样构造一个查找表:

byte[] LUT4Sqrt = new byte[130051];

for (int i = 0; i < 130051; i++)
{
    LUT4Sqrt[i] = (byte)(Math.Sqrt(i));
}
byte[]LUT4Sqrt=新字节[130051];
对于(int i=0;i<130051;i++)
{
LUT4Sqrt[i]=(字节)(Math.Sqrt(i));
}
数学查找表。Pow也可以制作

byte[] LUT4Sqrt = new byte[130051];

for (int i = 0; i < 130051; i++)
{
    LUT4Sqrt[i] = (byte)(Math.Sqrt(i));
}