简体   繁体   English

Sobel边缘检测输出,用于16位灰度图像

[英]Sobel Edge Detection output for 16bit grayscale image

I've seen many Sobel Edge Detecting Operations in C++ and C#, but I'm having great difficulty converting the code to operate on a 16bit graphic. 我已经看到了许多用C ++和C#进行的Sobel边缘检测操作,但是将代码转换为可在16位图形上进行操作非常困难。 Most of the code I've seen is programmed to operate on RGB style bitmaps. 我见过的大多数代码都被编程为在RGB样式位图上运行。 The graphic I have is in a ushort[] array with intensity values in each row,col pixel. 我拥有的图形在ushort []数组中,每行以像素为单位,包含强度值。

The following is the code I've come out with: (The issue is, that its not quite working...) With a fudge factor in place, it is finding edges perhaps, but it is also finding a lot of noise. 以下是我提供的代码:(问题是,它不太起作用...)在设置了软糖因素的情况下,它可能正在发现边缘,但同时也发现了很多噪音。

However if I save the original file as a JPG, and run it into a another alternative Sobel-Edge-Detector C# code that accepts Bitmaps, it is a lot better... almost no noise! 但是,如果我将原始文件另存为JPG,然后将其运行到接受位图的另一种Sobel-Edge-Detector C#代码中,那就更好了……几乎没有噪音! Shouldn't my 16bit Grayscale version be better?! 我的16位灰度版本应该更好吗? But it must be my code is just not up to snuff. 但这一定是我的代码还不够完善。 I'm not understanding the logic. 我不了解逻辑。

    public void sobel()
    {

        ushort[] pixels = new ushort[9];
        ushort[,] imageData = image_array[0].GetArray();
        ushort[,] imageOut = (ushort[,])imageData.Clone();
        uint xDim = (ushort)(imageData.GetLength(1) - imageData.GetLength(1) % regions);
        uint yDim = (ushort)(imageData.GetLength(0) - imageData.GetLength(0) % regions);

        double intensityX = 0.0;
        double intensityY = 0.0;
        double intensityTotal = 0.0;
        int limit = 1000000; //Just arbitrary junk number

        int filterOffset = 1;

        for (int offsetY = filterOffset; offsetY <
            yDim - (filterOffset+1); offsetY++)
        {

            for (int offsetX = filterOffset; offsetX <
                xDim - (filterOffset+1); offsetX++)
            {
                //intensityX = intensityY = 0;
                //intensityTotal = 0;

                pixels[0] = imageData[offsetY - 1, offsetX - 1];
                pixels[1] = imageData[offsetY - 1, offsetX];
                pixels[2] = imageData[offsetY - 1, offsetX + 1];
                pixels[3] = imageData[offsetY, offsetX - 1];
                pixels[4] = imageData[offsetY, offsetX];
                pixels[5] = imageData[offsetY, offsetX + 1];
                pixels[6] = imageData[offsetY + 1, offsetX - 1];
                pixels[7] = imageData[offsetY + 1, offsetX];
                pixels[8] = imageData[offsetY + 1, offsetX + 1];

                intensityX = pixels[8] + 2 * pixels[5] + pixels[2] - pixels[0] - 2 * pixels[3] - pixels[6];
                intensityY = pixels[8] + 2 * pixels[7] + pixels[6] - pixels[2] - 2 * pixels[1] - pixels[0];

                //intensityTotal = Math.Sqrt((intensityX * intensityX) + (intensityY * intensityY));
                //intensityTotal = Math.Abs(intensityX) + Math.Abs(intensityY);
                intensityTotal = intensityX * intensityX + intensityY * intensityY;
                //int sobel = (int)Math.Sqrt((xSobel * xSobel) + (ySobel * ySobel));

                //if (intensityTotal > MaximumValue)
                  //  intensityTotal = MaximumValue; //Presumably Black

                //if (intensityTotal < -1000) //1000 fudgefactor ...still not working correctly
                  //  intensityTotal = MinimumValue; //Presumably White
                //if (intensityTotal < (MinimumValue - 1000))
                  //  intensityTotal = MaximumValue;

                if (intensityTotal > limit)
                    imageOut[offsetY, offsetX] = MinimumValue;
                else
                    imageOut[offsetY, offsetX] = MaximumValue;

                //imageOut[offsetY, offsetX] = (ushort)intensityTotal;
            }

        }

        SetImageArrayItem(ImageDataIndex.RAWData, new DiskBackedArray(imageOut));

    }

Just assume 'image_array', xDim, yDim are givens. 只需假设给出了“ image_array”,xDim,yDim。 You'll notice some commented out other attempts. 您会注意到一些注释掉了其他尝试。

Sobel (and other gradient-based filter) is suffered from noise. Sobel(和其他基于梯度的滤波器)受到噪声的影响。 You can prefilter your picture with Gauss smoothing and compare results. 您可以使用高斯平滑对图片进行预过滤并比较结果。 Note that limit = 1000000 for squared difference corresponds to diff magnitudes about 1000 - this is rather small value for 16-bit (MAX=65535) picture. 请注意,平方差的limit = 1000000对应于约1000的差异大小-对于16位(MAX = 65535)图片而言,这是一个很小的值。
Saving in JPG makes a picture more blurred - sharp edges are smeared, high-frequency noise is lowered. 保存为JPG将使图片更加模糊-涂上锐利的边缘,降低高频噪声。 So play a bit with mild smoothing and limit. 因此,请使用适度的平滑度和限制来发挥作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM