1

원의 알 수없는 반경을 검출하는 3 차원 Hough 공간을 구현해야합니다. 나는 2 차원 공간을 구현했다. 사실 이미지에서 원의 반경을 찾아야합니다. 내가 어디에서부터 시작해야하는지 너희들이 알려줄 수 있니?3 차원 Hough 공간 변환

//Hough Circle Class 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using System.Collections; 
using System.Drawing; 
using System.Drawing.Imaging; 
namespace imageipload 
{ 
class HoughCirclez : IComparable 
{ 

    public readonly int X; 
    public readonly int Y; 
    public readonly int Radius; 
    public readonly short Intensity; 
    public readonly double RelativeIntensity; 

    public HoughCirclez(int x, int y, int radius, short intensity, double relativeIntensity) 
    { 
     X = x; 
     Y = y; 
     Radius = radius; 
     Intensity = intensity; 
     RelativeIntensity = relativeIntensity; 
    } 


    public int CompareTo(object value) 
    { 
     return (-Intensity.CompareTo(((HoughCirclez)value).Intensity)); 
    } 
} 
} 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Collections; 
using System.Drawing; 
using System.Drawing.Imaging; 

namespace imageipload 
{ 
class HoughCircleTrans 
{ 
    private int radiusToDetect; 
    private short[,] houghMap; 
    private short maxMapIntensity = 0; 

    // Hough map's width and height 
    private int width; 
    private int height; 

    private int localPeakRadius = 4; 
    private short minCircleIntensity = 10; 
    private ArrayList circles = new ArrayList(); 

    public HoughCircleTrans(int radiusToDetect) 
    { 
     this.radiusToDetect = radiusToDetect; 
    } 

    public short MinCircleIntensity 
    { 
     get { return minCircleIntensity; } 
     set { minCircleIntensity = value; } 
    } 
    public int LocalPeakRadius 
    { 
     get { return localPeakRadius; } 
     set { localPeakRadius = Math.Max(1, Math.Min(10, value)); } 
    } 

    public short MaxIntensity 
    { 
     get { return maxMapIntensity; } 
    } 

    public int CirclesCount 
    { 
     get { return circles.Count; } 
    } 

    public void ProcessImage(Bitmap image) 
    { 
     // check image format 
     if (image.PixelFormat != PixelFormat.Format8bppIndexed) 
      throw new ArgumentException("Pixel format of source image should be 8 bpp indexed"); 

     // lock source image 
     BitmapData imageData = image.LockBits(
      new Rectangle(0, 0, image.Width, image.Height), 
      ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed); 

     // process the image 
     ProcessImage(imageData); 

     // unlock image 
     image.UnlockBits(imageData); 
    } 

    public void ProcessImage(BitmapData imageData) 
    { 
     if (imageData.PixelFormat != PixelFormat.Format8bppIndexed) 
      throw new ArgumentException("Pixel format of source image should be 8 bpp indexed"); 

     // get source image size 
     width = imageData.Width; 
     height = imageData.Height; 

     int srcOffset = imageData.Stride - width; 

     // allocate Hough map of the same size like image 
     houghMap = new short[height, width]; 

     // do the job 
     unsafe 
     { 
      byte* src = (byte*)imageData.Scan0.ToPointer(); 

      // for each row 
      for (int y = 0; y < height; y++) 
      { 
       // for each pixel 
       for (int x = 0; x < width; x++, src++) 
       { 
        if (*src != 0) 
        { 
         DrawHoughCircle(x, y); 
        } 
       } 
       src += srcOffset; 
      } 
     } 

     // find max value in Hough map 
     maxMapIntensity = 0; 
     for (int i = 0; i < height; i++) 
     { 
      for (int j = 0; j < width; j++) 
      { 
       if (houghMap[i, j] > maxMapIntensity) 
       { 
        maxMapIntensity = houghMap[i, j]; 
       } 
      } 
     } 

     CollectCircles(); 
    } 

    public Bitmap ToBitmap() 
    { 
     // check if Hough transformation was made already 
     if (houghMap == null) 
     { 
      throw new ApplicationException("Hough transformation was not done yet"); 
     } 

     int width = houghMap.GetLength(1); 
     int height = houghMap.GetLength(0); 

     // create new image 
     Bitmap image = AForge.Imaging.Image.CreateGrayscaleImage(width, height); 

     // lock destination bitmap data 
     BitmapData imageData = image.LockBits(
      new Rectangle(0, 0, width, height), 
      ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); 

     int offset = imageData.Stride - width; 
     float scale = 255.0f/maxMapIntensity; 

     // do the job 
     unsafe 
     { 
      byte* dst = (byte*)imageData.Scan0.ToPointer(); 

      for (int y = 0; y < height; y++) 
      { 
       for (int x = 0; x < width; x++, dst++) 
       { 
        *dst = (byte)System.Math.Min(255, (int)(scale * houghMap[y, x])); 
       } 
       dst += offset; 
      } 
     } 

     // unlock destination images 
     image.UnlockBits(imageData); 

     return image; 
    } 

    public HoughCirclez[] GetMostIntensiveCircles(int count) 
    { 
     // lines count 
     int n = Math.Min(count, circles.Count); 

     if (n == 0) 
      return null; 

     // result array 
     HoughCirclez[] dst = new HoughCirclez[n]; 
     circles.CopyTo(0, dst, 0, n); 

     return dst; 
    } 

    public HoughCirclez[] GetCirclesByRelativeIntensity(double minRelativeIntensity) 
    { 
     int count = 0, n = circles.Count; 

     while ((count < n) && (((HoughCirclez)circles[count]).RelativeIntensity >= minRelativeIntensity)) 
      count++; 

     return GetMostIntensiveCircles(count); 
    } 

    private void CollectCircles() 
    { 
     short intensity; 
     bool foundGreater; 

     // clean circles collection 
     circles.Clear(); 

     // for each Y coordinate 
     for (int y = 0; y < height; y++) 
     { 
      // for each X coordinate 
      for (int x = 0; x < width; x++) 
      { 
       // get current value 
       intensity = houghMap[y, x]; 

       if (intensity < minCircleIntensity) 
        continue; 

       foundGreater = false; 

       // check neighboors 
       for (int ty = y - localPeakRadius, tyMax = y + localPeakRadius; ty < tyMax; ty++) 
       { 
        // continue if the coordinate is out of map 
        if (ty < 0) 
         continue; 
        // break if it is not local maximum or coordinate is out of map 
        if ((foundGreater == true) || (ty >= height)) 
         break; 

        for (int tx = x - localPeakRadius, txMax = x + localPeakRadius; tx < txMax; tx++) 
        { 
         // continue or break if the coordinate is out of map 
         if (tx < 0) 
          continue; 
         if (tx >= width) 
          break; 

         // compare the neighboor with current value 
         if (houghMap[ty, tx] > intensity) 
         { 
          foundGreater = true; 
          break; 
         } 
        } 
       } 

       // was it local maximum ? 
       if (!foundGreater) 
       { 
        // we have local maximum 
        circles.Add(new HoughCirclez(x, y, radiusToDetect, intensity, (double)intensity/maxMapIntensity)); 
       } 
      } 
     } 

     circles.Sort(); 

    } 

    private void DrawHoughCircle(int xCenter, int yCenter) 
    { 
     int x = 0; 
     int y = radiusToDetect; 
     int p = (5 - radiusToDetect * 4)/4; 

     SetHoughirclePoints(xCenter, yCenter, x, y); 

     while (x < y) 
     { 
      x++; 
      if (p < 0) 
      { 
       p += 2 * x + 1; 
      } 
      else 
      { 
       y--; 
       p += 2 * (x - y) + 1; 
      } 
      SetHoughirclePoints(xCenter, yCenter, x, y); 
     } 
    } 

    private void SetHoughirclePoints(int cx, int cy, int x, int y) 
    { 
     if (x == 0) 
     { 
      SetHoughPoint(cx, cy + y); 
      SetHoughPoint(cx, cy - y); 
      SetHoughPoint(cx + y, cy); 
      SetHoughPoint(cx - y, cy); 
     } 
     else if (x == y) 
     { 
      SetHoughPoint(cx + x, cy + y); 
      SetHoughPoint(cx - x, cy + y); 
      SetHoughPoint(cx + x, cy - y); 
      SetHoughPoint(cx - x, cy - y); 
     } 
     else if (x < y) 
     { 
      SetHoughPoint(cx + x, cy + y); 
      SetHoughPoint(cx - x, cy + y); 
      SetHoughPoint(cx + x, cy - y); 
      SetHoughPoint(cx - x, cy - y); 
      SetHoughPoint(cx + y, cy + x); 
      SetHoughPoint(cx - y, cy + x); 
      SetHoughPoint(cx + y, cy - x); 
      SetHoughPoint(cx - y, cy - x); 
     } 
    } 


    private void SetHoughPoint(int x, int y) 
    { 
     if ((x >= 0) && (y >= 0) && (x < width) && (y < height)) 
     { 
      houghMap[y, x]++; 
     } 
    } 


} 
} 
+0

소리가납니다. – CodesInChaos

답변

2

houghMap는 houghMap = new short[height, width,radius]; 될 것이다 사이클 더 하나가있을 것입니다 - 각 반경. 각 반경마다 2 차원 호프 변형을해야합니다 ...