代码之家  ›  专栏  ›  技术社区  ›  user366312

Hough线变换的实现

  •  -1
  • user366312  · 技术社区  · 6 年前

    我在努力实现 Hough Line Transform .

    输入。

    enter image description here

    期望的行为。 我的源代码将生成以下输出,因为它是由 sample application

    enter image description here

    在这里,我们可以看到:

    1. 输出的尺寸与输入图像相同。
    2. 正弦波的交点几乎出现在中心。
    3. 波的交叉模式非常小和简单。

    我的源代码生成的输出与AForge生成的输出不同。

    enter image description here

    • 十字路口不在中间。
    • 波形也不同。

    为什么我的代码会产生不同的输出?

    .

    源代码

    我自己写了下面的代码。以下是 a Minimal, Complete, and Verifiable 源代码。

    public class HoughMap
    {
        public int[,] houghMap { get; private set; }
        public int[,] image { get; set; }
    
        public void Compute()
        {
            if (image != null)
            {
                // get source image size
                int inWidth = image.GetLength(0);
                int inHeight = image.GetLength(1);
    
                int inWidthHalf = inWidth / 2;
                int inHeightHalf = inHeight / 2;
    
                int outWidth = (int)Math.Sqrt(inWidth * inWidth + inHeight * inHeight);
                int outHeight = 180;
                int outHeightHalf = outHeight / 2;
    
                houghMap = new int[outWidth, outHeight];
    
                // scanning through each (x,y) pixel of the image--+
                for (int y = 0; y < inHeight; y++)               //|
                {                                                //|
                    for (int x = 0; x < inWidth; x++)//<-----------+
                    {
                        if (image[x, y] != 0)//if a pixel is black, skip it.
                        {
                            // We are drawing some Sine waves. So, it may 
                            // vary from -90 to +90 degrees.
                            for (int theta = -outHeightHalf; theta < outHeightHalf; theta++)
                            {
                                double rad = theta * Math.PI / 180;
                                // respective radius value is computed
                                //int radius = (int)Math.Round(Math.Cos(rad) * (x - inWidthHalf) - Math.Sin(rad) * (y - inHeightHalf));
                                //int radius = (int)Math.Round(Math.Cos(rad) * (x + inWidthHalf) - Math.Sin(rad) * (y + inHeightHalf));
                                int radius = (int)Math.Round(Math.Cos(rad) * (x) - Math.Sin(rad) * (outHeight - y));
    
                                // if the radious value is between 1 and 
                                if ((radius > 0) && (radius <= outWidth))
                                {
                                    houghMap[radius, theta + outHeightHalf]++;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
    
            Bitmap bitmap = (Bitmap)pictureBox1.Image as Bitmap;
    
            int[,] intImage = ToInteger(bitmap);
    
            HoughMap houghMap = new HoughMap();
            houghMap.image = intImage;
            houghMap.Compute();
    
            int[,] normalized = Rescale(houghMap.houghMap);
    
            Bitmap hough = ToBitmap(normalized, bitmap.PixelFormat);
    
            pictureBox2.Image = hough;
        }
    
        public static int[,] Rescale(int[,] image)
        {
            int[,] imageCopy = (int[,])image.Clone();
    
            int Width = imageCopy.GetLength(0);
            int Height = imageCopy.GetLength(1);
    
            int minVal = 0;
            int maxVal = 0;
    
            for (int j = 0; j < Height; j++)
            {
                for (int i = 0; i < Width; i++)
                {
                    double conv = imageCopy[i, j];
    
                    minVal = (int)Math.Min(minVal, conv);
                    maxVal = (int)Math.Max(maxVal, conv);
                }
            }
    
            int minRange = 0;
            int maxRange = 255;
    
            int[,] array2d = new int[Width, Height];
    
            for (int j = 0; j < Height; j++)
            {
                for (int i = 0; i < Width; i++)
                {
                    array2d[i, j] = (maxRange - minRange) * (imageCopy[i,j] - minVal) / (maxVal - minVal) + minRange;
                }
            }
    
            return array2d;
        }
    
        public int[,] ToInteger(Bitmap input)
        {
            int Width = input.Width;
            int Height = input.Height;
    
            int[,] array2d = new int[Width, Height];
    
            for (int y = 0; y < Height; y++)
            {
                for (int x = 0; x < Width; x++)
                {
                    Color cl = input.GetPixel(x, y);
    
                    int gray = (int)Convert.ChangeType(cl.R * 0.3 + cl.G * 0.59 + cl.B * 0.11, typeof(int));
    
                    array2d[x, y] = gray;
                }
            }
    
            return array2d;
        }
    
        public Bitmap ToBitmap(int[,] image, PixelFormat pixelFormat)
        {
            int[,] imageCopy = (int[,])image.Clone();
    
            int Width = imageCopy.GetLength(0);
            int Height = imageCopy.GetLength(1);
    
            Bitmap bitmap = new Bitmap(Width, Height, pixelFormat);
    
            for (int y = 0; y < Height; y++)
            {
                for (int x = 0; x < Width; x++)
                {
                    int iii = imageCopy[x, y];
    
                    Color clr = Color.FromArgb(iii, iii, iii);
    
                    bitmap.SetPixel(x, y, clr);
                }
            }
    
            return bitmap;
        }
    }
    

    1 回复  |  直到 6 年前
        1
  •  0
  •   user366312    6 年前

    我已经解决了这个问题 this link

    enter image description here

    public class HoughMap
    {
        public int[,] houghMap { get; private set; }
        public int[,] image { get; set; }
    
        public void Compute()
        {
            if (image != null)
            {
                // get source image size
                int Width = image.GetLength(0);
                int Height = image.GetLength(1);
    
                int centerX = Width / 2;
                int centerY = Height / 2;
    
                int maxTheta = 180;
                int houghHeight = (int)(Math.Sqrt(2) * Math.Max(Width, Height)) / 2;
                int doubleHeight = houghHeight * 2;
                int houghHeightHalf = houghHeight / 2;
                int houghWidthHalf = maxTheta / 2;
    
                houghMap = new int[doubleHeight, maxTheta];
    
                // scanning through each (x,y) pixel of the image--+
                for (int y = 0; y < Height; y++)                 //|
                {                                                //|
                    for (int x = 0; x < Width; x++)//<-------------+
                    {
                        if (image[x, y] != 0)//if a pixel is black, skip it.
                        {
                            // We are drawing some Sine waves.  
                            // It may vary from -90 to +90 degrees.
                            for (int theta = 0; theta < maxTheta; theta++)
                            {
                                double rad = theta *Math.PI / 180;
                                // respective radius value is computed
                                int rho = (int)(((x - centerX) * Math.Cos(rad)) + ((y - centerY) * Math.Sin(rad)));
    
                                // get rid of negative value
                                rho += houghHeight;
    
                                // if the radious value is between 
                                // 1 and twice the houghHeight 
                                if ((rho > 0) && (rho <= doubleHeight))
                                {
                                    houghMap[rho, theta]++;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    只是看看 this C++ code ,和 this C# code

    推荐文章
    tim  ·  图像中的矩形检测
    10 年前